Step 1: Add EventListeners for the mouse events
document.addEventListener("mousedown", handleMouseDown, true); document.addEventListener("mouseup", handleMouseUp, true); document.addEventListener("mousemove", handleMouseMove, true);Step 2: Event Handlers
//Start Drag when the mouse click happens and save the start position var mouseX, mouseY, dragMode = false, line = null; function handleMouseDown(e) { mouseX = (e.clientX - canvas.offsetLeft) / SCALE; mouseY = (e.clientY - canvas.offsetTop) / SCALE; dragMode = true; } function handleMouseUp(e) { dragMode = false; currentMouseX = (e.clientX - canvas.offsetLeft) / SCALE; currentMouseY = (e.clientY - canvas.offsetTop) / SCALE; var start = new b2Vec2(mouseX, mouseY); var end = new b2Vec2(currentMouseX, currentMouseY); line = drawline(line, start, end); } function handleMouseMove(e) { if(dragMode) { currentMouseX = (e.clientX - canvas.offsetLeft) / SCALE; currentMouseY = (e.clientY - canvas.offsetTop) / SCALE; var start = new b2Vec2(mouseX, mouseY); var end = new b2Vec2(currentMouseX, currentMouseY); line = drawline(line, start, end); } } function keyset(evt){ }Step 3: updating the to redraw the new line
function update() { .... var lineCount = 0; for (b = world.GetBodyList() ; b; b = b.GetNext()) { if(b.GetUserData() != null){ if( b.GetUserData().name == "Line"){ updateDrawLine(b); lineCount++; if(dragMode && lineCount > 1) objScheduledForRemoval[++index] = b; } ....
In the above code snippet, I am drawing a new line and deleting the old one as my mouse gets dragged. The issue I faced while doing this is if I hover over the same point without moving then the line disappears to fix this I have added the lineCount parameter, to make sure atleast one line is visible to the user at all times during the drag. On a side note, Box2D doesn't like it when you attempt to remove a body from the world when the world is being stepped. Hence I am adding the objects to be removed to a list and removing them later.
//------------------------------- Removing objects from the world window.setInterval(removeObjScheduledForRemoval, 1000/90); var objScheduledForRemoval = Array(); var index = -1; function removeObjScheduledForRemoval() { for(var i = 0; i <= index; i++){ console.log("here",i); world.DestroyBody(objScheduledForRemoval[i]); objScheduledForRemoval[i] = null; } objScheduledForRemoval = Array(); index = -1; }
Step 4: Drawing the line in the Box2D world.
function drawline(b,start,end) { var fixDef = new b2FixtureDef; fixDef.shape = new b2PolygonShape; fixDef.density = 1.0; fixDef.friction = 0.5; fixDef.restitution = .5; fixDef.shape.SetAsArray([ start, end],2 ); var bodyDef = new b2BodyDef; bodyDef.type = b2Body.b2_staticBody; bodyDef.position.Set(0,0); rbData = new Object(); rbData.name = "Line"; rbData.start = start; rbData.end = end; bodyDef.userData = rbData; var line = world.CreateBody(bodyDef).CreateFixture(fixDef); return line; }Step 4: Mapping the line to the canvas.
function updateDrawLine(b){ start = b.GetUserData().start; end = b.GetUserData().end; context.save(); context.beginPath(); context.moveTo(start.x * SCALE,start.y * SCALE); context.lineTo(end.x * SCALE,end.y *SCALE); context.stroke(); context.restore(); }