HTML5 Canvas Drawing History

2019-09-07 11:57发布

I'm curious to know how applications such as Adobe Photoshop implement their drawing history with the ability to go back or undo strokes on rasterized graphics without having to redraw each stroke from the beginning...

I'm wanting to implement a similar history function on an HTML5 drawing application I'm working on but duplicating the canvas after every stoke seems like it'd use too much memory to be a practical approach, especially on larger canvas'...

Any suggestions on how this might be implemented in a practical and efficient manner?

1条回答
该账号已被封号
2楼-- · 2019-09-07 12:36

I may have a solution.....

var ctx = document.getElementById("canvasId").getContext("2d");
var DrawnSaves = new Array();
var Undo = new Array();
var FigureNumber = 0;
var deletingTimer;
function drawLine(startX, startY, destX, destY) {
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(destX, destY);
    ctx.stroke();
    var Para = new Array();
    Para["type"] = "line";
    Para["fromX"] = startX;
    Para["fromY"] = startY;
    Para["toX"] = destX;
    Para["toY"] = destY;
    DrawnSaves.push(Para);
    FigureNumber++;
}
function undo() {
    ctx.beginPath();
    ctx.clearRect(0, 0, 500, 500);
    Undo[FigureNumber] = DrawnSaves[FigureNumber];
    DrawnSaves[FigureNumber] = "deleted";
    FigureNumber--;
    drawEverything();
    startTimeoutOfDeleting();
}
function undoTheUndo() {
    FigureNumber++;
    DrawnSaves[FigureNumber] = Undo[FigureNumber];
    drawEverything();
    clearTimeout(deletingTimer);
}
function drawEverything() {
    for (i = 0; i < DrawnSaves.length; i++) {
       if (DrawnSaves[i].type == "line") {
          ctx.beginPath();
          ctx.moveTo(DrawnSaves[i].fromX, DrawnSaves[i].fromY);
          ctx.lineTo(DrawnSaves[i].toX, DrawnSaves[i].toY);
          ctx.stroke();
       }
    }
}
function startTimeoutOfDeleting() {
   setTimeout(function() {Undo[FigureNumber] = "deleted";}, 5000);
}

This is really simple, first I draw a line when the function is called and save all his parameters in an array. Then , in the undo function I just start a timer do delete the figure drawn i 2000 miliseconds, clears the whole canvas and makes it can't be redrawn. in the undoTheUndo function, it stops the timer to delete the figure and makes that the figure can be redrawn. In the drawEverything function, it draws everything in the array based on it's type ("line here"). That's it... :-) Here is an example working : This, after 2sec UNDOs then after 1sec UNDOTHEUNDO

查看更多
登录 后发表回答