Senza alcuna libreria di estensioni, è possibile avere più livelli nello stesso elemento canvas?
Quindi, se eseguo un clearRect sul livello superiore, non cancellerà quello inferiore?
Grazie.
Senza alcuna libreria di estensioni, è possibile avere più livelli nello stesso elemento canvas?
Quindi, se eseguo un clearRect sul livello superiore, non cancellerà quello inferiore?
Grazie.
Risposte:
No, tuttavia, potresti <canvas>
sovrapporre più elementi uno sopra l'altro e realizzare qualcosa di simile.
<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>
Disegna il tuo primo livello sulla layer1
tela e il secondo livello sulla layer2
tela. Quindi quando sei clearRect
sul livello superiore, tutto ciò che è sulla tela inferiore verrà mostrato.
display: none;
. O semplicemente cancella la tela, se non è super costoso ridisegnarla di nuovo quando dovrebbe essere mostrato il livello.
Correlato a questo:
Se hai qualcosa sulla tua tela e vuoi disegnare qualcosa sul retro - puoi farlo cambiando l'impostazione context.globalCompositeOperation su 'destination-over' - e poi riportalo a 'source-over' quando ' fatto.
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" />
È possibile creare più canvas
elementi senza aggiungerli al documento. Questi saranno i tuoi livelli :
Quindi fai quello che vuoi con loro e alla fine rendi il loro contenuto nell'ordine corretto nell'area di destinazione usando drawImage
su context
.
Esempio:
/* 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);
Ed ecco alcuni codici: https://codepen.io/anon/pen/mQWMMW
Anch'io stavo avendo lo stesso problema, mentre io ho più elementi canvas con position: absolute fa il lavoro, se vuoi salvare l'output in un'immagine, non funzionerà.
Quindi sono andato avanti e ho creato un semplice "sistema" di stratificazione per codificare come se ogni livello avesse il proprio codice, ma tutto viene reso nello stesso elemento.
https://github.com/federicojacobi/layeredCanvas
Ho intenzione di aggiungere funzionalità extra, ma per ora lo farà.
Puoi fare più funzioni e chiamarle per "fingere" i livelli.
Potresti anche dare un'occhiata a http://www.concretejs.com che è un framework di tela Html5 moderno, leggero, che consente il rilevamento di hit, la stratificazione e molte altre cose periferiche. Puoi fare cose del genere:
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();
Comprendo che la Q non desidera utilizzare una libreria, ma la offrirò per altri provenienti da ricerche su Google. @EricRowell ha menzionato un buon plugin, ma c'è anche un altro plugin che puoi provare, html2canvas .
Nel nostro caso stiamo usando PNG trasparenti a strati con z-index
come widget "Product Builder". Html2canvas ha funzionato brillantemente per ridurre la pila senza spingere le immagini, né usando complessità, soluzioni alternative e la tela "non reattiva" stessa. Non siamo riusciti a farlo in modo uniforme / sano con la tela alla vaniglia + JS.
Primo utilizzo z-index
su div assoluti per generare contenuto a strati all'interno di un wrapper posizionato relativo. Quindi reindirizzare il wrapper attraverso html2canvas per ottenere un'area di rendering, che può essere lasciata così com'è o prodotta come immagine in modo che un client possa salvarla.
ma il livello 02 coprirà tutti i disegni nel livello 01. L'ho usato per mostrare il disegno in entrambi i livelli. usa (background-color: transparent;) nello stile.
<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>