2014-09-13 8 views
0

Я хотел бы знать, как приложения, такие как Adobe Photoshop реализовать свою историю рисования с возможностью вернуться или отменить удары по растровой графике без необходимости перерисовывать каждый удар с самого начала ...HTML5 Canvas Drawing История

Я хочу реализовать аналогичную функцию истории в приложении для рисования HTML5, над которым я работаю, но дублируя холст после каждых стоков, кажется, что он будет использовать слишком много памяти для практического подхода, особенно на более крупном холсте ». .

Любые предложения о том, как это можно реализовать практичным и эффективным образом?

+2

Не пытайтесь сохранить весь холст после каждого удара. Сохраните каждую команду рисования в массив. Затем вы можете отменить, выбирая последний элемент (ы) с конца массива, очищая холст и перерисовывая все остальные элементы (== перезаписывая все остальные команды рисования). – markE

+0

Да, это то, чего я пытаюсь избежать, потому что требуется слишком много времени, чтобы перерисовать ... Мне интересно, как обрабатываются Photoshop и подобные приложения, они не перерисовывают все с самого начала ... – user1960364

+0

Холст достаточно быстр перерисовать большинство рисунков с нуля. Хотя у меня нет источника Photoshop, я подозреваю, что PS действительно перерисовывает с нуля, используя команды, а не сохраняет целые точки останова растра. Я говорю это, потому что в истории PS перечислены все команды. И PS Действия, безусловно, работают, играя в команды. – markE

ответ

1

I может иметь решение .....

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); 
} 

Это действительно просто, сначала я нарисовать линию, когда функция вызывается и сохранить все его параметры в массиве. Затем, в функции отмены, я просто запускаю таймер, удаляю фигуру, нарисованную i 2000 miliseconds, очищает весь холст и заставляет его не перерисовывать. в функции undoTheUndo он останавливает таймер, чтобы удалить фигуру, и делает эту цифру перерисованной. В функции drawEverything он рисует все в массиве на основе его типа («строка здесь»). Вот и все ... :-) Вот пример работы: This, after 2sec UNDOs then after 1sec UNDOTHEUNDO

Смежные вопросы