topical media & game development

talk show tell print

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.