html5 - элемент canvas - несколько слоев - PullRequest
161 голосов
/ 09 июня 2010

Без какой-либо библиотеки расширений возможно ли иметь несколько слоев в одном элементе canvas?

Итак, если я сделаю clearRect на верхнем слое, он не сотрет нижний?

Спасибо.

Ответы [ 6 ]

242 голосов
/ 09 июня 2010

Нет, однако, вы можете наложить несколько <canvas> элементов друг на друга и сделать что-то похожее.

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

Нарисуйте свой первый слой на холсте layer1, а второй слой на холсте layer2. Затем, когда вы clearRect на верхнем слое, все, что находится на нижнем холсте, будет просвечивать.

31 голосов
/ 05 мая 2013

С этим связано:

Если у вас есть что-то на холсте, и вы хотите нарисовать что-то позади него - вы можете сделать это, изменив параметр context.globalCompositeOperation на «destination-over» - и затем вернуть его в «source-over» когда вы закончите.

var co = document.getElementById('cvs').getContext('2d');

// Draw a red square

co.fillStyle = 'red';
co.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 whats already on the canvas

co.globalCompositeOperation = 'destination-over';



// Draw a big yellow rectangle

co.fillStyle = 'yellow';
co.fillRect(0,0,600,250);


// Now return the globalCompositeOperation to source-over and draw a
// blue rectangle

co.globalCompositeOperation = 'source-over';

co.fillStyle = 'blue';
co.fillRect(75,75,100,100);
19 голосов
/ 02 марта 2015

Вы можете создать несколько элементов canvas, не добавляя их в документ. Это будут ваши слои :

Затем делайте с ними все, что хотите, и в конце просто визуализируйте их содержимое в правильном порядке на холсте назначения, используя drawImage на context.

Пример:

/* 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);

А вот кодекс: https://codepen.io/anon/pen/mQWMMW

4 голосов
/ 22 декабря 2015

У меня тоже была такая же проблема, я в то время как несколько элементов canvas с position: absolute делает работу, если вы хотите сохранить вывод в изображение, это не сработает.вперед и сделал простую многоуровневую «систему» ​​для кодирования, как если бы каждый слой имел свой собственный код, но все это визуализируется в один и тот же элемент.возможности, но на данный момент это будет делать.

Вы можете сделать несколько функций и вызывать их, чтобы «подделать» слои.

3 голосов
/ 02 апреля 2016

Вы также можете оформить заказ http://www.concretejs.com, который представляет собой современный, легкий, Html5-фреймворк, который позволяет обнаруживать попадания, слои и многое другоеВы можете делать такие вещи:

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();
0 голосов
/ 20 июня 2016

Я понимаю, что Q не хочет использовать библиотеку, но я предложу это для других, приходящих из поисков Google. @EricRowell упомянул хороший плагин, но есть и другой плагин, который вы можете попробовать, html2canvas .

В нашем случае мы используем многоуровневые прозрачные PNG с z-index в качестве виджета «Построитель продукта». Html2canvas блестяще работал, чтобы свести стопку к минимуму, не нажимая на изображения, не используя сложностей, обходных путей и самого «неотвечающего» холста. Мы не смогли сделать это гладко / вменяемым с ванильным холстом + JS.

Сначала используйте z-index для абсолютных элементов div, чтобы создать многоуровневый контент в относительно расположенной оболочке. Затем направьте оболочку через html2canvas, чтобы получить обработанный холст, который вы можете оставить как есть, или вывести как изображение, чтобы клиент мог его сохранить.

...