html5 - 画布元素 - 多层

问题描述 投票:0回答:9

在没有任何扩展库的情况下,是否可以在同一个canvas元素中拥有多个图层?

所以如果我在顶层执行clearRect,它不会擦除底层?

谢谢。

html canvas layer
9个回答
304
投票

不,但是,您可以将多个

<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
时,下层画布上的任何内容都会显示出来。


62
投票

相关:

如果你的画布上有一些东西,并且你想在它的后面绘制一些东西 - 你可以通过将 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" />


45
投票

您可以创建多个

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


11
投票

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

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

https://github.com/federicojacobi/layeredCanvas

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

您可以执行多个函数并调用它们以“伪造”图层。


3
投票

您还可以查看 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();

3
投票

但是图层02,将覆盖图层01中的所有绘图。我用它来显示两个图层中的绘图。在风格中使用 (背景颜色: 透明;)。

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


0
投票

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

在我们的例子中,我们使用分层透明 PNG 和

z-index
作为“产品构建器”小部件。 Html2canvas 出色地简化了堆栈,无需推送图像,也无需使用复杂性、解决方法和“非响应式”画布本身。我们无法使用 vanilla canvas+JS 顺利/理智地完成此操作。

首先在绝对 div 上使用

z-index
在相对定位的包装器中生成分层内容。然后通过 html2canvas 对包装器进行管道传输以获取渲染的画布,您可以将其保留为原样,或者输出为图像以便客户端可以保存它。


0
投票

是的,这是可能的。

由于 Canvas 元素具有像 Paint 中一样的集成结构,因此您需要做的第一件事是将所有绘图存储在全局变量中。然后,对于您对此变量所做的每次更改,您都会自动在画布上重新绘制更改。后续步骤包括在屏幕上显示全局变量中的数据,将它们呈现为图层,并且对于使用鼠标在画布上进行左右移动,您将通过利用全局变量的属性来比较全局变量中的高度值。鼠标悬停并单击的画布,并相应地绘制一个区域。


0
投票

基于堆叠多个

<canvas>
元素的想法,我做了一个演示多个画布层

它包含 3 个堆叠层:背景 (bg)、中间 (grid)、前景 (fg)。

要在保存/导出时混合图层,只需创建一个 OffscreenCanvas 并调用 drawImage() 来按顺序绘制相关的

<canvas>
元素。

© www.soinside.com 2019 - 2024. All rights reserved.