1

i'm creating a web page where you dynamically draw multiple rectangles. I can draw the single object, but once I tried to draw another one, the previous one is gone away. I tried to save the state using save() and restore(), and it seems that I can't put it here. Isn't it logical that save method is put in the mouseup and restore method is called in the mousedown event? Any help or advice will be appreciated.

<script>
  var canvas = document.getElementById('myCanvasCircle'),
      ctx = canvas.getContext('2d'),
      circle = {},
      drag = false,
      circleMade = false,
      mouseMoved = false;

  function draw() {
    ctx.beginPath();
    ctx.arc(circle.X, circle.Y, circle.radius, 0, 2.0 * Math.PI);
    ctx.stroke();

  }

  function mouseDown(e) {
    ctx.restore();
    circle.startX = e.pageX - this.offsetLeft;
    circle.startY = e.pageY - this.offsetTop;

    circle.X = circle.startX;
    circle.Y = circle.startY;

    if (!circleMade) {
      circle.radius = 0;
    }

    drag = true;
  }

  function mouseUp() {
    drag = false;
    circleMade = true;

    if (!mouseMoved) {
      circle = {};
      circleMade = false;
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }

    mouseMoved = false;
    ctx.save();
  }

  function mouseMove(e) {
    if (drag) {
      mouseMoved = true;
      circle.X = e.pageX - this.offsetLeft;
      circle.Y = e.pageY - this.offsetTop;
      if (!circleMade) {
        circle.radius = Math.sqrt(Math.pow((circle.X - circle.startX), 2) + Math.pow((circle.Y - circle.startY), 2));
      }
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      draw();


    }
  }

  function init() {
    canvas.addEventListener('mousedown', mouseDown, false);
    canvas.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);

  }

  init();

</script>
user2585578
  • 239
  • 4
  • 14

1 Answers1

1

you need to save the information about what you are drawing in a separate object, every time you make a draw to the canvas you will wipe and redraw the new object. so when you clearRect and then draw you are clearing and then drawing a fresh one but the old ones are being left behind. A good example:

var SavedCircles = [];
var circleInfo = function()
{
  this.x = 0;
  this.y = 0;
  this.startX = 0;
  this.startY = 0;
  this.radius = 0;
}
circle = {};

function draw()
{
   for(var x=0;x<SavedCircles.length;x++)
   {
       ctx.beginPath();
       ctx.arc(SavedCircles[x].X, SavedCircles[x].Y, SavedCircles[x].radius, 0, 2.0 * Math.PI);
       ctx.stroke();
   }
}

function mouseDown()
{
  circle = new circleInfo();
}

function mouseUp()
{
   SavedCircles.push(circle);
}

function mouseMove()
{
   draw();
}

so you can get rid of save and restore, also its much faster to clear a canvas simply by: canvas.width = canvas.width;

this should help you keep all circles ever drawn. fill in the rest with your code.

  • It's bad practice `using canvas.width = canvas.width;` for clearing the canvas since it doesn't only clear the canvas from what you have drawn, it also resets properties such as lineWidth, strokeStyles, fillStyles and transformations etc. It's also slower than the alternative `ctx.clearRect(0,0,canvas.width,canvas.height);`, which is the preferred way to clear your canvas. – Niddro Jul 03 '15 at 06:02
  • well to be honest you shouldn't be depending on the canvas to store those properties and should have them stored elsewhere in an object. but in refrence to the `canvas.width` you are correct, in refrence to this post http://stackoverflow.com/questions/2142535/how-to-clear-the-canvas-for-redrawing – Gregory Guidero Jul 03 '15 at 17:11