Как добавить отмененную функциональность в HTML5 Canvas? - PullRequest
10 голосов
/ 23 июня 2010

У меня есть приложение для создания эскизов, выполненное во всех HTML5 и Javascript, и мне было интересно, как бы я создал кнопку отмены, чтобы вы могли отменить последнее, что нарисовали. Есть идеи?

Ответы [ 4 ]

13 голосов
/ 23 июня 2010

Вы должны хранить все модификации в структуре данных.Затем вы можете удалить последнюю модификацию, если пользователь хочет отменить ее.Затем вы перерисовываете все операции рисования из своей структуры данных.

3 голосов
/ 12 ноября 2010

Вкл. http://arthurclemens.github.io/Javascript-Undo-Manager/ У меня есть рабочий пример отмены с элементом canvas. Когда вы вносите изменения, вы передаете менеджеру отмены методы отмены и возврата. Отслеживание позиции в стеке отмены производится автоматически. Исходный код на Github.

1 голос
/ 21 ноября 2011

Другой вариант, если вам нужно манипулировать объектами, это преобразовать ваш холст в SVG с помощью библиотеки, которая сохраняет Canvas API, предотвращая перезапись.

По крайней мере одна такая библиотека существует в это время (ноябрь 2011): SVGKit

Если у вас есть SVG, гораздо проще удалять объекты и многое другое без необходимости перерисовывать весь холст.

0 голосов
/ 04 февраля 2015

Вот решение, которое работает для меня.Я пробовал его в последних версиях Firefox и Chrome, и он действительно хорошо работает в этих двух браузерах.

var isFirefox = typeof InstallTrigger !== 'undefined';
var ctx = document.getElementById('myCanvas').getContext("2d");
var CanvasLogBook = function() {
    this.index = 0;
    this.logs = [];
    this.logDrawing();
};
CanvasLogBook.prototype.sliceAndPush = function(imageObject) {
    var array;
    if (this.index == this.logs.length-1) {
        this.logs.push(imageObject);
        array = this.logs;
    } else {
        var tempArray = this.logs.slice(0, this.index+1);
        tempArray.push(imageObject);
        array = tempArray;
    }
    if (array.length > 1) {
        this.index++;
    }
    return array;
};
CanvasLogBook.prototype.logDrawing = function() { 
    if (isFirefox) {
        var image = new Image();
        image.src = document.getElementById('myCanvas').toDataURL();
        this.logs = this.sliceAndPush(image);
    } else {
        var imageData = document.getElementById('myCanvas').toDataURL();
        this.logs = this.sliceAndPush(imageData);
    }
};
CanvasLogBook.prototype.undo = function() {
    ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height());
    if (this.index > 0) {
        this.index--;
        this.showLogAtIndex(this.index);
    }
};
CanvasLogBook.prototype.redo = function() {
    if (this.index < this.logs.length-1) {
        ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height());
        this.index++;
        this.showLogAtIndex(this.index);
    }
};
CanvasLogBook.prototype.showLogAtIndex = function(index) {
    ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height());
    if (isFirefox) {
        var image = this.logs[index];
        ctx.drawImage(image, 0, 0);
    } else {
        var image = new Image();
        image.src = this.logs[index];
        ctx.drawImage(image, 0, 0);
    }
};
var canvasLogBook = new CanvasLogBook();

Так что каждый раз, когда вы рисуете что-либо, вы будете появляться после запуска функции canvasLogBook.logDrawing () длясохраните снимок холста, а затем вы можете вызвать canvasLogBook.undo () для отмены и canvasLogBook.redo () для повторения.

...