有什么简单的方法可以在 Kineticjs中创建撤消重做功能吗?我在https://github.com/ArthurClemens/Javascript-Undo-Manager中找到了 HTML 5 的撤消管理器,但我不知道如何放入 Kineticjs,请帮助我。谢谢你。
4 回答
我能够根据Chtiwi Malek 在 CodiCode 的帖子实现一个简单的解决方案。我还使用了这个问题中的一些代码作为示例来绘制矩形,因此感谢他们和 Chtiwi。
我的解决方案的唯一区别是我使用 toJSON() 将每个图层状态存储在一个数组中,而不是画布上的 toDataURL()。我认为 toJSON() 需要 toDataURL() 才能序列化在画布上存储每个动作所需的所有数据,但我不是 100% 对此,所以如果其他人知道请发表评论。
function makeHistory() {
historyStep++;
if (historyStep < history.length) {
history.length = historyStep;
}
json = layer.toJSON();
history.push(json);
}
每次要保存步骤以撤消或重做时调用此函数。在我的例子中,我在每个 mouseup 事件上调用这个函数。
将这两个函数绑定到 Undo/Redo 事件。
function undoHistory() {
if (historyStep > 0) {
historyStep--;
layer.destroy();
layer = Kinetic.Node.create(history[historyStep], 'container')
stage.add(layer);
}
}
function redoHistory() {
if (historyStep < history.length-1) {
historyStep++;
layer.destroy();
layer = Kinetic.Node.create(history[historyStep], 'container')
stage.add(layer);
}
}
这是jsfiddle。不要忘记初始化数组和步进计数器。祝你好运!
我不熟悉 KineticJS,但该方法应该类似于提供的演示(也使用画布)。
也许另一个例子有帮助。假设我有一个应用程序来创建/移动/删除代表音符的彩色形状。我有一种方法可以单击并突出显示选定的笔记。按键盘上的 Delete 会调用函数 onDeleteGroup:
onDeleteGroup: function(gridModel) {
// collect all notes in an array
// ...
this._deleteGroup(notes);
this.undoManager.register(
this, this._createGroup, [notes], 'Undo delete',
this, this._deleteGroup, [notes], 'Redo delete'
);
}
所有笔记都被删除,并且在 undo manager 中注册了 2 个方法:
- 撤消功能(将创建删除撤消)
- 重做功能(撤消/创建后将再次删除)
这两个功能都很简单:
_deleteGroup:function(notes) {
// removes each note from the model
// thereby removing them from the canvas
// ...
}
_createGroup:function(notes) {
// add each note to the model
// thereby adding them to the canvas
// ...
}
如您所见,数据对象(笔记数组)被传递用于创建和删除。您可以对单个对象执行相同的操作。
要解决事件侦听器问题,请继续制作克隆
$scope.makeHistory=function() {
$scope.historyStep++;
if ($scope.historyStep < $scope.history.length) {
$scope.history.length = $scope.historyStep;
}
var layerC = $scope.topLayer.clone();
$scope.history.push(layerC);
};
$scope.undoObject = function(){
if($scope.historyStep > 0) {
$scope.historyStep--;
$scope.topLayer.destroy();
if($scope.historyStep==0){
$scope.topLayerAdd(2); // will put empty layer
}
else{
var layer = $scope.history[$scope.historyStep-1].clone();
$scope.topLayerAdd(1,layer);
}
$scope.topLayer.draw();
}
};
$scope.redoObject = function(){
if($scope.historyStep <= $scope.history.length-1) {
$scope.historyStep++;
$scope.topLayer.destroy();
var layer = $scope.history[$scope.historyStep-1].clone();
if($scope.historyStep==0){
$scope.topLayerAdd(2); // will put empty layer
}
else{
$scope.topLayerAdd(1,layer);
}
$scope.topLayer.draw();
}
};
非常适合我。