Sin ninguna biblioteca de extensión, ¿es posible tener varias capas en el mismo elemento de lienzo?
Entonces, si hago un clearRect en la capa superior, ¿no borrará la capa inferior?
Gracias.
Sin ninguna biblioteca de extensión, ¿es posible tener varias capas en el mismo elemento de lienzo?
Entonces, si hago un clearRect en la capa superior, ¿no borrará la capa inferior?
Gracias.
Respuestas:
No, sin embargo, podría superponer varios <canvas>
elementos uno encima del otro y lograr algo similar.
<div style="position: relative;">
<canvas id="layer1" width="100" height="100"
style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
<canvas id="layer2" width="100" height="100"
style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>
Dibuja tu primera capa en el layer1
lienzo y la segunda capa en el layer2
lienzo. Luego, cuando esté clearRect
en la capa superior, se mostrará lo que esté en el lienzo inferior.
display: none;
. O simplemente limpie el lienzo, si no es muy costoso volver a dibujarlo nuevamente cuando se muestre la capa.
Relacionado con esto:
Si tiene algo en su lienzo y desea dibujar algo en la parte posterior, puede hacerlo cambiando la configuración context.globalCompositeOperation a 'destination-over' y luego vuelva a 'source-over' cuando usted ' re hecho.
var context = document.getElementById('cvs').getContext('2d');
// Draw a red square
context.fillStyle = 'red';
context.fillRect(50,50,100,100);
// Change the globalCompositeOperation to destination-over so that anything
// that is drawn on to the canvas from this point on is drawn at the back
// of what's already on the canvas
context.globalCompositeOperation = 'destination-over';
// Draw a big yellow rectangle
context.fillStyle = 'yellow';
context.fillRect(0,0,600,250);
// Now return the globalCompositeOperation to source-over and draw a
// blue rectangle
context.globalCompositeOperation = 'source-over';
// Draw a blue rectangle
context.fillStyle = 'blue';
context.fillRect(75,75,100,100);
<canvas id="cvs" />
Puede crear varios canvas
elementos sin agregarlos al documento. Estas serán tus capas :
Luego, haga lo que quiera con ellos y, al final, simplemente presente su contenido en el orden correcto en el lienzo de destino usando drawImage
on context
.
Ejemplo:
/* using canvas from DOM */
var domCanvas = document.getElementById('some-canvas');
var domContext = domCanvas.getContext('2d');
domContext.fillRect(50,50,150,50);
/* virtual canvase 1 - not appended to the DOM */
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(50,50,150,150);
/* virtual canvase 2 - not appended to the DOM */
var canvas2 = document.createElement('canvas')
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'yellow';
ctx2.fillRect(50,50,100,50)
/* render virtual canvases on DOM canvas */
domContext.drawImage(canvas, 0, 0, 200, 200);
domContext.drawImage(canvas2, 0, 0, 200, 200);
Y aquí hay algunos codepen: https://codepen.io/anon/pen/mQWMMW
También tenía este mismo problema, mientras que múltiples elementos de lienzo con posición: absoluto hacen el trabajo, si desea guardar la salida en una imagen, eso no va a funcionar.
Así que seguí adelante e hice un "sistema" de capas simple para codificar como si cada capa tuviera su propio código, pero todo se representa en el mismo elemento.
https://github.com/federicojacobi/layeredCanvas
Tengo la intención de agregar capacidades adicionales, pero por ahora lo hará.
Puede realizar múltiples funciones y llamarlas para "simular" capas.
También puede consultar http://www.concretejs.com, que es un marco de lienzo Html5 moderno y liviano que permite la detección de golpes, la estratificación y muchas otras cosas periféricas. Puedes hacer cosas como esta:
var wrapper = new Concrete.Wrapper({
width: 500,
height: 300,
container: el
});
var layer1 = new Concrete.Layer();
var layer2 = new Concrete.Layer();
wrapper.add(layer1).add(layer2);
// draw stuff
layer1.sceneCanvas.context.fillStyle = 'red';
layer1.sceneCanvas.context.fillRect(0, 0, 100, 100);
// reorder layers
layer1.moveUp();
// destroy a layer
layer1.destroy();
Entiendo que el Q no quiere usar una biblioteca, pero lo ofreceré a otros que provengan de búsquedas de Google. @EricRowell mencionó un buen complemento, pero también hay otro complemento que puedes probar, html2canvas .
En nuestro caso, estamos usando PNG transparentes en capas con z-index
un widget de "creador de productos". Html2canvas funcionó de manera brillante para reducir la pila sin presionar imágenes, ni utilizar complejidades, soluciones alternativas y el lienzo "no sensible". No pudimos hacer esto sin problemas con el lienzo de vainilla + JS.
Primer uso z-index
en divs absolutos para generar contenido en capas dentro de un contenedor posicionado relativo. Luego canalice el contenedor a través de html2canvas para obtener un lienzo renderizado, que puede dejar tal cual, o generar como una imagen para que un cliente pueda guardarlo.
pero la capa 02 cubrirá todos los dibujos de la capa 01. Utilicé esto para mostrar el dibujo en ambas capas. use (background-color: transparent;) en estilo.
<div style="position: relative;">
<canvas id="lay01" width="500" height="500" style="position: absolute; left: 0; top: 0; z-index: 0; background-color: transparent;">
</canvas>
<canvas id="lay02" width="500" height="500" style="position: absolute; left: 0; top: 0; z-index: 1; background-color: transparent;">
</canvas>
</div>