Ist es ohne Erweiterungsbibliothek möglich, mehrere Ebenen im selben Canvas-Element zu haben?
Wenn ich also ein clearRect auf der obersten Ebene mache, wird die unterste nicht gelöscht?
Vielen Dank.
Ist es ohne Erweiterungsbibliothek möglich, mehrere Ebenen im selben Canvas-Element zu haben?
Wenn ich also ein clearRect auf der obersten Ebene mache, wird die unterste nicht gelöscht?
Vielen Dank.
Antworten:
Nein, Sie können jedoch mehrere <canvas>
Elemente übereinander legen und etwas Ähnliches erreichen.
<div style="position: relative;">
<canvas id="layer1" width="100" height="100"
style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
<canvas id="layer2" width="100" height="100"
style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>
Zeichnen Sie Ihre erste Ebene auf die layer1
Leinwand und die zweite Ebene auf die layer2
Leinwand. Wenn Sie sich dann clearRect
auf der obersten Ebene befinden, wird alles auf der unteren Leinwand durchscheinen.
display: none;
. Oder löschen Sie einfach die Leinwand, wenn es nicht sehr teuer ist, sie erneut zu zeichnen, wenn die Ebene angezeigt werden soll.
Im Zusammenhang damit:
Wenn Sie etwas auf Ihrer Leinwand haben und etwas dahinter zeichnen möchten, können Sie dies tun, indem Sie die Einstellung context.globalCompositeOperation auf "Ziel-Over" ändern - und es dann auf "Quelle-Over" zurücksetzen, wenn Sie fertig.
var context = document.getElementById('cvs').getContext('2d');
// Draw a red square
context.fillStyle = 'red';
context.fillRect(50,50,100,100);
// Change the globalCompositeOperation to destination-over so that anything
// that is drawn on to the canvas from this point on is drawn at the back
// of what's already on the canvas
context.globalCompositeOperation = 'destination-over';
// Draw a big yellow rectangle
context.fillStyle = 'yellow';
context.fillRect(0,0,600,250);
// Now return the globalCompositeOperation to source-over and draw a
// blue rectangle
context.globalCompositeOperation = 'source-over';
// Draw a blue rectangle
context.fillStyle = 'blue';
context.fillRect(75,75,100,100);
<canvas id="cvs" />
Sie können mehrere canvas
Elemente erstellen , ohne sie an ein Dokument anzuhängen. Dies werden Ihre Schichten sein :
Machen Sie dann mit ihnen, was Sie wollen, und rendern Sie am Ende ihren Inhalt in der richtigen Reihenfolge auf der Zielleinwand mit drawImage
on context
.
Beispiel:
/* using canvas from DOM */
var domCanvas = document.getElementById('some-canvas');
var domContext = domCanvas.getContext('2d');
domContext.fillRect(50,50,150,50);
/* virtual canvase 1 - not appended to the DOM */
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(50,50,150,150);
/* virtual canvase 2 - not appended to the DOM */
var canvas2 = document.createElement('canvas')
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'yellow';
ctx2.fillRect(50,50,100,50)
/* render virtual canvases on DOM canvas */
domContext.drawImage(canvas, 0, 0, 200, 200);
domContext.drawImage(canvas2, 0, 0, 200, 200);
Und hier ist ein Codepen: https://codepen.io/anon/pen/mQWMMW
Ich hatte auch das gleiche Problem, ich habe zwar mehrere Canvas-Elemente mit Position: Absolut erledigt den Job, wenn Sie die Ausgabe in einem Bild speichern möchten, wird das nicht funktionieren.
Also habe ich ein einfaches "System" für Ebenen erstellt, um zu codieren, als ob jede Ebene ihren eigenen Code hätte, aber alles wird in dasselbe Element gerendert.
https://github.com/federicojacobi/layeredCanvas
Ich beabsichtige, zusätzliche Funktionen hinzuzufügen, aber im Moment wird es reichen.
Sie können mehrere Funktionen ausführen und sie aufrufen, um Ebenen zu "fälschen".
Sie können auch http://www.concretejs.com überprüfen, ein modernes, leichtes HTML5-Canvas-Framework, das Treffererkennung, Layering und viele andere periphere Funktionen ermöglicht. Sie können solche Dinge tun:
var wrapper = new Concrete.Wrapper({
width: 500,
height: 300,
container: el
});
var layer1 = new Concrete.Layer();
var layer2 = new Concrete.Layer();
wrapper.add(layer1).add(layer2);
// draw stuff
layer1.sceneCanvas.context.fillStyle = 'red';
layer1.sceneCanvas.context.fillRect(0, 0, 100, 100);
// reorder layers
layer1.moveUp();
// destroy a layer
layer1.destroy();
Ich verstehe, dass der Q keine Bibliothek verwenden möchte, aber ich werde dies für andere anbieten, die aus der Google-Suche stammen. @EricRowell erwähnte ein gutes Plugin, aber es gibt auch ein anderes Plugin, das Sie ausprobieren können, html2canvas .
In unserem Fall verwenden wir geschichtete transparente PNGs mit z-index
als "Product Builder" -Widget. Html2canvas hat hervorragend funktioniert, um den Stapel zu reduzieren, ohne Bilder zu verschieben oder Komplexitäten, Problemumgehungen und die "nicht reagierende" Leinwand selbst zu verwenden. Wir konnten dies mit der Vanille-Leinwand + JS nicht reibungslos / vernünftig machen.
Verwenden Sie diese z-index
Option zuerst für absolute Divs, um Ebeneninhalte in einem relativ positionierten Wrapper zu generieren. Führen Sie dann den Wrapper durch html2canvas, um eine gerenderte Zeichenfläche zu erhalten, die Sie unverändert lassen oder als Bild ausgeben können, damit ein Client sie speichern kann.
Aber Ebene 02 deckt alle Zeichnungen in Ebene 01 ab. Ich habe dies verwendet, um die Zeichnung in beiden Ebenen zu zeigen. Verwenden Sie (Hintergrundfarbe: transparent;) im Stil.
<div style="position: relative;">
<canvas id="lay01" width="500" height="500" style="position: absolute; left: 0; top: 0; z-index: 0; background-color: transparent;">
</canvas>
<canvas id="lay02" width="500" height="500" style="position: absolute; left: 0; top: 0; z-index: 1; background-color: transparent;">
</canvas>
</div>