topical media & game development
sample-canvas-editor.htm / htm
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script type="text/javascript" src="sample-canvas-editor.js">
</script>
<script type="text/javascript">
var ctx;
var env;
var ctx;
var width;
var height;
var pointmasses = new Array();
var joints = new Array();
var gravity = new Vector(0.0, 1.0);
var zeroForce = new Vector(0.0, 0.0);
var dt = 0.05;
var tempVector = new Vector();
var stopped = true;
var keyboardForce = new Vector();
var savedMouseCoords = null;
var editStates =
{
selectObject : 1,
placePointmass : 2,
placeStick : 3,
placeJoint1 : 4,
placeJoint2 : 5,
deleteObject : 6,
hideJoint : 7,
showJoint : 8,
anchorPointmass : 9
}
var editState = editStates.selectObject;
function placePointmass(xPos, yPos)
{
var p = new PointMass(xPos, yPos, 1.0);
pointmasses[pointmasses.length] = p;
}
function findClosestPointmass(xPos, yPos)
{
tempVector.setX(xPos);
tempVector.setY(yPos);
var i;
var minDist = 10000.0;
var minIndex = -1;
var selectPointmass = null;
for(i = 0; i < pointmasses.length; i++)
{
var dist = tempVector.dist(pointmasses[i].getPos());
if(dist < minDist && dist < 0.1)
{
minDist = dist;
selectPointmass = pointmasses[i];
minIndex = i;
}
}
return { pointmass : selectPointmass, dist : minDist, index : minIndex };
}
function findClosestJoint(xPos, yPos, visibleMatters)
{
tempVector.setX(xPos);
tempVector.setY(yPos);
visibleMatters = visibleMatters || false;
var i;
var minDist = 10000.0;
var minIndex = -1;
var selectJoint = null;
for(i = 0; i < joints.length; i++)
{
if(visibleMatters && !joints[i].getVisibility())
continue;
var dist = tempVector.dist(joints[i].getMiddle());
if(dist < minDist && dist < 0.1)
{
minDist = dist;
selectJoint = joints[i];
minIndex = i;
}
}
return { joint : selectJoint, dist : minDist, index : minIndex };
}
var firstSelectedPointmass;
function placeJoint1(xPos, yPos)
{
var t = findClosestPointmass(xPos, yPos);
firstSelectedPointmass = t.pointmass;
if(firstSelectedPointmass != null)
{
firstSelectedPointmass.select();
editState = editStates.placeJoint2;
}
}
function placeJoint2(xPos, yPos)
{
var t = findClosestPointmass(xPos, yPos);
var secondSelectedPointmass = t.pointmass;
if(secondSelectedPointmass != null && secondSelectedPointmass != firstSelectedPointmass)
{
firstSelectedPointmass.unselect();
var joint = new Joint(firstSelectedPointmass, secondSelectedPointmass, 0.9, 1.1);
joints[joints.length] = joint;
firstSelectedPointmass = null;
editState = editStates.placeJoint1;
}
}
function deleteAllAssociatedJoints(pointmass)
{
var i;
for(i = 0; i < joints.length; i++)
{
if(joints[i].getPointmassA() == pointmass)
joints.splice(i--, 1);
else if(joints[i].getPointmassB() == pointmass)
joints.splice(i--, 1);
}
}
function deleteObject(xPos, yPos)
{
var j = findClosestJoint(xPos, yPos);
var p = findClosestPointmass(xPos, yPos);
if(j == null && p == null)
return;
if(j != null && p == null)
{
joints.splice(j.index, 1);
}
else if(p != null && j == null)
{
deleteAllAssociatedJoints(p.pointmass);
pointmasses.splice(p.index, 1);
}
else if(j.dist < p.dist)
{
joints.splice(j.index, 1);
}
else if(p.dist < j.dist)
{
deleteAllAssociatedJoints(p.pointmass);
pointmasses.splice(p.index, 1);
}
}
function hideJoint(xPos, yPos)
{
var j = findClosestJoint(xPos, yPos, true);
if(j.joint != null)
j.joint.setVisible(false);
}
function showJoint(xPos, yPos)
{
var j = findClosestJoint(xPos, yPos);
if(j.joint != null)
j.joint.setVisible(true);
}
function anchorPointmass(xPos, yPos)
{
var p = findClosestPointmass(xPos, yPos);
if(p.pointmass != null)
p.pointmass.toggleAnchor();
}
function setAllObjectsPauseMode(paused)
{
var i;
for(i = 0; i < joints.length; i++)
joints[i].setPaused(paused);
for(i = 0; i < pointmasses.length; i++)
pointmasses[i].setPaused(paused);
}
function setAllObjectsSelectMode(selectable)
{
var i;
for(i = 0; i < joints.length; i++)
joints[i].setSelectable(selectable);
}
function updatePhysics()
{
var i;
for(i = 0; i < pointmasses.length; i++)
{
pointmasses[i].addForce(gravity);
pointmasses[i].move(dt);
pointmasses[i].setForce(zeroForce);
if(env.collision(pointmasses[i].getPos(), pointmasses[i].getPrevPos()) == true)
pointmasses[i].setFriction(0.1);
else
pointmasses[i].setFriction(0.01);
}
for(i = 0; i < joints.length; i++)
joints[i].sc();
}
function draw()
{
ctx.clearRect(0, 0, width, height);
env.draw(ctx, width);
var i;
for(i = 0; i < joints.length; i++)
joints[i].draw(ctx, width);
for(i = 0; i < pointmasses.length; i++)
pointmasses[i].draw(ctx, width);
}
function timeout()
{
if(!stopped)
updatePhysics();
draw();
setTimeout("timeout()", 30);
}
/*
function log(msg)
{
var textArea;
textArea = document.getElementById("logArea");
textArea.value = msg + "\n" + textArea.value;
}
function clearLog()
{
var textArea;
textArea = document.getElementById("logArea");
textArea.value = "";
}
*/
function setForceOnAllPointmasses(force)
{
var i = 0;
for(i = 0; i < pointmasses.length; i++)
pointmasses[i].addForce(force);
}
function initExample4(aWidth, aHeight)
{
var canvas = document.getElementById("drawingarea");
ctx = canvas.getContext('2d');
env = new Environment(0.02, 0.02, 0.96, 0.96);
width = aWidth;
height = aHeight;
function getMouseCoords(event)
{
if(event == null)
event = window.event;
if(event == null)
return null;
if(event.pageX || event.pageY)
return {x:event.pageX / width, y:event.pageY / width};
return null;
}
document.onmousedown = function(event)
{
var mouseCoords;
mouseCoords = getMouseCoords(event);
if(mouseCoords == null)
return;
if(mouseCoords.x < 0.15 || mouseCoords.x > 0.8 || mouseCoords.y < 0.15 || mouseCoords.y > 0.8)
return;
if(editState == editStates.placePointmass)
placePointmass(mouseCoords.x, mouseCoords.y);
else if(editState == editStates.placeJoint1)
placeJoint1(mouseCoords.x, mouseCoords.y);
else if(editState == editStates.placeJoint2)
placeJoint2(mouseCoords.x, mouseCoords.y);
else if(editState == editStates.deleteObject)
deleteObject(mouseCoords.x, mouseCoords.y);
else if(editState == editStates.hideJoint)
hideJoint(mouseCoords.x, mouseCoords.y);
else if(editState == editStates.showJoint)
showJoint(mouseCoords.x, mouseCoords.y);
else if(editState == editStates.anchorPointmass)
anchorPointmass(mouseCoords.x, mouseCoords.y);
}
document.onmouseup = function(event)
{
}
document.onmousemove = function(event)
{
}
document.onkeydown = function(event)
{
var keyCode;
if(event == null)
keyCode = window.event.keyCode;
else
keyCode = event.keyCode;
var force = 10.0;
switch(keyCode)
{
case 37:
keyboardForce.setX(-force);
keyboardForce.setY(0.0);
setForceOnAllPointmasses(keyboardForce);
break;
case 38:
keyboardForce.setX(0.0);
keyboardForce.setY(-force);
setForceOnAllPointmasses(keyboardForce);
break;
case 39:
keyboardForce.setX(force);
keyboardForce.setY(0.0);
setForceOnAllPointmasses(keyboardForce);
break;
case 40:
keyboardForce.setX(0.0);
keyboardForce.setY(force);
setForceOnAllPointmasses(keyboardForce);
break;
case 71:
if(gravity.getY() == 1.0)
gravity.setY(0.0);
else
gravity.setY(1.0);
break;
default:
break;
}
}
timeout();
}
function setStatePlacePointmass()
{
editState = editStates.placePointmass;
setAllObjectsSelectMode(false);
}
function setStatePlaceJoint()
{
editState = editStates.placeJoint1;
setAllObjectsSelectMode(false);
}
function setStateDeleteObject()
{
editState = editStates.deleteObject;
setAllObjectsSelectMode(true);
}
function pauseSimulation()
{
stopped = true;
setAllObjectsPauseMode(true);
}
function resumeSimulation()
{
stopped = false;
setAllObjectsPauseMode(false);
setAllObjectsSelectMode(false);
}
function stopSimulation()
{
stopped = true;
var i;
for(i = 0; i < pointmasses.length; i++)
pointmasses[i].moveToOrigPos();
setAllObjectsPauseMode(true);
}
function setStateHideJoint()
{
editState = editStates.hideJoint;
setAllObjectsSelectMode(true);
}
function setStateShowJoint()
{
editState = editStates.showJoint;
setAllObjectsSelectMode(true);
}
function anchorPointsmass()
{
editState = editStates.anchorPointmass;
}
function clearAll()
{
joints.splice(0, joints.length);
pointmasses.splice(0, pointmasses.length);
}
</script>
</head><body onload="initExample4(600, 600)">
<canvas id="drawingarea" width="600" height="600"></canvas><br>
<a href="javascript:setStateDeleteObject()">delete</a><br>
<a href="javascript:setStatePlacePointmass()">pointmass</a>
<a href="javascript:setStatePlaceJoint()">joint</a><br>
<a href="javascript:setStateHideJoint()">hide joint</a><br>
<a href="javascript:setStateShowJoint()">show joint</a><br>
<a href="javascript:anchorPointsmass()">anchor pointmass</a><br>
<a href="javascript:pauseSimulation()">pause</a>
<a href="javascript:resumeSimulation()">start</a>
<a href="javascript:stopSimulation()">stop</a><br>
<a href="javascript:clearAll()">clear</a><br>
</body></html>
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.