Czy bez żadnej biblioteki rozszerzeń można mieć wiele warstw w tym samym elemencie Canvas?
Więc jeśli zrobię clearRect na górnej warstwie, to nie usunie dolnej?
Dzięki.
Czy bez żadnej biblioteki rozszerzeń można mieć wiele warstw w tym samym elemencie Canvas?
Więc jeśli zrobię clearRect na górnej warstwie, to nie usunie dolnej?
Dzięki.
Odpowiedzi:
Nie, jednak możesz nałożyć wiele <canvas>
elementów jeden na drugi i osiągnąć coś podobnego.
<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>
Narysuj pierwszą warstwę na layer1
płótnie, a drugą na layer2
płótnie. Następnie, gdy jesteś clearRect
na górnej warstwie, prześwituje wszystko, co znajduje się na niższym płótnie.
display: none;
. Lub po prostu wyczyść płótno, jeśli ponowne narysowanie go ponownie, gdy warstwa powinna zostać wyświetlona, nie jest zbyt kosztowne.
Powiązane z tym:
Jeśli masz coś na płótnie i chcesz narysować coś z tyłu - możesz to zrobić, zmieniając ustawienie context.globalCompositeOperation na „destination-over” - a następnie przywróć je do „source-over”, kiedy to zrobisz gotowe.
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" />
Możesz tworzyć wiele canvas
elementów bez dołączania ich do dokumentu. To będą twoje warstwy :
Następnie rób z nimi, co chcesz, a na koniec po prostu renderuj ich zawartość w odpowiedniej kolejności na docelowym płótnie, używając drawImage
on context
.
Przykład:
/* 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);
A oto kilka kodów: https://codepen.io/anon/pen/mQWMMW
Miałem też ten sam problem, podczas gdy wiele elementów płótna z pozycją: absolutne spełnia swoje zadanie, jeśli chcesz zapisać wynik do obrazu, to nie zadziała.
Więc poszedłem do przodu i zrobiłem prosty "system" warstwowania, aby zakodować tak, jakby każda warstwa miała swój własny kod, ale wszystko jest renderowane w tym samym elemencie.
https://github.com/federicojacobi/layeredCanvas
Zamierzam dodać dodatkowe możliwości, ale na razie wystarczy.
Możesz wykonywać wiele funkcji i wywoływać je w celu „sfałszowania” warstw.
Możesz również sprawdzić http://www.concretejs.com, który jest nowoczesnym, lekkim frameworkiem HTML5, który umożliwia wykrywanie trafień, nakładanie warstw i wiele innych peryferyjnych rzeczy. Możesz robić takie rzeczy:
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();
Rozumiem, że Q nie chce korzystać z biblioteki, ale zaoferuję to innym osobom pochodzącym z wyszukiwań Google. @EricRowell wspomniał o dobrej wtyczce, ale jest też inna wtyczka, którą możesz wypróbować, html2canvas .
W naszym przypadku używamy warstwowych przezroczystych plików PNG z z-index
widżetem „konstruktora produktu”. Html2canvas działał znakomicie, aby ugotować stos bez przesuwania obrazów ani stosowania zawiłości, obejść i samego „niereagującego” płótna. Nie byliśmy w stanie zrobić tego płynnie / rozsądnie z płótnem waniliowym + JS.
Pierwsze użycie z-index
na absolutnych elementach DIV w celu wygenerowania zawartości warstwowej we względnie pozycjonowanym opakowaniu. Następnie przepuść opakowanie przez html2canvas, aby uzyskać renderowane płótno, które możesz pozostawić bez zmian, lub wyprowadzić jako obraz, aby klient mógł go zapisać.
ale warstwa 02 pokryje wszystkie rysunki w warstwie 01. Użyłem tego do pokazania rysunków w obu warstwach. użyj stylu (background-color: transparent;).
<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>