Tengo una aplicación de bocetos en HTML5 y Javascript, y me preguntaba cómo crearía un botón Deshacer, por lo que podría deshacer lo último que haya dibujado. ¿Alguna idea?Cómo agregar la funcionalidad de deshacer a HTML5 Canvas?
Respuesta
Debe almacenar todas las modificaciones en una estructura de datos. A continuación, puede eliminar la última modificación si el usuario desea deshacer. Luego vuelve a pintar todas las operaciones de dibujo desde su estructura de datos.
Consulte http://whiffdoc.appspot.com/tests/schema/diagram para ver un ejemplo de cómo hacerlo; en este caso, almacenando una estructura de datos JSON que represente la información del lienzo en un elemento DIV invisible. (siga el enlace de la página a la fuente) –
@AaronWatters, este enlace me dirige a 404. ¿Tiene el enlace actualizado? – link2pk
En http://arthurclemens.github.io/Javascript-Undo-Manager/ Tengo un ejemplo funcional de deshacer con un elemento canvas. Cuando realiza una modificación, alimenta al administrador de deshacer los métodos de deshacer y rehacer. El seguimiento de la posición en la pila de deshacer se realiza automáticamente. El código fuente está en Github.
¡su ejemplo se ve bien! Gracias por compartir –
se ve bien en Chrome, pero no funciona en Firefox – waspinator
He arreglado un par de pequeños errores de dibujo en la demostración. –
La otra opción, si necesita manipular objetos es convertir su lienzo a SVG utilizando una biblioteca que preserve el Canvas API evitando una reescritura.
Al menos uno de estos biblioteca existe en este momento (noviembre de 2011): SVGKit
Una vez que tenga SVG, es mucho más fácil de quitar objetos y mucho más sin la necesidad de volver a dibujar todo el lienzo.
O puede simplemente usar la biblioteca de abstracción de lienzo, como [fabric.js] (http://kangax.github.com/fabric.js/) para poder trabajar con objetos en lienzo mediante programación. – kangax
Excelente @kangax. Tengo curiosidad, ¿cómo crees que fabric.js se podría comparar con SVGKit en términos de rendimiento cuando se trata de editar objetos en lienzos con cientos de nodos? –
No estoy seguro de cómo se compara con SVGKit, pero cuando se trata de una gran cantidad de objetos, el lienzo tiende a ser más eficiente que SVG. Eche un vistazo a algunos benchmarks comparando Raphael (basado en SVG) y fabric (basado en lienzo) - http://fabricjs.com/benchmarks/ – kangax
Aquí hay una solución que funciona para mí. Lo probé en las últimas versiones de Firefox y Chrome y funciona muy bien en esos dos navegadores.
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();
Así que cada vez que dibuje cualquier cosa que existe después de la función de ejecución canvasLogBook.logDrawing() para guardar una instantánea de la tela y luego se le puede llamar canvasLogBook.undo() para deshacer y canvasLogBook.redo() Rehacer.
Esta sería una buena respuesta si no dependiera de jQuery y si se deshace de 'isFirefox' boolean :) – A1rPun
- 1. ¿Cómo implementar la funcionalidad de deshacer?
- 2. cómo enviar contenido DIV a html5 CANVAS
- 3. Cómo agregar un borde en HTML5 Canvas 'Text?
- 4. HTML5 - canvas createLinearGradient vertical
- 5. Conversión de imagen a Canvas/HTML5
- 6. canvas HTML5 "restablecer" fillStyle
- 7. Dart HTML5 Canvas Library?
- 8. HTML5 canvas hittesting
- 9. Canvas HTML5: diferentes trazos
- 10. HTML5 Canvas: zoom
- 11. Diagramas en SVG frente a HTML5 Canvas
- 12. Strange HTML5 Canvas drawComportamiento de la imagen
- 13. HTML5 Canvas Vector Graphics?
- 14. Anti-alias de canvas HTML5?
- 15. canvas de HTML5 marco avanzado
- 16. línea clara en HTML5 Canvas
- 17. apoyo IE9 para la etiqueta HTML5 Canvas
- 18. HTML5 Canvas y Anti-aliasing
- 19. Canvas HTML5: Cómo manejar mousedown mouseup mouseclick
- 20. Cómo utilizar HTML5 <canvas> clip()
- 21. HTML5 Canvas drawing líneas multicolores
- 22. Canvas y HTML5: navegadores compatibles?
- 23. Acelerar HTML5 Canvas píxel renderizado
- 24. cómo agregar tareas prioridad funcionalidad
- 25. Mezcla HTML5 Canvas y Python
- 26. Crear mediante programación HTML5 Canvas
- 27. HTML5 Canvas Mouse Wheel Evento
- 28. HTML5 Canvas Library para UI Widgets
- 29. A * Iniciar búsqueda de ruta en HTML5 Canvas
- 30. HTML5 Canvas evita cualquier representación de subpíxeles
Consulte el [patrón de comando] (http://en.wikipedia.org/wiki/Command_pattern) – Anurag
¿por qué tiene java y object-c en las etiquetas? –