在不使用扩展库的情况下,是否可以在同一画布元素中拥有多个图层?
因此,如果我在顶层执行clearRect操作,它将不会擦除底部图层吗?
谢谢。
在不使用扩展库的情况下,是否可以在同一画布元素中拥有多个图层?
因此,如果我在顶层执行clearRect操作,它将不会擦除底部图层吗?
谢谢。
<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
时,下层画布上的任何内容将会显示出来。
display:none;
。或者仅清除画布,如果在应该显示该层时重新绘制它不会太耗费资源。 - jimr与此相关:
如果您在画布上有绘制内容,并想在其后面绘制其他内容,可以通过将context.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
元素,而无需将它们附加到文档中。这些将成为您的层:canvas
上的context
中的drawImage
以适当的顺序呈现其内容。/* 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);
这里有一些 CodePen 代码:https://codepen.io/anon/pen/mQWMMW
clear(ctx2); ctx2.draw(ctx3); clear(ctx); ctx.draw(ctx2)
应该改为 clear(ctx); ctx.draw(ctx3); ctx.draw(ctx2)
,在我的机器上运行时(时间轴正在运行),结果为 test1 x 38,607 ops test2 x 24,853
,如预期(请注意,test2 的结果约为 test1 的一半)。第二个也是最重要的缺陷是测试是连续的,并将 JavaScript 阻塞在大约 50 毫秒左右的块中。在每个 test1 块之后查看时间轴,会发现大约有 1.7 毫秒的画面更新和 0.25 毫秒的合成(GPU 绿色),但在 test2 之后不存在。DOM 也会进行绘制,但速度较慢,而你的基准测试没有记录这一点。 - Blindman67我也遇到了同样的问题,虽然使用多个带有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();
<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>
<canvas>
元素的想法,我制作了一个演示多层画布。<canvas>
元素。我知道Q不想使用库,但是我会为那些通过谷歌搜索而来的人提供这个建议。@EricRowell提到了一个好的插件,但是还有另一个插件可以尝试,html2canvas。
在我们的情况下,我们使用带有z-index
的分层透明PNG作为“产品构建器”小部件。Html2canvas非常出色地将堆栈简化,而不会推动图像,也不会使用复杂性、解决方法和“非响应式”的画布本身。我们无法使用原始的canvas+JS平稳/理智地完成这项工作。
首先,在相对定位的包装器中使用绝对divs上的z-index
生成分层内容。然后将包装器通过html2canvas传输以获取渲染的画布,您可以将其保留不变,或者将其输出为图像,以便客户端保存。