2014-09-13 164 views
0

我很想知道諸如Adobe Photoshop等應用程序如何實現其繪圖歷史,能夠返回或撤消光柵化圖形上的筆劃,而不必從頭開始重繪每筆畫...HTML5畫布繪圖歷史

我想要在我正在處理的HTML5繪圖應用程序上實現類似的歷史記錄功能,但是在每次寫入後重復畫布似乎會使用太多的內存來成爲實用的方法,特別是在較大的畫布上。 。

有關如何以實用和有效的方式實現這一點的任何建議?

+2

不要在每次中風後保存整個畫布。將每個繪圖命令保存到一個數組中。然後你可以通過彈出數組末尾的最後一個元素來撤銷,清除畫布並重繪所有剩餘的元素(==重新執行所有剩下的繪圖命令)。 – markE 2014-09-13 04:15:24

+0

是的,這就是我想要避免的,因爲它需要很長的時間來重繪...我想知道Photoshop和類似的應用程序如何處理它,他們不會從一開始就重繪一切... – user1960364 2014-09-13 05:19:27

+0

畫布速度足夠快從頭開始重繪大多數圖紙。儘管我沒有Photoshop源代碼,但我懷疑PS實際上是使用命令重新繪製而不是保存整個柵格斷點。我這樣說是因爲PS歷史列出了所有的命令。而PS的行動當然是通過玩命令來工作的。 – markE 2014-09-13 05:32:55

回答

1

我可能有一個解決方案.....

var ctx = document.getElementById("canvasId").getContext("2d"); 
var DrawnSaves = new Array(); 
var Undo = new Array(); 
var FigureNumber = 0; 
var deletingTimer; 
function drawLine(startX, startY, destX, destY) { 
    ctx.beginPath(); 
    ctx.moveTo(startX, startY); 
    ctx.lineTo(destX, destY); 
    ctx.stroke(); 
    var Para = new Array(); 
    Para["type"] = "line"; 
    Para["fromX"] = startX; 
    Para["fromY"] = startY; 
    Para["toX"] = destX; 
    Para["toY"] = destY; 
    DrawnSaves.push(Para); 
    FigureNumber++; 
} 
function undo() { 
    ctx.beginPath(); 
    ctx.clearRect(0, 0, 500, 500); 
    Undo[FigureNumber] = DrawnSaves[FigureNumber]; 
    DrawnSaves[FigureNumber] = "deleted"; 
    FigureNumber--; 
    drawEverything(); 
    startTimeoutOfDeleting(); 
} 
function undoTheUndo() { 
    FigureNumber++; 
    DrawnSaves[FigureNumber] = Undo[FigureNumber]; 
    drawEverything(); 
    clearTimeout(deletingTimer); 
} 
function drawEverything() { 
    for (i = 0; i < DrawnSaves.length; i++) { 
     if (DrawnSaves[i].type == "line") { 
      ctx.beginPath(); 
      ctx.moveTo(DrawnSaves[i].fromX, DrawnSaves[i].fromY); 
      ctx.lineTo(DrawnSaves[i].toX, DrawnSaves[i].toY); 
      ctx.stroke(); 
     } 
    } 
} 
function startTimeoutOfDeleting() { 
    setTimeout(function() {Undo[FigureNumber] = "deleted";}, 5000); 
} 

這是非常簡單的,首先我畫一條線,當函數被調用,並保存他的陣列中的所有參數。然後,在撤銷功能中,我只需啓動一個計時器,刪除繪製的圖形2000毫秒,清除整個畫布並使其無法重繪。在undoTheUndo函數中,它會停止計時器以刪除圖形並使該圖形可以重新繪製。在drawEverything函數中,它根據數組的類型(「line here」)繪製數組中的所有內容。就是這樣...... :-) 這是一個工作示例:This, after 2sec UNDOs then after 1sec UNDOTHEUNDO