如何向HTML5 Canvas添加撤消功能?

时间:2010-06-23 06:18:56

标签: javascript html html5 canvas undo

我在所有HTML5和Javascript中都有一个草绘应用程序,我想知道如何创建一个撤消按钮,所以你可以撤消你画的最后一件事。有什么想法吗?

4 个答案:

答案 0 :(得分:13)

您必须将所有修改存储在数据结构中。然后,如果用户想撤消,您可以删除最新修改。然后再次重新绘制数据结构中的所有绘图操作。

答案 1 :(得分:3)

On http://arthurclemens.github.io/Javascript-Undo-Manager/我有一个使用canvas元素撤消的工作示例。进行修改时,可以向撤消管理器提供撤消和重做方法。跟踪撤消堆栈中的位置是自动完成的。源代码在Github。

答案 2 :(得分:1)

如果您需要操作对象,另一个选项是使用保留Canvas API的库来阻止重写,从而将画布转换为SVG。

目前至少存在一个此类图书馆(2011年11月): SVGKit

拥有SVG后,无需重绘整个画布就可以更轻松地删除对象等等。

答案 3 :(得分:0)

这是一个适合我的解决方案。我在最新版本的Firefox和Chrome中尝试过它,它在这两种浏览器中运行得非常好。

var isFirefox = typeof InstallTrigger !== 'undefined';
var ctx = document.getElementById('myCanvas').getContext("2d");
var CanvasLogBook = function() {
    this.index = 0;
    this.logs = [];
    this.logDrawing();
};
CanvasLogBook.prototype.sliceAndPush = function(imageObject) {
    var array;
    if (this.index == this.logs.length-1) {
        this.logs.push(imageObject);
        array = this.logs;
    } else {
        var tempArray = this.logs.slice(0, this.index+1);
        tempArray.push(imageObject);
        array = tempArray;
    }
    if (array.length > 1) {
        this.index++;
    }
    return array;
};
CanvasLogBook.prototype.logDrawing = function() { 
    if (isFirefox) {
        var image = new Image();
        image.src = document.getElementById('myCanvas').toDataURL();
        this.logs = this.sliceAndPush(image);
    } else {
        var imageData = document.getElementById('myCanvas').toDataURL();
        this.logs = this.sliceAndPush(imageData);
    }
};
CanvasLogBook.prototype.undo = function() {
    ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height());
    if (this.index > 0) {
        this.index--;
        this.showLogAtIndex(this.index);
    }
};
CanvasLogBook.prototype.redo = function() {
    if (this.index < this.logs.length-1) {
        ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height());
        this.index++;
        this.showLogAtIndex(this.index);
    }
};
CanvasLogBook.prototype.showLogAtIndex = function(index) {
    ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height());
    if (isFirefox) {
        var image = this.logs[index];
        ctx.drawImage(image, 0, 0);
    } else {
        var image = new Image();
        image.src = this.logs[index];
        ctx.drawImage(image, 0, 0);
    }
};
var canvasLogBook = new CanvasLogBook();

因此,每次绘制任何东西后,您都会在运行函数canvasLogBook.logDrawing()之后存储画布的快照,然后可以调用canvasLogBook.undo()来撤消,而将canvasLogBook.redo()调用到重做。 / p>