web-dev-qa-db-ja.com

html5-キャンバス要素-複数のレイヤー

拡張ライブラリがない場合、同じキャンバス要素に複数のレイヤーを含めることは可能ですか?

したがって、最上位レイヤーでclearRectを実行しても、最下位レイヤーは消去されませんか?

ありがとう。

161
Gregoire

いいえ、ただし、複数の<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キャンバスに描画し、2番目のレイヤーをlayer2キャンバスに描画します。次に、clearRectを最上位のレイヤーに配置すると、下のキャンバスにあるものがすべて表示されます。

242
jimr

これに関連する:

キャンバスに何かがあり、その後ろに何かを描きたい場合-context.globalCompositeOperation設定を 'destination-over'に変更することでそれを行うことができます-そして、それを 'source-over'に戻しますやり直しました。

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);
30
Richard

ドキュメントに追加することなく、複数のcanvas要素を作成できます。これらはあなたのlayersです:

次に、それらで必要なことを行い、最後に、drawImagecontextを使用して、宛先キャンバスでコンテンツを適切な順序でレンダリングします。

例:

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

19
juszczak

私もこれと同じ問題を抱えていましたが、position:absoluteの複数のキャンバス要素が機能しますが、出力を画像に保存したい場合は機能しません。

そこで、私は先に進み、各レイヤーに独自のコードがあるかのように単純なレイヤー化「システム」をコーディングしましたが、すべて同じ要素にレンダリングされます。

https://github.com/federicojacobi/layeredCanvas

機能を追加する予定ですが、今のところは追加します。

複数の機能を実行し、それらを呼び出してレイヤーを「偽造」できます。

4
Federico Jacobi

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

Qはライブラリを使用したくないことを理解していますが、Google検索から来る他の人にこれを提供します。 @EricRowellは良いプラグインについて言及しましたが、試してみることができる別のプラグイン html2canvas もあります。

私たちの場合、「製品ビルダー」ウィジェットとしてz-indexでレイヤー化された透過PNGを使用しています。 Html2canvasは、画像をプッシュすることなく、複雑さ、回避策、および「応答しない」キャンバス自体を使用することなく、スタックを徹底的に煮詰めるために見事に機能しました。 Vanilla canvas + JSでは、これをスムーズに行うことはできませんでした。

まず、絶対divでz-indexを使用して、相対的な位置にあるラッパー内でレイヤー化コンテンツを生成します。次に、ラッパーをhtml2canvasにパイプしてレンダリングされたキャンバスを取得します。キャンバスはそのままにするか、クライアントが保存できるように画像として出力します。

0
dhaupin