J'ai une application Sketching faite dans tous les HTML5 et Javascript, et je me demandais comment je pourrais créer un bouton Annuler, afin que vous puissiez annuler la dernière chose que vous avez dessinée. Une idée?Comment ajouter une fonctionnalité d'annulation à HTML5 Canvas?
Répondre
Vous devez stocker toutes les modifications dans une structure de données. Ensuite, vous pouvez supprimer la dernière modification si l'utilisateur veut annuler il. Ensuite, vous repeignez toutes les opérations de dessin de votre structure de données.
Veuillez consulter http://whiffdoc.appspot.com/tests/schema/diagram pour un exemple de procédure, dans ce cas en stockant une structure de données JSON représentant les informations de canevas dans un élément DIV invisible. (suivez le lien sur la page à la source) –
@AaronWatters, ce lien me dirige vers 404. Avez-vous mis à jour le lien? – link2pk
Sur http://arthurclemens.github.io/Javascript-Undo-Manager/ J'ai un exemple de travail d'annulation avec un élément de canevas. Lorsque vous effectuez une modification, vous indiquez au gestionnaire d'annulation les méthodes d'annulation et de rétablissement. Le suivi de la position dans la pile d'annulation est effectué automatiquement. Le code source est à Github.
votre exemple a l'air bien! Merci pour le partage –
semble bon dans Chrome, mais ne fonctionne pas dans Firefox – waspinator
J'ai corrigé un couple de petits bugs de dessin dans la démo. –
L'autre option, si vous avez besoin de manipuler des objets, est de convertir votre canevas en SVG en utilisant une bibliothèque qui préserve l'API Canvas en empêchant une réécriture.
Au moins une telle bibliothèque existe à ce moment (Novembre 2011): SVGKit
Une fois que vous avez SVG, il est beaucoup plus facile de supprimer des objets et bien plus encore, sans la nécessité de redessiner toute la toile.
Ou il peut simplement utiliser la bibliothèque d'abstraction de toile, comme [fabric.js] (http://kangax.github.com/fabric.js/) pour pouvoir travailler avec des objets sur le canevas par programmation. – kangax
Excellent @kangax. Je suis curieux, comment pensez-vous que fabric.js se compare à SVGKit en termes de performance quand il s'agit d'éditer des objets dans la toile avec des centaines de nœuds? –
Je ne suis pas sûr de savoir comment il se compare à SVGKit, mais quand il s'agit d'un grand nombre d'objets toile a tendance à être plus performant que SVG. Jetez un oeil à quelques benchmarks comparant Raphael (basé sur SVG) et le tissu (sur toile) - http://fabricjs.com/benchmarks/ – kangax
Voici une solution qui fonctionne pour moi. Je l'ai essayé dans les dernières versions de Firefox et Chrome et cela fonctionne très bien dans ces deux navigateurs.
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();
Ainsi, chaque fois que vous dessinez quelque chose vous y après la fonction d'exécution canvasLogBook.logDrawing() pour stocker un instantané de la toile et vous pouvez appeler canvasLogBook.undo() pour annuler et canvasLogBook.redo() refaire
Ce serait une bonne réponse si vous ne dépendiez pas de jQuery et si vous vous débarrassiez du booléen 'isFirefox' :) – A1rPun
Commander le [motif de commande] (http://en.wikipedia.org/wiki/Command_pattern) – Anurag
Pourquoi avez-vous java et objectif-c dans les balises? –