2011-04-11 99 views
0

我要实现上可以用JavaScript我怎么能这样被拖着svgElements功能,可以dragable元素(拖放)...申请撤销重做上

我曾与鼠标向上

实现了这个

当鼠标抬起时,我保存的X和Y位置,对象ID,对象类型(圆形,矩形等)

任何一个可以告诉...为实现这个好办法吗?

回答

1

如果您问的是如何实现一般的撤销/重做功能,这很简单:您有一组操作和一个计数器。当操作发生时,您可以将新元素推入阵列,并在人们撤消时将其倒退。

非常基本的实现:

var history = { 
    stack : [], 
    counter : -1, 
    add  : function(item){ 
     this.stack[++counter] = item; 
     this.doSomethingWith(item); 

     // delete anything forward of the counter 
     this.stack.splice(this.counter+1); 
    }, 
    undo : function(){ 
     this.doSomethingWith(this.stack[--counter]); 
    }, 
    redo : function(){ 
     this.doSomethingWith(this.stack[++counter]); 
    }, 
    doSomethingWith : function(item){ 
     // show item 
    } 
}; 

注意,应该有基本的错误检查看到,柜台没有超越界限,并且你可能想通过“撤消”信息到doSomethingWith在的情况下,撤消,但所有这些都是特定于应用程序的。

1

cwolves描述了撤销/重做功能的良好结构。

你是对的,在鼠标移动过程中,你需要存储历史记录,但是你还需要存储在鼠标移动过程中被操作的对象的原始位置,所以你会在撤消移动时已经拥有了它。

如果您最终进一步考虑并允许缩放,则您需要存储完整的原始转换,例如“翻译(10,10)缩放(1.2,1.2)旋转(90)”,对于历史记录,还可以使用拖放缩放操作的基线。

+0

感谢乔希·皮尔斯,onmousedown事件,如果我保存的位置可以节省两个时间(因为它节省的mouseup还)我已经差不多完成了......但问题是有保存上次位置2次..当我按撤消按钮2次然后对象撤消(走到最后的位置) – 2011-04-13 06:54:17

2

我在这个例子中看到一个小问题,你有时会忘记这个。

var history = { 
    stack : [], 
    counter : -1, 
    add  : function(item){ 
     this.stack[++this.counter] = item; 
     this.doSomethingWith(item); 

     // delete anything forward of the counter 
     this.stack.splice(this.counter+1); 
    }, 
    undo : function(){ 
     this.doSomethingWith(this.stack[--this.counter]); 
    }, 
    redo : function(){ 
     this.doSomethingWith(this.stack[++this.counter]); 
    }, 
    doSomethingWith : function(item){ 
     // show item 
    } 
}; 
1

我发现一个没有计数器,索引移位或限制处理问题的更好的结构。 只需2堆栈即可完成平衡的“完成”和“恢复”操作。

var history = function() { 
    this.done = this.reverted = []; 
    var self = this; 

    this.add = function(item) { 
     self.done.push(item); 

     // delete anything forward 
     self.reverted = []; 
    }; 

    this.undo = function() { 
     var item = self.done.pop(); 

     if (item) { 
      self.reverted.push(item); 
     } 

     return item; 
    }; 

    this.redo = function() { 
     var item = self.reverted.pop(); 

     if (item) { 
      self.done.push(item); 
     } 

     return item; 
    }; 
}; 
0

上述代码存在一些问题。 我试图使用这些,并发现我必须在开始关闭数组之前最初进行两次撤销。

所以说我已经完成了[0] done [1] done [2]。 done [2]刚刚保存到数组中。如果我点击撤消,它会返回。你不想那样。它正在取代那里已经存在的东西。但是再次触发撤消,那么你得到你以前的代码。

因为我有一个具有不同编辑模式的拖放编辑器。拖放元素。编辑元素HTML /图片。排序元素。

$(“#neoContentContainer”)包含所有编辑器html。 你可以通过点击,mousedowns等来调用editor_add ...看到它是一个你可以轻松调用的函数。

function editor_add(){ 
    undo.push($("#neoContentContainer").html()); 
    update_buttons(); 
} 
function editor_undo(){ 
    var item = undo.pop(); 
    // prevent undo/redo from undoing to the same HTML currently shown. 
    if(item == $("#neoContentContainer").html()){ 
     redo.push(item); 
     item = undo.pop(); 
    } 
    if(item){ 
     redo.push(item); 
     $("#neoContentContainer").html(item); 
    } 
    update_buttons(); 
} 
function editor_redo(){ 
    var item = redo.pop(); 
    if(item == $("#neoContentContainer").html()){ 
     undo.push(item); 
     item = redo.pop(); 
    } 
    if(item){ 
     undo.push(item); 
     $("#neoContentContainer").html(item); 
    } 
    update_buttons(); 
} 
function update_buttons(){ 
    if(undo.length == 0){ 
     $('button[data-id="undo"]').attr('disabled',true); 
    } else { 
     $('button[data-id="undo"]').attr('disabled',false); 
    } 

    if(redo.length == 0){ 
     $('button[data-id="redo"]').attr('disabled',true); 
    } else { 
     $('button[data-id="redo"]').attr('disabled',false); 
    } 
} 

https://jsfiddle.net/s1L6vv5y/

并不完美,但得到它的JIST。 (仍然想知道什么时候我们可以得到一条线路断线!!!! DEVS在STACKOVERFLOW !! :)

所以当我的页面加载时,我运行:editor_add(); 因为当他们做某事时,它需要撤销某些东西!

现在,每次他们放下东西,排序我运行editor_add();整天带着我,现在意识到这对我来说非常有效。

所以这一个,这是很好的....

var history = function() { 
    this.done = this.reverted = []; 
    var self = this; 

    this.add = function(item) { 
     self.done.push(item); 
    }; 

    this.undo = function() { 
     if(done.length >= 3){ 
      var undo_item = self.done.pop(); 
      self.reverted.push(undo_item); 
     } 

     var item = self.done.pop(); 
     if (item) { 
      self.reverted.push(item); 
     } 

     return item; 
    }; 

    this.redo = function() { 
     if(reverted.length >= 3){ 
      var revert_item = self.reverted.pop(); 
      self.done.push(revert_item); 
     } 
     var item = self.reverted.pop(); 
     if (item) { 
      self.done.push(item); 
     } 

     return item; 
    }; 
}; 

你不想清除重做操作,直到您通过数组跑。

(猜登录编辑帮助前!)