2010-12-12 31 views
23

Je suis sur le point d'implémenter des calques de type Photoshop dans HTML5 Canvas. Actuellement, j'ai deux idées. La première et peut-être l'idée plus simple est d'avoir un élément de toile pour chaque couche comme:Implémentation de calques dans 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> 

De cette façon, lorsque vous dessinez à une couche - il va en fait à cette « couche ». Les couches avec des positions transparentes peuvent être vues à travers des couches inférieures (Toiles). L'empilement des calques est contrôlé avec la propriété z-index.

La deuxième idée est d'utiliser un seul élément de toile et mettre en œuvre une certaine logique pour traiter des couches comme dans ce cas:

<!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> 

Dans le code ci-dessus les deux couches changeront l'ordre d'empilement tous les 200 ms. Donc, la question est de savoir quelle serait la meilleure façon de faire? Quels sont les avantages et les inconvénients des deux approches?

Répondre

26

Si vous souhaitez utiliser un élément de toile unique et ont plusieurs couches à l'intérieur, vous voudrez peut-être regarder ma bibliothèque:

Il utilise un système de rect endommagé pour réduire la quantité de repeindre à chaque fois que le canevas change, donc non seulement vous obtenez des calques (qui peuvent être imbriqués), mais vous obtenez également des redessins optimisés.

Voici une démonstration simple:

+1

Cela semble génial! Merci de partager votre travail. :) –

+1

Lien est cassé ... – Tek

+2

@Tek: Merci! Lien fixe. – Ant

20

L'utilisation de plusieurs canevas devrait être plus rapide, parce que le canevas est dessiné hors écran et ensuite simplement blitted à l'écran par le navigateur. Vous mettez le fardeau de la commutation des couches sur le navigateur, qui doit juste déplacer des rectangles de données graphiques autour.

Si vous faites la superposition vous-même, vous avez plus de contrôle, mais il incombe au JS et au moteur JS de faire tout le travail. J'éviterais ceci si j'avais le choix, mais si vous optez pour des effets de calques qui fonctionnent sur les calques sous-jacents, cela pourrait être votre seul choix.

+0

Que voulez-vous dire par 'mais si vous allez pour les effets de la couche que les travaux sur la layers' sous-jacente? – Tower

+0

il veut dire des choses comme des calques dans Photoshop: ÉCRAN, DIFFÉRENCE, LUMIÈRE, DARKEN etc ... – Zevan

+0

Oui, ce que @Zevan dit. – moeffju

2

Réglage du conteneur div par rapport aurait dû éviter ce problème de couche Ecraser. Essayez de définir la position sur le "texte masqué" - par ex. Si elle est actuellement absolue, elle ira évidemment dans la même région que la partie supérieure gauche de l'étoffe relative.

Et c'est probablement évident mais, par l'ordre des divs dans le html, vous pouvez éliminer l'utilisation de l'axe z. Si vous souhaitez que votre contenu soit générique (et pour les autres développeurs), utilisez l'axe z mais stockez une ligne de base à laquelle vous ajoutez vos indices de calque (afin que la ligne de base puisse être modifiée).).