web-dev-qa-db-fra.com

Implémentation de calques dans un canevas HTML5

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 la plus simple idée est d’avoir un élément Canvas pour chaque calque comme:

<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 tracez un calque, il s’applique à ce "calque". Les calques avec des positions transparentes peuvent être vus jusque sous les calques (canevas). L'empilement de couches est contrôlé avec la propriété z-index.

La deuxième idée consiste à utiliser un seul élément Canvas et à implémenter une logique pour gérer les calques 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 toutes les 200 ms.

Alors, la question est de savoir quelle voie serait la meilleure? Quels sont les avantages et les inconvénients des deux approches?

23
Tower

Si vous souhaitez utiliser un seul élément de la toile et y avoir plusieurs calques, vous pouvez consulter ma bibliothèque:

Il utilise un système rect endommagé pour réduire le nombre de repeints effectué chaque fois que le canevas est modifié. Vous obtenez ainsi non seulement des calques (qui peuvent être imbriqués), mais également des retraits optimisés.

Voici une démo simple:

26
Ant

L'utilisation de plusieurs canevas devrait être plus rapide, car le canevas est dessiné hors de l'écran, puis simplement affiché à l'écran par le navigateur. Vous chargez le navigateur de changer de couche, ce qui vous oblige à déplacer des rectangles de données graphiques.

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

21
moeffju

La définition du div div du conteneur aurait dû éviter ce problème d’écrasement de la couche. Essayez de définir la position sur le "texte masqué" - par exemple. si elle est actuellement absolue, cela ira évidemment dans la même région que le coin supérieur gauche du texte relatif.

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 voulez que votre contenu soit générique (et pour les autres développeurs également), utilisez l'axe z, mais stockez une ligne de base à laquelle vous ajoutez vos index de couche (afin que la ligne de base puisse être modifiée lorsque vous utilisez un autre code utilisant l'axe z de manière problématique ).

2
firemonkey
1
周汉成