skip to Main Content

Consider the following piece of code (test it yourself):

function draw() {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');

  ctx.beginPath();
  ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
  ctx.stroke();
  ctx.moveTo(75, 75);

  ctx.save();
  ctx.setLineDash([3, 3]);
  ctx.lineTo(90, 90);
  ctx.stroke();
  ctx.restore();
  
  //ctx.stroke();
}

draw();
<canvas id="canvas"></canvas>

It plots this:

enter image description here

However, if I uncomment the last ctx.stroke(), it draws a line on top of the dashed one, not sure if from (75, 75) to (90, 90) or the other way around:

function draw() {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');

  ctx.beginPath();
  ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
  ctx.stroke();
  ctx.moveTo(75, 75);

  ctx.save();
  ctx.setLineDash([3, 3]);
  ctx.lineTo(90, 90);
  ctx.stroke();
  ctx.restore();

  ctx.stroke();
}

draw()
<canvas id="canvas"></canvas>

enter image description here

I thought saving and restoring didn’t affect the "path cursor", and there’s either any "pending draw command", and so I expected the extra (and accidental) stroke after restore don’t have any effect whatsoever.

What is going on exactly and how does save()/restore() relate to this?

2

Answers


  1. Chosen as BEST ANSWER

    I answer myself. The reason of that effect turned out to have nothing to do with save and restore, but with stroke. If you call stroke repeatedly, you draw the path repeatedly, like if the last stroke didn't "clear it up", so the path is still available to keep growing or adding more pieces to it.

    In my example above, the second stroke just had a different dash style, and so the second stroke was applied with other settings.

    In this other simpler example, I draw an almost transparent path, and as I added more and more calls to stroke, the path was progressively less transparent:

    function draw() {
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
    
      ctx.beginPath();
      ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)';
      ctx.moveTo(75, 75);
      ctx.lineTo(90, 90);
      ctx.lineTo(100, 120);
      ctx.stroke();
      ctx.stroke();
      ctx.stroke();
      ctx.stroke();
      ctx.stroke();
      ctx.stroke();
      ctx.stroke();
    }
    
    draw()
    <canvas id="canvas"></canvas>


  2. save() and restore() only saves the canvas drawing state, it does not saves/restores the actual line (with eg lineTo and stroke).

    So your last stroke is still affected by the lineTo called before.


    The drawing state that gets saved onto a stack consists of:
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search