html5 - canvas 元素 - 多层

发布于 2024-09-05 04:13:40 字数 87 浏览 5 评论 0原文

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

那么如果我在顶层执行clearRect,它不会擦除底层吗?

谢谢。

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?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

我早已燃尽 2024-09-12 04:13:40

不,但是,您可以将多个 元素相互叠加并完成类似的操作。

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

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

<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 layer1 canvas, and the second layer on the layer2 canvas. Then when you clearRect on the top layer, whatever's on the lower canvas will show through.

屋顶上的小猫咪 2024-09-12 04:13:40

与此相关:

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

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.

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

没有伤那来痛 2024-09-12 04:13:40

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

然后对它们执行您想要的任何操作,最后只需在 contextdrawImage 在目标画布上以正确的顺序渲染其内容代码>.

示例:

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

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

Then do whatever you want with them and at the end just render their content in proper order at destination canvas using drawImage on 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

焚却相思 2024-09-12 04:13:40

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

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

https://github.com/federicojacobi/layeredCanvas

我打算添加额外的功能,但目前它会做。

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

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.

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

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.

怼怹恏 2024-09-12 04:13:40

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

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

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();
明媚如初 2024-09-12 04:13:40

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

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.

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

夏见 2024-09-12 04:13:40

基于堆叠多个 元素的想法,我做了一个演示 多个画布层

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

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

Based on the idea stacking multiple <canvas> elements, I made a demo Multiple Canvas Layers.

It contains 3 stacked layers: background (bg), intermediate (grid), foreground (fg).

To blend layers when saving/exporting, just create an OffscreenCanvas and invoke drawImage() to draw related <canvas> elements in order.

靖瑶 2024-09-12 04:13:40

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

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

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

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.

In our case we are using layered transparent PNG's with z-index as 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.

First use z-index on 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.

揽清风入怀 2024-09-12 04:13:40

是的,这是可能的。

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

Yes, it is possible.

Since the Canvas element has an integrated structure like in Paint, the first thing you need to do is to store all the drawings in a global variable. Then, for each change you make in this variable, you will automatically redraw the changes on the Canvas. The subsequent steps include displaying the data from the global variable on the screen, presenting them like layers, and for the left-right movement using the mouse on the Canvas, you will compare the height values in your global variable by utilizing the properties of the Canvas for mouseover and click, and draw an area accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文