0

I have a canvas which I can use to draw on it and I add an undo button. I am saving the canvas in an array (as in the code) and I am calling it click on the undo button. on console.log you can see that the src is changing but the canvas isn't.

What am I doing wrong? (the second code is what I am having problem with but I added most of the code because my question always get closed for not giving enough information)

var mousePressed = false;
var lastX, lastY;
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");

function InitThis() {
    
    $('#myCanvas').mousedown(function (e) {
        mousePressed = true;
        Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false);
    });

    $('#myCanvas').mousemove(function (e) {
        if (mousePressed) {
            Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
        }
    });

    $('#myCanvas').mouseup(function (e) {
        if (mousePressed) {
            mousePressed = false;
            cPush() 
        }
    });

    $('#myCanvas').mouseleave(function (e) {
        if (mousePressed) {
            mousePressed = false;
            cPush() 
        }
    });
}

function Draw(x, y, isDown) {
    if (isDown) {
        ctx.beginPath();
        ctx.strokeStyle = $('#selColor').val();
        ctx.lineWidth = $('#selWidth').val();
        ctx.lineJoin = "round";
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(x, y);
        ctx.closePath();
        ctx.stroke();
    }
    lastX = x;
    lastY = y;
}



var cPushArray = [""];
var cStep = -1;

function cPush() {
    cStep++;
    if (cStep < cPushArray.length) { cPushArray.length = cStep; }
    image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
    cPushArray.push(image);
}
function cUndo() {
    if (cStep > 0) {
        cStep--;
        var canvasPic = new Image();
        canvasPic.src = cPushArray[cStep];
        canvasPic.onload = function() { ctx.drawImage(canvasPic, 0, 0); };
        console.log(canvasPic);
    }
}
function cRedo() {
    if (cStep < cPushArray.length - 1) {
        cStep++;
        var canvasPic = new Image();
        canvasPic.src = cPushArray[cStep];
        canvasPic.onload = function() { ctx.drawImage(canvasPic, 0, 0); }
    }
}
canvas {
    
    border: 2px solid black;
    
}
<!DOCTYPE html>
<html>
<head>
    
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    
    <link rel="stylesheet" type="text/css" href="style.css">

</head>

<body onload="InitThis();">
    
    <div>
    
        <canvas id="myCanvas" width="500" height="200"></canvas>
        <br /><br />
        <button onclick="javascript:clearArea(); return false;">Clear Area</button>
        Line width : <select id="selWidth">
            <option value="1">1</option>
            <option value="3" selected="selected">3</option>
            <option value="5">5</option>
            <option value="7">7</option>
            <option value="9">9</option>
            <option value="11">11</option>
        </select>
        
        Color : <select id="selColor">
            <option value="black" selected="selected">black</option>
            <option value="blue">blue</option>
            <option value="red">red</option>
            <option value="green">green</option>
            <option value="yellow">yellow</option>
            <option value="gray">gray</option>
        </select>
        
        <button onclick="javascript:cUndo();return false;">Undo</button>
        <button onclick="javascript:cRedo();return false;">Redo</button>
    </div>
    
    
    <script type="text/javascript" src="script.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    
</body>
    



</html>
Itairozen
  • 79
  • 8

1 Answers1

1

You need to clear the canvas before drawing the saved image, when undoing ...

function cUndo() {
   if (cStep > 0) {
      cStep--;
      var canvasPic = new Image();
      canvasPic.onload = function() {
         ctx.clearRect(0, 0, canvas.width, canvas.height); //clear canvas
         ctx.drawImage(canvasPic, 0, 0);
      };
      canvasPic.src = cPushArray[cStep];
      console.log(canvasPic);
   }
}

Use clearRect() method to clear the canvas.

ɢʀᴜɴᴛ
  • 32,025
  • 15
  • 116
  • 110
  • Ok it works, why is the `canvasPic.src = cPushArray[cStep];` after the `drawImage()` – Itairozen Jul 07 '17 at 09:48
  • 1
    It's a best practice. See [this](https://stackoverflow.com/questions/14648598/is-it-necessary-to-set-onload-function-before-setting-src-for-an-image-object). – ɢʀᴜɴᴛ Jul 07 '17 at 09:50