Sans aucune bibliothèque d'extension, est-il possible d'avoir plusieurs calques dans le même élément de canevas?
Donc, si je fais un clearRect sur le calque supérieur, il n'effacera pas celui du bas?
Merci.
Sans aucune bibliothèque d'extension, est-il possible d'avoir plusieurs calques dans le même élément de canevas?
Donc, si je fais un clearRect sur le calque supérieur, il n'effacera pas celui du bas?
Merci.
Réponses:
Non, cependant, vous pouvez <canvas>
superposer plusieurs éléments les uns sur les autres et accomplir quelque chose de similaire.
<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>
Dessinez votre premier calque sur la layer1
toile et le deuxième calque sur la layer2
toile. Ensuite, lorsque vous êtes clearRect
sur la couche supérieure, tout ce qui se trouve sur la toile inférieure apparaîtra.
display: none;
. Ou effacez simplement le canevas, s'il n'est pas très coûteux de le redessiner lorsque le calque doit être affiché.
Liés à ceci:
Si vous avez quelque chose sur votre canevas et que vous voulez dessiner quelque chose à l'arrière de celui-ci - vous pouvez le faire en modifiant le paramètre context.globalCompositeOperation sur 'destination-over' - puis le remettre à 'source-over' lorsque vous ' c'est fait.
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" />
Vous pouvez créer plusieurs canvas
éléments sans les ajouter au document. Ce seront vos couches :
Ensuite, faites ce que vous voulez avec eux et à la fin, rendez simplement leur contenu dans le bon ordre sur le canevas de destination en utilisant drawImage
sur context
.
Exemple:
/* 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);
Et voici quelques codepen: https://codepen.io/anon/pen/mQWMMW
J'avais le même problème aussi, je me suis mis à plusieurs éléments de canevas avec position: absolu fait le travail, si vous voulez enregistrer la sortie dans une image, cela ne fonctionnera pas.
Je suis donc allé de l'avant et j'ai fait un simple "système" de couches pour coder comme si chaque couche avait son propre code, mais tout est rendu dans le même élément.
https://github.com/federicojacobi/layeredCanvas
J'ai l'intention d'ajouter des capacités supplémentaires, mais pour l'instant, cela fera l'affaire.
Vous pouvez faire plusieurs fonctions et les appeler afin de "faux" calques.
Vous pouvez également consulter http://www.concretejs.com qui est un framework de canevas Html5 moderne et léger qui permet la détection des coups, la superposition et beaucoup d'autres choses périphériques. Vous pouvez faire des choses comme ceci:
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();
Je comprends que le Q ne souhaite pas utiliser de bibliothèque, mais je proposerai ceci à d'autres personnes issues de recherches Google. @EricRowell a mentionné un bon plugin, mais il y a aussi un autre plugin que vous pouvez essayer, html2canvas .
Dans notre cas, nous utilisons des PNG transparents en couches avec z-index
un widget de "création de produit". Html2canvas a travaillé avec brio pour faire bouillir la pile sans pousser les images, ni utiliser les complexités, les solutions de contournement et le canevas «non réactif» lui-même. Nous n'avons pas pu faire cela de manière fluide / saine avec la toile vanille + JS.
Première utilisation z-index
sur des div absolus pour générer du contenu en couches dans un wrapper positionné relatif. Ensuite, dirigez le wrapper à travers html2canvas pour obtenir un canevas rendu, que vous pouvez laisser tel quel, ou afficher sous forme d'image afin qu'un client puisse l'enregistrer.
mais la couche 02 couvrira tous les dessins de la couche 01. Je l'ai utilisé pour montrer le dessin dans les deux couches. utilisez (background-color: transparent;) avec style.
<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>