Erasing previously drawn lines on an HTML5 canvas









up vote
13
down vote

favorite
3












To play around with HTML5 canvas, I decided to make an app which draws an analogue clockface. Everything's fine, except that old lines don't get erased in the way that I would expect. I've included part of the code below - DrawHands() gets called once a second:



var hoursPoint = new Object();
var minutesPoint = new Object();
var secondsPoint = new Object();

function drawHands()

var now = new Date();

drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "white", 1);
var seconds = now.getSeconds();
secondsPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * seconds, 0.75 * radius);
drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "black", 1);

drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "white", 3);
var minutes = now.getMinutes();
minutesPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * minutes, 0.75 * radius);
drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "black", 3);

drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "white", 3);
var hours = now.getHours();
if (hours >= 12) hours -= 12; // Hours are 0-11
hoursPoint = getOtherEndOfLine(centerX, centerY, (2 * Math.PI / 12 * hours) + (2 * Math.PI / 12 / 60 * minutes), 0.6 * radius);
drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "black", 3);



To make sense of the above, there are two helper functions:



  • drawLine(x1, y1, x2, y2, color, thickness)

  • getOtherEndOfLine(x, y, angle, length)

The problem is that while all the hands get drawn as expected in black, they never get erased. I would expect that since the same line is drawn in white (the background colour) it would effectively erase what was previously drawn at that point. But this doesn't seem to be the case.



Anything I'm missing?










share|improve this question

























    up vote
    13
    down vote

    favorite
    3












    To play around with HTML5 canvas, I decided to make an app which draws an analogue clockface. Everything's fine, except that old lines don't get erased in the way that I would expect. I've included part of the code below - DrawHands() gets called once a second:



    var hoursPoint = new Object();
    var minutesPoint = new Object();
    var secondsPoint = new Object();

    function drawHands()

    var now = new Date();

    drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "white", 1);
    var seconds = now.getSeconds();
    secondsPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * seconds, 0.75 * radius);
    drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "black", 1);

    drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "white", 3);
    var minutes = now.getMinutes();
    minutesPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * minutes, 0.75 * radius);
    drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "black", 3);

    drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "white", 3);
    var hours = now.getHours();
    if (hours >= 12) hours -= 12; // Hours are 0-11
    hoursPoint = getOtherEndOfLine(centerX, centerY, (2 * Math.PI / 12 * hours) + (2 * Math.PI / 12 / 60 * minutes), 0.6 * radius);
    drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "black", 3);



    To make sense of the above, there are two helper functions:



    • drawLine(x1, y1, x2, y2, color, thickness)

    • getOtherEndOfLine(x, y, angle, length)

    The problem is that while all the hands get drawn as expected in black, they never get erased. I would expect that since the same line is drawn in white (the background colour) it would effectively erase what was previously drawn at that point. But this doesn't seem to be the case.



    Anything I'm missing?










    share|improve this question























      up vote
      13
      down vote

      favorite
      3









      up vote
      13
      down vote

      favorite
      3






      3





      To play around with HTML5 canvas, I decided to make an app which draws an analogue clockface. Everything's fine, except that old lines don't get erased in the way that I would expect. I've included part of the code below - DrawHands() gets called once a second:



      var hoursPoint = new Object();
      var minutesPoint = new Object();
      var secondsPoint = new Object();

      function drawHands()

      var now = new Date();

      drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "white", 1);
      var seconds = now.getSeconds();
      secondsPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * seconds, 0.75 * radius);
      drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "black", 1);

      drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "white", 3);
      var minutes = now.getMinutes();
      minutesPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * minutes, 0.75 * radius);
      drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "black", 3);

      drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "white", 3);
      var hours = now.getHours();
      if (hours >= 12) hours -= 12; // Hours are 0-11
      hoursPoint = getOtherEndOfLine(centerX, centerY, (2 * Math.PI / 12 * hours) + (2 * Math.PI / 12 / 60 * minutes), 0.6 * radius);
      drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "black", 3);



      To make sense of the above, there are two helper functions:



      • drawLine(x1, y1, x2, y2, color, thickness)

      • getOtherEndOfLine(x, y, angle, length)

      The problem is that while all the hands get drawn as expected in black, they never get erased. I would expect that since the same line is drawn in white (the background colour) it would effectively erase what was previously drawn at that point. But this doesn't seem to be the case.



      Anything I'm missing?










      share|improve this question













      To play around with HTML5 canvas, I decided to make an app which draws an analogue clockface. Everything's fine, except that old lines don't get erased in the way that I would expect. I've included part of the code below - DrawHands() gets called once a second:



      var hoursPoint = new Object();
      var minutesPoint = new Object();
      var secondsPoint = new Object();

      function drawHands()

      var now = new Date();

      drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "white", 1);
      var seconds = now.getSeconds();
      secondsPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * seconds, 0.75 * radius);
      drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "black", 1);

      drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "white", 3);
      var minutes = now.getMinutes();
      minutesPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * minutes, 0.75 * radius);
      drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "black", 3);

      drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "white", 3);
      var hours = now.getHours();
      if (hours >= 12) hours -= 12; // Hours are 0-11
      hoursPoint = getOtherEndOfLine(centerX, centerY, (2 * Math.PI / 12 * hours) + (2 * Math.PI / 12 / 60 * minutes), 0.6 * radius);
      drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "black", 3);



      To make sense of the above, there are two helper functions:



      • drawLine(x1, y1, x2, y2, color, thickness)

      • getOtherEndOfLine(x, y, angle, length)

      The problem is that while all the hands get drawn as expected in black, they never get erased. I would expect that since the same line is drawn in white (the background colour) it would effectively erase what was previously drawn at that point. But this doesn't seem to be the case.



      Anything I'm missing?







      javascript html5 canvas






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Sep 9 '11 at 17:45









      Saqib

      5,70962743




      5,70962743






















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          15
          down vote



          accepted










          For reasons that I could expand upon, you should consider clearing your canvas and redrawing it entirely unless there are performance or compositing reasons not to.



          You want clearRect, something like this:



          //clear the canvas so we can draw a fresh clock
          ctx.clearRect(0, 0, canvasWidth, canvasHeight);

          //redraw your clock here
          /* ... */





          share|improve this answer


















          • 3




            If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
            – TheMadDeveloper
            Nov 22 '15 at 11:31











          • It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
            – Allasso
            Apr 12 '16 at 12:28










          • Correction on above comment - that should read mrmcgreg's answer.
            – Allasso
            Apr 12 '16 at 19:55


















          up vote
          15
          down vote













          Instead of erasing the things you don't want you can:



          1. save the state of the canvas

          2. draw the things you don't want

          3. restore the canvas to the saved state to 'erase' them

          This can be accomplished pretty easily using ImageData:






          var canvas = document.querySelector('canvas'),
          context = canvas.getContext('2d');

          context.fillStyle = 'blue';
          context.fillRect(0,0,10,10);

          // save the state of the canvas here
          var imageData = context.getImageData(0,0,canvas.width,canvas.height);

          // draw a red rectangle that we'll get rid of in a second
          context.strokeStyle = 'red';
          context.strokeRect(70,70,20,20);

          setTimeout(function ()
          // return the canvas to the state right after we drew the blue rect
          context.putImageData(imageData, 0, 0);
          , 1000);

          <canvas width=100 height=100>








          share|improve this answer


















          • 1




            This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
            – Allasso
            Apr 12 '16 at 12:24






          • 1




            ...You could even take snapshots at several points in the drawing process if needed to restore to.
            – Allasso
            Apr 12 '16 at 12:32










          • This can also keep you from having to reload an image if you are using one for a backdrop.
            – Allasso
            Apr 12 '16 at 12:39

















          up vote
          4
          down vote













          The reason you can't just redraw the line in white and hope for it to erase the old line is because there might be some anti-aliasing/bleeding. You'll also notice that a straight horizontal line drawn on a pixel versus a half-pixel looks very different because of this.



          When you do your white "erase" lines, try drawing them with a larger lineWidth by about 3 or 4. That should work for your case.



          You should also draw all of the white lines first, then all of the black lines, in case they intersect.






          share|improve this answer





























            up vote
            4
            down vote













            A quick and easy way to clear a canvas is to set the width:



            context.canvas.width = context.canvas.width;





            share|improve this answer
















            • 1




              Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
              – BarbaraKwarc
              Dec 31 '16 at 4:52

















            up vote
            0
            down vote













            My solution is double buffering :






            var shapes = 
            [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
            ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
            ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
            ];

            step1();
            setTimeout(function ()
            step2();
            setTimeout(function ()
            step3();
            , 1000);
            , 1000);

            function step1()
            clearCanvas('myCanvas1');
            shapes.forEach((sh) => drawShape('myCanvas1', sh); );
            ;

            function step2()
            clearCanvas('myCanvas2');
            shapes.pop();
            shapes.forEach((sh) => drawShape('myCanvas2', sh); );
            showOtherCanvas('myCanvas2', 'myCanvas1');
            ;

            function step3()
            clearCanvas('myCanvas1');
            shapes.pop();
            shapes.forEach((sh) => drawShape('myCanvas1', sh); );
            showOtherCanvas('myCanvas1', 'myCanvas2');
            ;

            function showOtherCanvas(cnv1, cnv2)
            var c1 = document.getElementById(cnv1);
            var c2 = document.getElementById(cnv2);

            c1.style['z-index'] = 3;
            c2.style['z-index'] = 1;
            c1.style['z-index'] = 2;


            function clearCanvas(canvasID)
            var canvas = document.getElementById(canvasID);
            var ctx = canvas.getContext('2d');

            ctx.fillStyle="#FFFFFF";
            ctx.fillRect(0,0,480,320);


            function drawShape (canvasID, info)
            switch (info.type)
            case "line" : drawLine(canvasID, info);
            case "rectangle" : drawRectangle(canvasID, info);
            case "circle" : drawCircle(canvasID, info);



            function drawLine (canvasID, info)
            var canvas = document.getElementById(canvasID);
            var ctx = canvas.getContext('2d');

            ctx.strokeStyle = info.strokeStyle;
            ctx.lineWidth = info.lineWidth

            ctx.beginPath();
            ctx.moveTo(info.x1, info.y1);
            ctx.lineTo(info.x2, info.y2);
            ctx.stroke();


            function drawRectangle (canvasID, info)
            var canvas = document.getElementById(canvasID);
            var ctx = canvas.getContext('2d');

            ctx.fillStyle = info.fillStyle;
            ctx.strokeStyle = info.strokeStyle;
            ctx.lineWidth = info.lineWidth

            ctx.fillRect(info.x, info.y, info.width, info.height);
            ctx.strokeRect(info.x, info.y, info.width, info.height);


            function drawCircle (canvasID, info)
            var canvas = document.getElementById(canvasID);
            var ctx = canvas.getContext('2d');

            ctx.fillStyle = info.fillStyle;
            ctx.strokeStyle = info.strokeStyle;
            ctx.lineWidth = info.lineWidth

            ctx.beginPath();
            ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
            ctx.fill();

            ctx.beginPath();
            ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
            ctx.stroke();

            <canvas id="myCanvas2" width="480" height="320"
            style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
            </canvas>
            <canvas id="myCanvas1" width="480" height="320"
            style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
            </canvas>





            The change is so fast you won't see any flicker.






            share|improve this answer




















              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "1"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7365436%2ferasing-previously-drawn-lines-on-an-html5-canvas%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              15
              down vote



              accepted










              For reasons that I could expand upon, you should consider clearing your canvas and redrawing it entirely unless there are performance or compositing reasons not to.



              You want clearRect, something like this:



              //clear the canvas so we can draw a fresh clock
              ctx.clearRect(0, 0, canvasWidth, canvasHeight);

              //redraw your clock here
              /* ... */





              share|improve this answer


















              • 3




                If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
                – TheMadDeveloper
                Nov 22 '15 at 11:31











              • It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
                – Allasso
                Apr 12 '16 at 12:28










              • Correction on above comment - that should read mrmcgreg's answer.
                – Allasso
                Apr 12 '16 at 19:55















              up vote
              15
              down vote



              accepted










              For reasons that I could expand upon, you should consider clearing your canvas and redrawing it entirely unless there are performance or compositing reasons not to.



              You want clearRect, something like this:



              //clear the canvas so we can draw a fresh clock
              ctx.clearRect(0, 0, canvasWidth, canvasHeight);

              //redraw your clock here
              /* ... */





              share|improve this answer


















              • 3




                If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
                – TheMadDeveloper
                Nov 22 '15 at 11:31











              • It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
                – Allasso
                Apr 12 '16 at 12:28










              • Correction on above comment - that should read mrmcgreg's answer.
                – Allasso
                Apr 12 '16 at 19:55













              up vote
              15
              down vote



              accepted







              up vote
              15
              down vote



              accepted






              For reasons that I could expand upon, you should consider clearing your canvas and redrawing it entirely unless there are performance or compositing reasons not to.



              You want clearRect, something like this:



              //clear the canvas so we can draw a fresh clock
              ctx.clearRect(0, 0, canvasWidth, canvasHeight);

              //redraw your clock here
              /* ... */





              share|improve this answer














              For reasons that I could expand upon, you should consider clearing your canvas and redrawing it entirely unless there are performance or compositing reasons not to.



              You want clearRect, something like this:



              //clear the canvas so we can draw a fresh clock
              ctx.clearRect(0, 0, canvasWidth, canvasHeight);

              //redraw your clock here
              /* ... */






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 13 '16 at 14:00

























              answered Sep 9 '11 at 17:50









              ellisbben

              5,4622040




              5,4622040







              • 3




                If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
                – TheMadDeveloper
                Nov 22 '15 at 11:31











              • It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
                – Allasso
                Apr 12 '16 at 12:28










              • Correction on above comment - that should read mrmcgreg's answer.
                – Allasso
                Apr 12 '16 at 19:55













              • 3




                If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
                – TheMadDeveloper
                Nov 22 '15 at 11:31











              • It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
                – Allasso
                Apr 12 '16 at 12:28










              • Correction on above comment - that should read mrmcgreg's answer.
                – Allasso
                Apr 12 '16 at 19:55








              3




              3




              If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
              – TheMadDeveloper
              Nov 22 '15 at 11:31





              If one were to want to clear a specific line or shape (as I did), rather than clearing a rectangular region, setting ctx.globalCompositeOperation = "destination-out" -- as mentioned in andrewmu's solution to a similar question -- will pretty much make your fill/stroke operations act just like an eraser tool. Remember to change the compositing mode back when you're done. See the Mozilla's compositing and clipping for full details.
              – TheMadDeveloper
              Nov 22 '15 at 11:31













              It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
              – Allasso
              Apr 12 '16 at 12:28




              It is not necessary to always clear the canvas entirely. See Simon Sarris's answer using getImageData / putImageData, which allows you to restore the drawing to any previous phase(s) of the drawing.
              – Allasso
              Apr 12 '16 at 12:28












              Correction on above comment - that should read mrmcgreg's answer.
              – Allasso
              Apr 12 '16 at 19:55





              Correction on above comment - that should read mrmcgreg's answer.
              – Allasso
              Apr 12 '16 at 19:55













              up vote
              15
              down vote













              Instead of erasing the things you don't want you can:



              1. save the state of the canvas

              2. draw the things you don't want

              3. restore the canvas to the saved state to 'erase' them

              This can be accomplished pretty easily using ImageData:






              var canvas = document.querySelector('canvas'),
              context = canvas.getContext('2d');

              context.fillStyle = 'blue';
              context.fillRect(0,0,10,10);

              // save the state of the canvas here
              var imageData = context.getImageData(0,0,canvas.width,canvas.height);

              // draw a red rectangle that we'll get rid of in a second
              context.strokeStyle = 'red';
              context.strokeRect(70,70,20,20);

              setTimeout(function ()
              // return the canvas to the state right after we drew the blue rect
              context.putImageData(imageData, 0, 0);
              , 1000);

              <canvas width=100 height=100>








              share|improve this answer


















              • 1




                This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
                – Allasso
                Apr 12 '16 at 12:24






              • 1




                ...You could even take snapshots at several points in the drawing process if needed to restore to.
                – Allasso
                Apr 12 '16 at 12:32










              • This can also keep you from having to reload an image if you are using one for a backdrop.
                – Allasso
                Apr 12 '16 at 12:39














              up vote
              15
              down vote













              Instead of erasing the things you don't want you can:



              1. save the state of the canvas

              2. draw the things you don't want

              3. restore the canvas to the saved state to 'erase' them

              This can be accomplished pretty easily using ImageData:






              var canvas = document.querySelector('canvas'),
              context = canvas.getContext('2d');

              context.fillStyle = 'blue';
              context.fillRect(0,0,10,10);

              // save the state of the canvas here
              var imageData = context.getImageData(0,0,canvas.width,canvas.height);

              // draw a red rectangle that we'll get rid of in a second
              context.strokeStyle = 'red';
              context.strokeRect(70,70,20,20);

              setTimeout(function ()
              // return the canvas to the state right after we drew the blue rect
              context.putImageData(imageData, 0, 0);
              , 1000);

              <canvas width=100 height=100>








              share|improve this answer


















              • 1




                This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
                – Allasso
                Apr 12 '16 at 12:24






              • 1




                ...You could even take snapshots at several points in the drawing process if needed to restore to.
                – Allasso
                Apr 12 '16 at 12:32










              • This can also keep you from having to reload an image if you are using one for a backdrop.
                – Allasso
                Apr 12 '16 at 12:39












              up vote
              15
              down vote










              up vote
              15
              down vote









              Instead of erasing the things you don't want you can:



              1. save the state of the canvas

              2. draw the things you don't want

              3. restore the canvas to the saved state to 'erase' them

              This can be accomplished pretty easily using ImageData:






              var canvas = document.querySelector('canvas'),
              context = canvas.getContext('2d');

              context.fillStyle = 'blue';
              context.fillRect(0,0,10,10);

              // save the state of the canvas here
              var imageData = context.getImageData(0,0,canvas.width,canvas.height);

              // draw a red rectangle that we'll get rid of in a second
              context.strokeStyle = 'red';
              context.strokeRect(70,70,20,20);

              setTimeout(function ()
              // return the canvas to the state right after we drew the blue rect
              context.putImageData(imageData, 0, 0);
              , 1000);

              <canvas width=100 height=100>








              share|improve this answer














              Instead of erasing the things you don't want you can:



              1. save the state of the canvas

              2. draw the things you don't want

              3. restore the canvas to the saved state to 'erase' them

              This can be accomplished pretty easily using ImageData:






              var canvas = document.querySelector('canvas'),
              context = canvas.getContext('2d');

              context.fillStyle = 'blue';
              context.fillRect(0,0,10,10);

              // save the state of the canvas here
              var imageData = context.getImageData(0,0,canvas.width,canvas.height);

              // draw a red rectangle that we'll get rid of in a second
              context.strokeStyle = 'red';
              context.strokeRect(70,70,20,20);

              setTimeout(function ()
              // return the canvas to the state right after we drew the blue rect
              context.putImageData(imageData, 0, 0);
              , 1000);

              <canvas width=100 height=100>








              var canvas = document.querySelector('canvas'),
              context = canvas.getContext('2d');

              context.fillStyle = 'blue';
              context.fillRect(0,0,10,10);

              // save the state of the canvas here
              var imageData = context.getImageData(0,0,canvas.width,canvas.height);

              // draw a red rectangle that we'll get rid of in a second
              context.strokeStyle = 'red';
              context.strokeRect(70,70,20,20);

              setTimeout(function ()
              // return the canvas to the state right after we drew the blue rect
              context.putImageData(imageData, 0, 0);
              , 1000);

              <canvas width=100 height=100>





              var canvas = document.querySelector('canvas'),
              context = canvas.getContext('2d');

              context.fillStyle = 'blue';
              context.fillRect(0,0,10,10);

              // save the state of the canvas here
              var imageData = context.getImageData(0,0,canvas.width,canvas.height);

              // draw a red rectangle that we'll get rid of in a second
              context.strokeStyle = 'red';
              context.strokeRect(70,70,20,20);

              setTimeout(function ()
              // return the canvas to the state right after we drew the blue rect
              context.putImageData(imageData, 0, 0);
              , 1000);

              <canvas width=100 height=100>






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 5 at 23:45

























              answered Apr 23 '15 at 16:42









              mrmcgreg

              2,00611322




              2,00611322







              • 1




                This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
                – Allasso
                Apr 12 '16 at 12:24






              • 1




                ...You could even take snapshots at several points in the drawing process if needed to restore to.
                – Allasso
                Apr 12 '16 at 12:32










              • This can also keep you from having to reload an image if you are using one for a backdrop.
                – Allasso
                Apr 12 '16 at 12:39












              • 1




                This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
                – Allasso
                Apr 12 '16 at 12:24






              • 1




                ...You could even take snapshots at several points in the drawing process if needed to restore to.
                – Allasso
                Apr 12 '16 at 12:32










              • This can also keep you from having to reload an image if you are using one for a backdrop.
                – Allasso
                Apr 12 '16 at 12:39







              1




              1




              This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
              – Allasso
              Apr 12 '16 at 12:24




              This method has an advantage over using clearRectangle, in that you can getImageData at any phase of the drawing and restore to that level, whereas clearRectangle will always take you back to a blank canvas. For this reason I upvoted.
              – Allasso
              Apr 12 '16 at 12:24




              1




              1




              ...You could even take snapshots at several points in the drawing process if needed to restore to.
              – Allasso
              Apr 12 '16 at 12:32




              ...You could even take snapshots at several points in the drawing process if needed to restore to.
              – Allasso
              Apr 12 '16 at 12:32












              This can also keep you from having to reload an image if you are using one for a backdrop.
              – Allasso
              Apr 12 '16 at 12:39




              This can also keep you from having to reload an image if you are using one for a backdrop.
              – Allasso
              Apr 12 '16 at 12:39










              up vote
              4
              down vote













              The reason you can't just redraw the line in white and hope for it to erase the old line is because there might be some anti-aliasing/bleeding. You'll also notice that a straight horizontal line drawn on a pixel versus a half-pixel looks very different because of this.



              When you do your white "erase" lines, try drawing them with a larger lineWidth by about 3 or 4. That should work for your case.



              You should also draw all of the white lines first, then all of the black lines, in case they intersect.






              share|improve this answer


























                up vote
                4
                down vote













                The reason you can't just redraw the line in white and hope for it to erase the old line is because there might be some anti-aliasing/bleeding. You'll also notice that a straight horizontal line drawn on a pixel versus a half-pixel looks very different because of this.



                When you do your white "erase" lines, try drawing them with a larger lineWidth by about 3 or 4. That should work for your case.



                You should also draw all of the white lines first, then all of the black lines, in case they intersect.






                share|improve this answer
























                  up vote
                  4
                  down vote










                  up vote
                  4
                  down vote









                  The reason you can't just redraw the line in white and hope for it to erase the old line is because there might be some anti-aliasing/bleeding. You'll also notice that a straight horizontal line drawn on a pixel versus a half-pixel looks very different because of this.



                  When you do your white "erase" lines, try drawing them with a larger lineWidth by about 3 or 4. That should work for your case.



                  You should also draw all of the white lines first, then all of the black lines, in case they intersect.






                  share|improve this answer














                  The reason you can't just redraw the line in white and hope for it to erase the old line is because there might be some anti-aliasing/bleeding. You'll also notice that a straight horizontal line drawn on a pixel versus a half-pixel looks very different because of this.



                  When you do your white "erase" lines, try drawing them with a larger lineWidth by about 3 or 4. That should work for your case.



                  You should also draw all of the white lines first, then all of the black lines, in case they intersect.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Sep 9 '11 at 18:33

























                  answered Sep 9 '11 at 18:07









                  Simon Sarris

                  51.1k11111147




                  51.1k11111147




















                      up vote
                      4
                      down vote













                      A quick and easy way to clear a canvas is to set the width:



                      context.canvas.width = context.canvas.width;





                      share|improve this answer
















                      • 1




                        Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
                        – BarbaraKwarc
                        Dec 31 '16 at 4:52














                      up vote
                      4
                      down vote













                      A quick and easy way to clear a canvas is to set the width:



                      context.canvas.width = context.canvas.width;





                      share|improve this answer
















                      • 1




                        Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
                        – BarbaraKwarc
                        Dec 31 '16 at 4:52












                      up vote
                      4
                      down vote










                      up vote
                      4
                      down vote









                      A quick and easy way to clear a canvas is to set the width:



                      context.canvas.width = context.canvas.width;





                      share|improve this answer












                      A quick and easy way to clear a canvas is to set the width:



                      context.canvas.width = context.canvas.width;






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Sep 10 '11 at 3:29









                      Joe

                      60.2k14103130




                      60.2k14103130







                      • 1




                        Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
                        – BarbaraKwarc
                        Dec 31 '16 at 4:52












                      • 1




                        Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
                        – BarbaraKwarc
                        Dec 31 '16 at 4:52







                      1




                      1




                      Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
                      – BarbaraKwarc
                      Dec 31 '16 at 4:52




                      Smells like depending on some particular implementation in a particular browser, which is an easy way to undefined behaviour in other browsers.
                      – BarbaraKwarc
                      Dec 31 '16 at 4:52










                      up vote
                      0
                      down vote













                      My solution is double buffering :






                      var shapes = 
                      [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
                      ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
                      ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
                      ];

                      step1();
                      setTimeout(function ()
                      step2();
                      setTimeout(function ()
                      step3();
                      , 1000);
                      , 1000);

                      function step1()
                      clearCanvas('myCanvas1');
                      shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                      ;

                      function step2()
                      clearCanvas('myCanvas2');
                      shapes.pop();
                      shapes.forEach((sh) => drawShape('myCanvas2', sh); );
                      showOtherCanvas('myCanvas2', 'myCanvas1');
                      ;

                      function step3()
                      clearCanvas('myCanvas1');
                      shapes.pop();
                      shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                      showOtherCanvas('myCanvas1', 'myCanvas2');
                      ;

                      function showOtherCanvas(cnv1, cnv2)
                      var c1 = document.getElementById(cnv1);
                      var c2 = document.getElementById(cnv2);

                      c1.style['z-index'] = 3;
                      c2.style['z-index'] = 1;
                      c1.style['z-index'] = 2;


                      function clearCanvas(canvasID)
                      var canvas = document.getElementById(canvasID);
                      var ctx = canvas.getContext('2d');

                      ctx.fillStyle="#FFFFFF";
                      ctx.fillRect(0,0,480,320);


                      function drawShape (canvasID, info)
                      switch (info.type)
                      case "line" : drawLine(canvasID, info);
                      case "rectangle" : drawRectangle(canvasID, info);
                      case "circle" : drawCircle(canvasID, info);



                      function drawLine (canvasID, info)
                      var canvas = document.getElementById(canvasID);
                      var ctx = canvas.getContext('2d');

                      ctx.strokeStyle = info.strokeStyle;
                      ctx.lineWidth = info.lineWidth

                      ctx.beginPath();
                      ctx.moveTo(info.x1, info.y1);
                      ctx.lineTo(info.x2, info.y2);
                      ctx.stroke();


                      function drawRectangle (canvasID, info)
                      var canvas = document.getElementById(canvasID);
                      var ctx = canvas.getContext('2d');

                      ctx.fillStyle = info.fillStyle;
                      ctx.strokeStyle = info.strokeStyle;
                      ctx.lineWidth = info.lineWidth

                      ctx.fillRect(info.x, info.y, info.width, info.height);
                      ctx.strokeRect(info.x, info.y, info.width, info.height);


                      function drawCircle (canvasID, info)
                      var canvas = document.getElementById(canvasID);
                      var ctx = canvas.getContext('2d');

                      ctx.fillStyle = info.fillStyle;
                      ctx.strokeStyle = info.strokeStyle;
                      ctx.lineWidth = info.lineWidth

                      ctx.beginPath();
                      ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                      ctx.fill();

                      ctx.beginPath();
                      ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                      ctx.stroke();

                      <canvas id="myCanvas2" width="480" height="320"
                      style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
                      </canvas>
                      <canvas id="myCanvas1" width="480" height="320"
                      style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
                      </canvas>





                      The change is so fast you won't see any flicker.






                      share|improve this answer
























                        up vote
                        0
                        down vote













                        My solution is double buffering :






                        var shapes = 
                        [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
                        ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
                        ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
                        ];

                        step1();
                        setTimeout(function ()
                        step2();
                        setTimeout(function ()
                        step3();
                        , 1000);
                        , 1000);

                        function step1()
                        clearCanvas('myCanvas1');
                        shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                        ;

                        function step2()
                        clearCanvas('myCanvas2');
                        shapes.pop();
                        shapes.forEach((sh) => drawShape('myCanvas2', sh); );
                        showOtherCanvas('myCanvas2', 'myCanvas1');
                        ;

                        function step3()
                        clearCanvas('myCanvas1');
                        shapes.pop();
                        shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                        showOtherCanvas('myCanvas1', 'myCanvas2');
                        ;

                        function showOtherCanvas(cnv1, cnv2)
                        var c1 = document.getElementById(cnv1);
                        var c2 = document.getElementById(cnv2);

                        c1.style['z-index'] = 3;
                        c2.style['z-index'] = 1;
                        c1.style['z-index'] = 2;


                        function clearCanvas(canvasID)
                        var canvas = document.getElementById(canvasID);
                        var ctx = canvas.getContext('2d');

                        ctx.fillStyle="#FFFFFF";
                        ctx.fillRect(0,0,480,320);


                        function drawShape (canvasID, info)
                        switch (info.type)
                        case "line" : drawLine(canvasID, info);
                        case "rectangle" : drawRectangle(canvasID, info);
                        case "circle" : drawCircle(canvasID, info);



                        function drawLine (canvasID, info)
                        var canvas = document.getElementById(canvasID);
                        var ctx = canvas.getContext('2d');

                        ctx.strokeStyle = info.strokeStyle;
                        ctx.lineWidth = info.lineWidth

                        ctx.beginPath();
                        ctx.moveTo(info.x1, info.y1);
                        ctx.lineTo(info.x2, info.y2);
                        ctx.stroke();


                        function drawRectangle (canvasID, info)
                        var canvas = document.getElementById(canvasID);
                        var ctx = canvas.getContext('2d');

                        ctx.fillStyle = info.fillStyle;
                        ctx.strokeStyle = info.strokeStyle;
                        ctx.lineWidth = info.lineWidth

                        ctx.fillRect(info.x, info.y, info.width, info.height);
                        ctx.strokeRect(info.x, info.y, info.width, info.height);


                        function drawCircle (canvasID, info)
                        var canvas = document.getElementById(canvasID);
                        var ctx = canvas.getContext('2d');

                        ctx.fillStyle = info.fillStyle;
                        ctx.strokeStyle = info.strokeStyle;
                        ctx.lineWidth = info.lineWidth

                        ctx.beginPath();
                        ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                        ctx.fill();

                        ctx.beginPath();
                        ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                        ctx.stroke();

                        <canvas id="myCanvas2" width="480" height="320"
                        style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
                        </canvas>
                        <canvas id="myCanvas1" width="480" height="320"
                        style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
                        </canvas>





                        The change is so fast you won't see any flicker.






                        share|improve this answer






















                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          My solution is double buffering :






                          var shapes = 
                          [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
                          ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
                          ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
                          ];

                          step1();
                          setTimeout(function ()
                          step2();
                          setTimeout(function ()
                          step3();
                          , 1000);
                          , 1000);

                          function step1()
                          clearCanvas('myCanvas1');
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          ;

                          function step2()
                          clearCanvas('myCanvas2');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas2', sh); );
                          showOtherCanvas('myCanvas2', 'myCanvas1');
                          ;

                          function step3()
                          clearCanvas('myCanvas1');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          showOtherCanvas('myCanvas1', 'myCanvas2');
                          ;

                          function showOtherCanvas(cnv1, cnv2)
                          var c1 = document.getElementById(cnv1);
                          var c2 = document.getElementById(cnv2);

                          c1.style['z-index'] = 3;
                          c2.style['z-index'] = 1;
                          c1.style['z-index'] = 2;


                          function clearCanvas(canvasID)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle="#FFFFFF";
                          ctx.fillRect(0,0,480,320);


                          function drawShape (canvasID, info)
                          switch (info.type)
                          case "line" : drawLine(canvasID, info);
                          case "rectangle" : drawRectangle(canvasID, info);
                          case "circle" : drawCircle(canvasID, info);



                          function drawLine (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.moveTo(info.x1, info.y1);
                          ctx.lineTo(info.x2, info.y2);
                          ctx.stroke();


                          function drawRectangle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.fillRect(info.x, info.y, info.width, info.height);
                          ctx.strokeRect(info.x, info.y, info.width, info.height);


                          function drawCircle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.fill();

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.stroke();

                          <canvas id="myCanvas2" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
                          </canvas>
                          <canvas id="myCanvas1" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
                          </canvas>





                          The change is so fast you won't see any flicker.






                          share|improve this answer












                          My solution is double buffering :






                          var shapes = 
                          [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
                          ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
                          ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
                          ];

                          step1();
                          setTimeout(function ()
                          step2();
                          setTimeout(function ()
                          step3();
                          , 1000);
                          , 1000);

                          function step1()
                          clearCanvas('myCanvas1');
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          ;

                          function step2()
                          clearCanvas('myCanvas2');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas2', sh); );
                          showOtherCanvas('myCanvas2', 'myCanvas1');
                          ;

                          function step3()
                          clearCanvas('myCanvas1');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          showOtherCanvas('myCanvas1', 'myCanvas2');
                          ;

                          function showOtherCanvas(cnv1, cnv2)
                          var c1 = document.getElementById(cnv1);
                          var c2 = document.getElementById(cnv2);

                          c1.style['z-index'] = 3;
                          c2.style['z-index'] = 1;
                          c1.style['z-index'] = 2;


                          function clearCanvas(canvasID)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle="#FFFFFF";
                          ctx.fillRect(0,0,480,320);


                          function drawShape (canvasID, info)
                          switch (info.type)
                          case "line" : drawLine(canvasID, info);
                          case "rectangle" : drawRectangle(canvasID, info);
                          case "circle" : drawCircle(canvasID, info);



                          function drawLine (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.moveTo(info.x1, info.y1);
                          ctx.lineTo(info.x2, info.y2);
                          ctx.stroke();


                          function drawRectangle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.fillRect(info.x, info.y, info.width, info.height);
                          ctx.strokeRect(info.x, info.y, info.width, info.height);


                          function drawCircle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.fill();

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.stroke();

                          <canvas id="myCanvas2" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
                          </canvas>
                          <canvas id="myCanvas1" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
                          </canvas>





                          The change is so fast you won't see any flicker.






                          var shapes = 
                          [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
                          ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
                          ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
                          ];

                          step1();
                          setTimeout(function ()
                          step2();
                          setTimeout(function ()
                          step3();
                          , 1000);
                          , 1000);

                          function step1()
                          clearCanvas('myCanvas1');
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          ;

                          function step2()
                          clearCanvas('myCanvas2');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas2', sh); );
                          showOtherCanvas('myCanvas2', 'myCanvas1');
                          ;

                          function step3()
                          clearCanvas('myCanvas1');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          showOtherCanvas('myCanvas1', 'myCanvas2');
                          ;

                          function showOtherCanvas(cnv1, cnv2)
                          var c1 = document.getElementById(cnv1);
                          var c2 = document.getElementById(cnv2);

                          c1.style['z-index'] = 3;
                          c2.style['z-index'] = 1;
                          c1.style['z-index'] = 2;


                          function clearCanvas(canvasID)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle="#FFFFFF";
                          ctx.fillRect(0,0,480,320);


                          function drawShape (canvasID, info)
                          switch (info.type)
                          case "line" : drawLine(canvasID, info);
                          case "rectangle" : drawRectangle(canvasID, info);
                          case "circle" : drawCircle(canvasID, info);



                          function drawLine (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.moveTo(info.x1, info.y1);
                          ctx.lineTo(info.x2, info.y2);
                          ctx.stroke();


                          function drawRectangle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.fillRect(info.x, info.y, info.width, info.height);
                          ctx.strokeRect(info.x, info.y, info.width, info.height);


                          function drawCircle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.fill();

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.stroke();

                          <canvas id="myCanvas2" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
                          </canvas>
                          <canvas id="myCanvas1" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
                          </canvas>





                          var shapes = 
                          [type:"circle", x:50, y:50, radious:40, lineWidth:2, strokeStyle:"#FF0000", fillStyle:"#800000"
                          ,type:"rectangle", x:50, y:50, width:100, height: 100, lineWidth:2, strokeStyle:"#00FF00", fillStyle:"#008000"
                          ,type:"line", x1:75, y1:100, x2:170, y2:75, lineWidth:3, strokeStyle:"#0000FF"
                          ];

                          step1();
                          setTimeout(function ()
                          step2();
                          setTimeout(function ()
                          step3();
                          , 1000);
                          , 1000);

                          function step1()
                          clearCanvas('myCanvas1');
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          ;

                          function step2()
                          clearCanvas('myCanvas2');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas2', sh); );
                          showOtherCanvas('myCanvas2', 'myCanvas1');
                          ;

                          function step3()
                          clearCanvas('myCanvas1');
                          shapes.pop();
                          shapes.forEach((sh) => drawShape('myCanvas1', sh); );
                          showOtherCanvas('myCanvas1', 'myCanvas2');
                          ;

                          function showOtherCanvas(cnv1, cnv2)
                          var c1 = document.getElementById(cnv1);
                          var c2 = document.getElementById(cnv2);

                          c1.style['z-index'] = 3;
                          c2.style['z-index'] = 1;
                          c1.style['z-index'] = 2;


                          function clearCanvas(canvasID)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle="#FFFFFF";
                          ctx.fillRect(0,0,480,320);


                          function drawShape (canvasID, info)
                          switch (info.type)
                          case "line" : drawLine(canvasID, info);
                          case "rectangle" : drawRectangle(canvasID, info);
                          case "circle" : drawCircle(canvasID, info);



                          function drawLine (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.moveTo(info.x1, info.y1);
                          ctx.lineTo(info.x2, info.y2);
                          ctx.stroke();


                          function drawRectangle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.fillRect(info.x, info.y, info.width, info.height);
                          ctx.strokeRect(info.x, info.y, info.width, info.height);


                          function drawCircle (canvasID, info)
                          var canvas = document.getElementById(canvasID);
                          var ctx = canvas.getContext('2d');

                          ctx.fillStyle = info.fillStyle;
                          ctx.strokeStyle = info.strokeStyle;
                          ctx.lineWidth = info.lineWidth

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.fill();

                          ctx.beginPath();
                          ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
                          ctx.stroke();

                          <canvas id="myCanvas2" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
                          </canvas>
                          <canvas id="myCanvas1" width="480" height="320"
                          style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
                          </canvas>






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 10 at 8:31









                          Dominique Fortin

                          1,632816




                          1,632816



























                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7365436%2ferasing-previously-drawn-lines-on-an-html5-canvas%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

                              Syphilis

                              Darth Vader #20