2014-09-13 274 views
0

我很想知道诸如Adobe Photoshop等应用程序如何实现其绘图历史,能够返回或撤消光栅化图形上的笔划,而不必从头开始重绘每笔画...HTML5画布绘图历史

我想要在我正在处理的HTML5绘图应用程序上实现类似的历史记录功能,但是在每次写入后重复画布似乎会使用太多的内存来成为实用的方法,特别是在较大的画布上。 。

有关如何以实用和有效的方式实现这一点的任何建议?

+2

不要在每次中风后保存整个画布。将每个绘图命令保存到一个数组中。然后你可以通过弹出数组末尾的最后一个元素来撤销,清除画布并重绘所有剩余的元素(==重新执行所有剩下的绘图命令)。 – markE 2014-09-13 04:15:24

+0

是的,这就是我想要避免的,因为它需要很长的时间来重绘...我想知道Photoshop和类似的应用程序如何处理它,他们不会从一开始就重绘一切... – user1960364 2014-09-13 05:19:27

+0

画布速度足够快从头开始重绘大多数图纸。尽管我没有Photoshop源代码,但我怀疑PS实际上是使用命令重新绘制而不是保存整个栅格断点。我这样说是因为PS历史列出了所有的命令。而PS的行动当然是通过玩命令来工作的。 – markE 2014-09-13 05:32:55

回答

1

我可能有一个解决方案.....

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); 
} 

这是非常简单的,首先我画一条线,当函数被调用,并保存他的阵列中的所有参数。然后,在撤销功能中,我只需启动一个计时器,删除绘制的图形2000毫秒,清除整个画布并使其无法重绘。在undoTheUndo函数中,它会停止计时器以删除图形并使该图形可以重新绘制。在drawEverything函数中,它根据数组的类型(“line here”)绘制数组中的所有内容。就是这样...... :-) 这是一个工作示例:This, after 2sec UNDOs then after 1sec UNDOTHEUNDO