elemento html5-canvas-camadas múltiplas

sem qualquer biblioteca de extensão, é possível ter várias camadas no mesmo elemento de tela?

Então, se eu fizer um clearRect na camada superior, não apagará a inferior?

Obrigado.

Author: Gregoire, 2010-06-09

7 answers

Não, no entanto, você poderia colocar vários elementos <canvas> em cima um do outro e realizar algo semelhante.

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

Desenhe a sua primeira camada sobre a tela layer1, e a segunda camada sobre a tela layer2. Então quando você clearRect na camada superior, o que quer que esteja na tela inferior irá aparecer através.

 280
Author: jimr, 2010-06-09 19:08:29

Relacionado com isto:

Se você tem algo em sua tela e quer desenhar algo na parte de trás - você pode fazê-lo mudando o contexto.operação globalcompositeoprogramação para ' destino-over '-e, em seguida, retorná-lo para' fonte-over ' quando você terminar.

   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" />
 45
Author: Richard, 2019-11-09 20:05:33

Você pode criar vários canvas elementos sem adicioná-los ao documento. Estas serão as tuas camadas :

Então faça o que quiser com eles e no final apenas torne o seu conteúdo em ordem adequada na tela de destino usando drawImage em context.

Exemplo:

/* 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);
E aqui está o codepen: https://codepen.io/anon/pen/mQWMMW
 34
Author: juszczak, 2018-11-14 10:34:38

Eu também estava tendo esse mesmo problema, eu enquanto vários elementos de tela com posição: absoluto faz o trabalho, se você quiser salvar a saída em uma imagem, isso não vai funcionar.

Então eu fui em frente e fiz um simples "sistema" de camadas para codificar como se cada camada tivesse seu próprio código, mas tudo se transforma no mesmo elemento.

Https://github.com/federicojacobi/layeredCanvas

Eu pretendo adicionar capacidades extras, mas por agora vai servir.

Tu pode fazer várias funções e chamá-los a fim de "falsificar" camadas.

 8
Author: Federico Jacobi, 2015-12-22 02:08:30

Também pode sair http://www.concretejs.com que é uma estrutura de tela moderna, leve, Html5 que permite a detecção de hit, camadas, e muitas outras coisas periféricas. Você pode fazer coisas assim:

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();
 5
Author: Eric Rowell, 2016-04-01 22:52:14

Mas a camada 02 cobrirá todos os desenhos na camada 01. Usei isto para mostrar desenho em ambas as camadas. usar (cor de fundo: transparente;) em estilo.

    <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>
 1
Author: aymhenry, 2019-12-29 20:02:44

Eu entendo que o Q não quer usar uma biblioteca, mas eu vou oferecer isso para outros que vêm de pesquisas do Google. @EricRowell mencionou um bom plugin, mas, há também outro plugin que você pode tentar, html2canvas .

No nosso caso, estamos a usar PNG transparente em camadas com {[[0]} como um elemento" construtor de produtos". Html2canvas trabalhou brilhantemente para ferver a pilha sem empurrar imagens, nem usando complexidades, workarounds, e a tela "não-responsiva" em si. O não foram capazes de fazer isso sem problemas / sane com o vanilla canvas+JS.

Primeiro usar {[[0]} em divisórias absolutas para gerar conteúdo em camadas dentro de um invólucro posicionado relativo. Em seguida, pipe a embalagem através do html2canvas para obter uma tela renderizada, que você pode deixar como-is, ou saída como uma imagem para que um cliente pode salvá-la.

 0
Author: dhaupin, 2016-06-20 20:52:26