2010-12-12 5 views
23

Ich bin dabei Photoshop-ähnliche Ebenen in HTML5 Canvas zu implementieren. Momentan habe ich zwei Ideen. Die erste und vielleicht die einfachere Idee ist, für jede Schicht ein Canvas-Element zu haben, wie:Implementieren von Ebenen 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> 

diese Weise, wenn Sie auf eine Ebene ziehen - es geht tatsächlich auf diese „Schicht“. Schichten mit transparenten Positionen können bis unter die Schichten (Canvases) durchgeschaut werden. Das Schichtenstapeln wird mit der Eigenschaft z-index gesteuert.

Die zweite Idee ist, ein einzelnes Canvas-Element zu verwenden und einige Logik implementieren Schichten 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> 

In dem obigen Code die beiden Schichten ändern, um alle 200 ms zu stapeln.

Also, die Frage ist, welcher Weg wäre der beste Weg? Was sind die Vor- und Nachteile beider Ansätze?

Antwort

26

Wenn Sie ein einzelnes Canvas-Element verwenden möchten, und haben mehrere Schichten im Inneren, könnte man an meiner Bibliothek aussehen wollen:

Es verwendet ein beschädigtes rect System zu reduzieren Die Anzahl der Übermalungen erfolgt bei jeder Änderung der Zeichenfläche. Sie erhalten nicht nur Ebenen (die verschachtelt werden können), sondern Sie erhalten auch optimierte Neuzeichnungen.

Hier ist eine einfache Demo:

+1

Das sieht toll aus! Danke, dass du deine Arbeit geteilt hast. :) –

+1

Link ist kaputt ... – Tek

+2

@Tek: Danke! Link repariert – Ant

20

Die Verwendung mehrerer Leinwände sollte schneller sein, da die Leinwand vom Bildschirm abgezogen und dann vom Browser einfach auf den Bildschirm geblendet wird. Sie haben die Aufgabe, Layer auf den Browser zu verschieben, der nur einige Rechtecke von Grafikdaten verschieben muss.

Wenn Sie die Layering selbst vornehmen, haben Sie mehr Kontrolle, aber die Last ist auf die JS und die JS-Engine, um die ganze Arbeit zu erledigen. Ich würde dies vermeiden, wenn ich die Wahl hätte, aber wenn Sie Ebeneneffekte verwenden, die auf den darunter liegenden Ebenen arbeiten, ist dies möglicherweise Ihre einzige Wahl.

+0

Was meinst du mit ', aber wenn Sie für Ebeneneffekte, dass die Arbeit auf dem darunterliegenden layers' gehen? – Tower

+0

er meint Dinge wie layerModes in photoshop: BILDSCHIRM, UNTERSCHIED, LICHT, DUNKEL usw. – Zevan

+0

Ja, was @Zevan sagt. – moeffju

2

den Container div relativen Einstellung sollte diese Schicht-Überschreibungs Problem verhindert haben. Versuchen Sie, die Position auf dem "okkludierten Text" festzulegen - z. Wenn es momentan absolut ist, wird es offensichtlich in der gleichen Region wie die obere linke der relativen Sachen gehen.

Und es ist wahrscheinlich offensichtlich, aber durch die Reihenfolge der divs im HTML können Sie die Verwendung der Z-Achse beseitigen. Wenn Sie möchten, dass Ihre Daten generisch sind (und auch für andere Entwickler), verwenden Sie die z-Achse, aber speichern Sie eine Baseline, zu der Sie Ihre Layer-Indizes hinzufügen (damit die Baseline optimiert werden kann, wenn Sie anderen Code mit der z-Achse verwenden)).

Verwandte Themen