html5 - canvas元素-多层

如果没有任何扩展库,是否有可能在同一个画布元素中有多个层?

所以如果我在顶层做一个clearRect,它不会擦除底层吗?

谢谢。

236600 次浏览

不,然而,你可以将多个<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时,下层画布上的任何内容都会显示出来。

与此相关的:

如果你在画布上有一些东西,你想在它的后面画一些东西,你可以通过改变上下文来做到这一点。globalCompositeOperation设置为'destination-over' -然后当你完成时返回它为'source-over'。

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

你可以创建多个canvas元素,而不将它们附加到文档中。这些将是你的:

然后对它们做任何你想做的事情,最后在目标画布上使用drawImagecontext上以适当的顺序渲染它们的内容。

例子:

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

我也遇到了同样的问题,我同时使用多个canvas元素position:absolute来完成工作,如果你想将输出保存到图像中,这是行不通的。

所以我继续做了一个简单的分层“系统”来编码,就好像每一层都有自己的代码一样,但它都被呈现到相同的元素中。

https://github.com/federicojacobi/layeredCanvas

我打算添加额外的功能,但现在它就可以了。

你可以做多个函数并调用它们来“伪造”图层。

你也可以签出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();

我知道Q不想使用库,但我会为其他人提供这来自谷歌搜索。@EricRowell提到了一个很好的插件,但是,还有另一个插件你可以尝试,html2canvas

在我们的例子中,我们使用了带有z-index的分层透明PNG作为“产品构建器”小部件。Html2canvas出色地将堆栈压缩,无需推送图像,也不使用复杂性、变通方法和“无响应”画布本身。我们不能用香草画布+JS顺利/理智地做到这一点。

首先在绝对div上使用z-index来在相对定位包装器中生成分层内容。然后将包装器通过html2canvas管道以获得渲染的画布,您可以保持原样,也可以将其输出为图像以便客户端保存。

但是图层02,将覆盖图层01中的所有图纸。我用它在两个图层中显示绘图。在样式中使用(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>