2010-12-12 12 views
23

Sto per implementare livelli simili a Photoshop in HTML5 Canvas. Attualmente ho due idee. Il primo e forse l'idea più semplice è quella di avere un elemento Canvas per ogni strato come:Implementazione di livelli in HTML5 Canvas

<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas> 
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas> 
<canvas id="layerName" width="320" height="240" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas> 

In questo modo quando si disegna a un livello - va in realtà a quel "layer". I livelli con posizioni trasparenti possono essere visti attraverso gli strati sottostanti (tele). L'impilamento dei livelli è controllato con la proprietà z-index.

La seconda idea è quella di utilizzare un unico elemento tela e implementare alcuni logica per gestire strati come in questo caso:

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Test</title> 
     <script> 
      window.addEventListener('load', function() { 
       var canvas = document.getElementById("canvas"); 
       var ctx = canvas.getContext("2d"); 

       var order = 0; 

       function drawLayer1() { 
        ctx.fillStyle = "rgb(200,0,0)"; 
        ctx.fillRect (10, 10, 55, 50); 
       } 

       function drawLayer2() { 
        ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; 
        ctx.fillRect (30, 30, 55, 50); 
       } 

       function draw() { 
        ctx.clearRect(0, 0, 256, 256); 

        if (order === 0) { 
         drawLayer1(); 
         drawLayer2(); 
        } 
        else { 
         drawLayer2(); 
         drawLayer1(); 
        } 
       } 

       setInterval(draw, 250); 
       setInterval(function() { 
        order = 1 - order; 
       }, 200); 
      }, false); 
     </script> 
    </head> 
    <body> 
     <canvas id="canvas" width="256px" height="256px"></canvas> 
    </body> 
</html> 

Nel codice sopra i due strati si cambia l'ordine di sovrapposizione ogni 200msec.

Quindi, la domanda è: quale sarebbe il modo migliore? Quali sono i pro e i contro di entrambi gli approcci?

risposta

26

Se si desidera utilizzare un unico elemento tela e avere più livelli al suo interno, si potrebbe desiderare di guardare alla mia biblioteca:

Utilizza un sistema rect danneggiato per ridurre la quantità di riverniciatura eseguita ogni volta che la tela cambia, quindi non solo ottieni dei livelli (che possono essere nidificati), ma ottieni anche ridisegni ottimizzati.

Ecco un semplice demo:

+1

Che sembra fantastico! Grazie per aver condiviso il tuo lavoro. :) –

+1

Il collegamento è interrotto ... – Tek

+2

@Tek: Grazie! Link fisso. – Ant

20

L'utilizzo di più tele dovrebbe essere più veloce, perché la tela viene disegnata fuori dallo schermo e quindi semplicemente filtrata sullo schermo dal browser. Hai il peso di cambiare i livelli nel browser, che deve solo spostare alcuni rettangoli di dati grafici in giro.

Se si esegue il layering da soli, si ha un maggiore controllo, ma l'onere è sul motore JS e JS per fare tutto il lavoro. Eviterei questo se avessi una scelta, ma se stai cercando effetti di livello che funzionano sui livelli sottostanti, questa potrebbe essere la tua unica scelta.

+0

Che cosa si intende per 'ma se si sta andando per gli effetti di livello che i lavori sul layers' sottostante? – Tower

+0

significa cose come layerModes in Photoshop: SCHERMO, DIFFERENZA, CHIARO, SCURO ecc ... – Zevan

+0

Sì, cosa dice @Zevan. – moeffju

2

Impostazione del div contenitore relativo avrebbe dovuto impedito tale questione strato-sovrascrittura. Prova a impostare la posizione sul "testo occluso", ad es. se è attualmente assoluto, sarà ovvio andare nella stessa regione in alto a sinistra della roba relativa.

Ed è probabilmente ovvio ma, dall'ordine dei div in html è possibile eliminare l'uso dell'asse z. Se vuoi che le tue cose siano generiche (e anche per altri sviluppatori), usa l'asse z ma archivia una linea di base a cui aggiungi gli indici di livello (in modo che la linea di base possa essere ottimizzata quando usi un altro codice usando l'asse z in modo problematico).