2010-06-09 579 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