我有一个使用所有HTML5和Javascript完成的Sketching应用程序,我想知道如何创建一个“撤消按钮”,以便您可以撤消最后绘制的内容。有什么主意吗?
您必须将所有修改存储在数据结构中。然后,如果用户要撤消,可以删除最新的修改。然后,再次从数据结构重新绘制所有绘图操作。
在http://arthurclemens.github.io/Javascript-Undo-Manager/上,我有一个带有画布元素的撤消工作示例。进行修改时,您将撤消和重做方法提供给撤消管理器。撤消堆栈中的位置跟踪是自动完成的。源代码位于Github。
另一个选择,如果您需要操作对象,则使用保留Canvas API防止重写的库将画布转换为SVG。
目前(2011年11月,至少存在一个这样的库:SVGKit
一旦有了SVG,删除对象就容易得多,而且无需重新绘制整个画布。
以下是对我有用的解决方案。我已经在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()来进行重做。