2010-06-09 168 views
140

没有任何扩展库,是否可以在同一个canvas元素中有多个图层?html5 - canvas元素 - 多个图层

因此,如果我在顶层执行clearRect,它不会清除底层的一个?

谢谢。

+1

检查了这个.. http://html5.litten.com/using-multiple-html5-canvases-as-layers/这将帮助你以正确的方式解决你的问题 – Dakshika 2014-02-23 05:13:08

+0

你可能想看看http://radikalfx.com/2009/10/16/canvas-collage/。他使用了一种“图层”技术。 – Matthew 2010-07-25 11:23:36

回答

214

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

的​​画布上画出你的第一层,和layer2画布上的第二层。然后当你在顶层上clearRect时,下层画布上的任何东西都会显示出来。

+3

感谢您的回答。一个bemol:z-index不是zIndex;) – Gregoire 2010-06-09 19:04:56

+0

谢谢,更新。 – jimr 2010-06-09 19:08:50

+0

有没有隐藏/取消隐藏图层的方法..这样我就可以隐藏图层1并显示图层2,反之亦然。 – Zaraki 2012-06-12 13:56:11

26

与此相关:

如果你有你的画布上的东西,你想在它的背面画的东西 - 你可以通过改变context.globalCompositeOperation设置为“目的地在”做它 - 然后在完成后将其恢复为“源代码”。

var co = document.getElementById('cvs').getContext('2d'); 

// Draw a red square 

co.fillStyle = 'red'; 
co.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 whats already on the canvas 

co.globalCompositeOperation = 'destination-over'; 



// Draw a big yellow rectangle 

co.fillStyle = 'yellow'; 
co.fillRect(0,0,600,250); 


// Now return the globalCompositeOperation to source-over and draw a 
// blue rectangle 

co.globalCompositeOperation = 'source-over'; 

co.fillStyle = 'blue'; 
co.fillRect(75,75,100,100); 
12

您可以在不附加他们到文档中创建多个canvas元素。这些将是你

然后做你想要与他们在最后无论只呈现他们以正确的顺序在上context使用drawImage目的地帆布内容。

+0

表现杀手。约慢10倍。 – SCLeo 2017-04-02 21:00:23

+2

@SCLeo你说的“性能杀手,慢了大约10倍”是完全错误的。取决于使用单个DOM画布和渲染离线画布的用例,这比在DOM中堆叠画布更快。常见的错误是绘制渲染调用的基准,画布绘制调用可以是定时的,DOM渲染在Javascript的上下文之外并且不能被定时。结果是DOM堆叠画布不能获得基准测试中包含的合成渲染(由DOM完成)。 – Blindman67 2017-04-18 20:08:26

+0

@ Blindman67我知道你的意思。只需检查此基准:https://jsfiddle.net/9a9L8k7k/1/。如果你误解了,有三个画布,画布1(ctx1)是一个真正的画布。画布2(ctx2)和画布3(ctx)不在屏幕上。该图像先前已被渲染到ctx3上。在这个基准测试1中,我直接将ctx3渲染到ctx1上。在测试2中,我将ctx3渲染为ctx2,然后将ctx2渲染为ctx1。测试2在我的电脑上比测试1慢30倍。这就是为什么我说使用中间画布要慢得多。 – SCLeo 2017-04-19 04:24:22

4

我也有这个相同的问题,我虽然多个画布元素与位置:绝对做的工作,如果你想保存输出到图像,这是行不通的。

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

https://github.com/federicojacobi/layeredCanvas

我打算增加额外的功能,但现在它会做。

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

+0

这是完美的。 – Nadir 2016-01-11 12:22:37

2

您可能还签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(); 
+0

真的很感谢你的工作 – Guigui 2017-11-06 03:18:37

0

据我所知,将q不希望使用一个库,但我会提供这种为他人从谷歌搜索来。 @EricRowell提到了一个好插件,但是,还有另一个插件可以试用,html2canvas

在我们的案例中,我们使用分层透明PNG与z-index作为“产品构建器”小部件。 Html2canvas工作出色归结堆栈没有推的图像,也使用的复杂性,解决方法,以及“不响应”画布本身。我们无法用香草帆布+ JS顺利/理智地做到这一点。

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

+0

如果你有更重的图像,这将需要一些时间来转换HTML到画布,我们不得不摆脱这一切,只是因为渲染花了很长时间。 – Vilius 2017-09-27 15:36:58

+0

@Vilius是很好的电话重/大图像。我们试图坚持不超过4层的300K或更少的图像,否则资源受到破坏的客户会在下载最终的堆肥图像时感到灼热。好奇,你为什么会缩短时间? – dhaupin 2017-10-07 22:10:32

+0

那么,我们首先使用html元素来绘制一些东西,这是一个很大的错误。由于我们的api返回了x,y,宽度和高度,我们转而使用jscanavs来绘制图像,而不是使用html元素。请注意,我们确实遇到了几个轮换问题(起点有点尴尬和不可预知),并且使用特定维度将图像应用于其中,但最终都解决了这些问题。我们还发现,我们的图像处理应用程序耗尽了大量资源,所以我们也离开了。 – Vilius 2017-10-11 11:21:58