wake-up-neo.com

Ebenen in HTML5-Canvas implementieren

Ich bin dabei, Photoshop-ähnliche Ebenen in HTML5 Canvas zu implementieren. Momentan habe ich zwei Ideen. Die erste und vielleicht einfachere Idee besteht darin, für jede Ebene ein Canvas-Element zu haben, z.

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

Auf diese Weise wird beim Zeichnen auf eine Ebene tatsächlich diese "Ebene" verwendet. Ebenen mit transparenten Positionen können bis unter die Ebenen (Canvases) gesehen werden. Das Layer-Stacking wird mit der z-index-Eigenschaft gesteuert.

Die zweite Idee ist, ein einzelnes Canvas-Element zu verwenden und eine Logik zu implementieren, um Ebenen wie in diesem Fall zu behandeln:

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

Im obigen Code ändern die beiden Schichten die Stapelreihenfolge alle 200 ms.

Die Frage ist also, welcher Weg der beste Weg ist. Was sind die Vor- und Nachteile beider Ansätze?

23
Tower

Wenn Sie ein einzelnes Canvas-Element verwenden möchten und mehrere Ebenen enthalten, möchten Sie möglicherweise meine Bibliothek betrachten:

Es verwendet ein beschädigtes Rect-System, um die Anzahl der Neulackierungen zu verringern, die bei jeder Änderung der Leinwand vorgenommen werden. So erhalten Sie nicht nur Ebenen (die verschachtelt werden können), sondern auch optimierte Neuzeichnungen.

Hier ist eine einfache Demo:

26
Ant

Die Verwendung mehrerer Leinwände sollte schneller sein, da die Leinwand außerhalb des Bildschirms gezeichnet und dann vom Browser nur auf dem Bildschirm angezeigt wird. Sie müssen den Layer wechseln, indem Sie die Rechtecke der Grafikdaten verschieben.

Wenn Sie das Layering selbst durchführen, haben Sie mehr Kontrolle, aber die Arbeit des JS und der JS-Engine liegt bei Ihnen. Ich würde dies vermeiden, wenn ich die Wahl hätte, aber wenn Sie sich für Layer-Effekte entscheiden, die auf den darunter liegenden Layern funktionieren, ist dies möglicherweise Ihre einzige Wahl.

21
moeffju

Durch das Setzen des relativen Containers div sollte dieses Problem beim Überschreiben der Ebene verhindert werden. Stellen Sie die Position auf dem "verdeckten Text" ein - z. Wenn es momentan absolut ist, wird es offensichtlich in die gleiche Region gehen wie die oberen linken Bereiche des jeweiligen Materials.

Und es ist wahrscheinlich offensichtlich, aber durch die Reihenfolge der divs in der HTML-Datei können Sie die Verwendung der z-Achse beseitigen. Wenn Sie möchten, dass Ihr Material generisch ist (und für andere Entwickler auch), verwenden Sie die Z-Achse, speichern Sie jedoch eine Basislinie, zu der Sie Ihre Layer-Indizes hinzufügen (sodass die Basislinie bei der Verwendung von anderem Code mit der Z-Achse auf problematische Weise angepasst werden kann ).

2
firemonkey

Verwenden Sie jCanvas , siehe dessen Layer-API: http://projects.calebevans.me/jcanvas/docs/layerAPI/

1
周汉成