2011-04-11 114 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; 
    }; 
}; 

你不想清除重做操作,直到您通過數組跑。

(猜登錄編輯幫助前!)