我正在使用HTML5画布创建一个Web应用程序来绘制图像(比如绘制web),我尝试实现“撤消”(ctrl + Z)和“重做”功能,这里我面临着一个奇怪的问题的画布元素。 有时候,当我按下ctrl + Z来撤消时,会出现一个空白图像,但是数据在数组中并且我指向正确的元素(因为当我使用undo / redo时,我设法以正确的顺序校正图像)。
如果您可以查看以下代码,我将不胜感激,我已经花了很多时间,而且我无法找到问题......: - (
function Stack(firstImg , size) {
var drawStack = new Array();
var stackIndex = 0;
var stackTop = 0;
var stackFloor = 0;
var stackSize = size;
drawStack[0] = firstImg;
this.add = function() {
drawStack[++stackIndex%stackSize] = cvs.toDataURL("image/png");
if (stackIndex >= stackSize) stackFloor = (stackIndex +1) % stackSize ;
stackTop = stackIndex % stackSize;
}
this.undo = function () {
if (stackIndex%stackSize == stackFloor ) return;
clearCanvas();
var tmpImg = new Image();
tmpImg.src = drawStack[--stackIndex%stackSize];
cvsCtx.drawImage(tmpImg, 0, 0);
}
this.redo = function () {
if (stackIndex%stackSize == stackTop) return;
clearCanvas();
var tmpImg = new Image();
tmpImg.src = drawStack[++stackIndex%stackSize];
cvsCtx.drawImage(tmpImg, 0, 0);
}
}
我会采取任何解决方案或解决方法,非常感谢!!
答案 0 :(得分:6)
我已经实现了几次撤消/重做功能,虽然由于许可原因我无法发布代码,但我可以给你一些伪造的代码,它应该演示一下undo / redo实际上是多么简单:
首先,你需要两个数组。称这些为“撤消”和“重做”。
每次状态改变时,将该状态推送到撤消堆栈。
当用户按下ctrl-z(撤消)时,从撤消堆栈中弹出上次保存的状态。将此状态推送到重做队列,并使其成为当前状态。
当用户按下ctrl-y(重做)时,从重做队列中弹出上次保存的状态。
如果其中一个阵列开始填满你要保存的状态数,请使用shift来丢弃最旧的状态。
有关push,pop和shift的参考,请参阅MDN documentation。
另外,你可能会发现自己希望数组有窥视,所以这就是:
Array.prototype.peek = function () {
var theArray = this;
var temp = theArray.pop();
if (temp !== undefined) {
theArray.push(temp);
}
return temp;
};
编辑:我的代码片段中有一个错误,在空数组上调用.peek()将推送未定义。