Html html5 - 画布元素 - 多层

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3008635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 03:23:44  来源:igfitidea点击:

html5 - canvas element - Multiple layers

htmlcanvaslayer

提问by Gregtheitroade

Without any extension library, is it possible to have multiple layers in the same canvas element?

没有任何扩展库,是否可以在同一个画布元素中拥有多个图层?

So if I do a clearRect on the top layer, it will not erase the bottom one?

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

Thanks.

谢谢。

回答by jimr

No, however, you could layer multiple <canvas>elements on top of each other and accomplish something similar.

不,但是,您可以将多个<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>

Draw your first layer on the layer1canvas, and the second layer on the layer2canvas. Then when you clearRecton the top layer, whatever's on the lower canvas will show through.

layer1画布上绘制第一层,在画布上绘制第二层layer2。然后,当您clearRect在顶层时,下方画布上的任何内容都会显示出来。

回答by Richard

Related to this:

与此相关:

If you have something on your canvas and you want to draw something at the back of it - you can do it by changing the context.globalCompositeOperation setting to 'destination-over' - and then return it to 'source-over' when you're done.

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

回答by juszczak

You can create multiple canvaselements without appending them into document. These will be your layers:

您可以创建多个canvas元素而无需将它们附加到文档中。这些将是您的图层

Then do whatever you want with them and at the end just render their content in proper order at destination canvas using drawImageon context.

然后对它们做任何你想做的事情,最后只需使用drawImageon在目标画布上以正确的顺序呈现它们的内容context

Example:

例子:

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

And here is some codepen: https://codepen.io/anon/pen/mQWMMW

这是一些代码笔:https://codepen.io/anon/pen/mQWMMW

回答by Federico Jacobi

I was having this same problem too, I while multiple canvas elements with position:absolute does the job, if you want to save the output into an image, that's not going to work.

我也遇到了同样的问题,虽然多个带有 position:absolute 的画布元素可以完成这项工作,但如果您想将输出保存到图像中,那是行不通的。

So I went ahead and did a simple layering "system" to code as if each layer had its own code, but it all gets rendered into the same element.

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

https://github.com/federicojacobi/layeredCanvas

https://github.com/federicojacobi/layeredCanvas

I intend to add extra capabilities, but for now it will do.

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

You can do multiple functions and call them in order to "fake" layers.

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

回答by Eric Rowell

You might also checkout http://www.concretejs.comwhich is a modern, lightweight, Html5 canvas framework that enables hit detection, layering, and lots of other peripheral things. You can do things like this:

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

回答by dhaupin

I understand that the Q does not want to use a library, but I will offer this for others coming from Google searches. @EricRowell mentioned a good plugin, but, there is also another plugin you can try, html2canvas.

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

In our case we are using layered transparent PNG's with z-indexas a "product builder" widget. Html2canvas worked brilliantly to boil the stack down without pushing images, nor using complexities, workarounds, and the "non-responsive" canvas itself. We were not able to do this smoothly/sane with the vanilla canvas+JS.

在我们的例子中,我们使用分层透明 PNGz-index作为“产品构建器”小部件。Html2canvas 在不推送图像、不使用复杂性、变通方法和“无响应”画布本身的情况下,出色地将堆栈简化。我们无法使用 vanilla canvas+JS 顺利/理智地做到这一点。

First use z-indexon absolute divs to generate layered content within a relative positioned wrapper. Then pipe the wrapper through html2canvas to get a rendered canvas, which you may leave as-is, or output as an image so that a client may save it.

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

回答by aymhenry

but layer 02, will cover all drawings in layer 01. I used this to show drawing in both layers. use (background-color: transparent;) in style.

但是层 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>