将画布数据保存到数组时出现问题

时间:2012-03-26 15:36:50

标签: javascript jquery image html5 canvas

我正在使用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);
    }
} 

我会采取任何解决方案或解决方法,非常感谢!!

1 个答案:

答案 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()将推送未定义。