【发布时间】:2010-06-23 06:18:55
【问题描述】:
我有一个使用所有 HTML5 和 Javascript 编写的草图应用程序,我想知道如何创建一个撤消按钮,以便您可以撤消您最后绘制的内容。有什么想法吗?
【问题讨论】:
-
为什么标签里有java和objective-c?
标签: javascript html canvas
我有一个使用所有 HTML5 和 Javascript 编写的草图应用程序,我想知道如何创建一个撤消按钮,以便您可以撤消您最后绘制的内容。有什么想法吗?
【问题讨论】:
标签: javascript html canvas
您必须将所有修改存储在数据结构中。然后,如果用户想要撤消它,您可以删除最新的修改。然后再次从数据结构中重新绘制所有绘图操作。
【讨论】:
在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() 来重做。
【讨论】:
isFirefox 布尔值,这将是一个很好的答案 :)