MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

合成とクリッピング

これまでの例はすべて、常にほかの図形より手前に図形が描かれました。これはほとんどの状況において十分以上ですが、合成した図形を構築する順序を制限します。しかし、globalCompositeOperation プロパティを設定すると、この動作を変更できます。さらに clip プロパティで、図形の不要な部分を隠すことができます。

globalCompositeOperation

新しい図形を既存の図形の後ろに描くだけでなく、特定の領域を覆う、一部分を canvas から消去する (clearRect() メソッドのように矩形に限定されません) などが可能です。

globalCompositeOperation = type
これは、新しい図形を描くときに適用する合成処理の種類を設定します。type は、12種類の合成処理から使用するものを特定する文字列です。

以下の例のコードについては、合成のサンプルをご覧ください。

クリッピングパス

クリッピングパスは通常の canvas の図形に似ていますが、図形の不要な部分を隠すマスクとして作用します。これを右の画像で視覚化しました。赤い星型の図形は、クリッピングパスです。このパスの外側にあるものはすべて、canvas で描画されません。

クリッピングパスと先ほどの globalCompositeOperation プロパティを比較すると、おおむね同じ効果をもたらす合成モードとして source-insource-atop の 2 つがあることがわかります。これら 2 つとのもっとも重要な違いは、クリッピングパスは実際に canvas に描かれるものではないことと、クリッピングパスは新しい図形による影響を受けないことです。これは制限された領域に複数の図形を描くという、クリッピングパスの目標を表しています。

図形を描く の章では stroke() および fill() メソッドのみ言及しましたが、パスを扱う第 3 のメソッドとして clip() があります。

clip()
現在構築しているパスを、現在のクリッピングパスに変換します。

closePath() の代わりに clip() を使用して、パスの輪郭を描いたり塗りつぶすのではなく、パスを閉じてクリッピングパスに変換します。

デフォルトで <canvas> 要素には、canvas 自体とまったく同じサイズのクリッピングパスが存在します。言い換えると、クリッピングは行われません。

clip の例

この例では、ランダムな星の集団の描画先を特定の領域に制限するために、円形のクリッピングパスを使用しています。

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  ctx.fillRect(0,0,150,150);
  ctx.translate(75,75);

  // 円形のクリッピングパスを作成
  ctx.beginPath();
  ctx.arc(0,0,60,0,Math.PI*2,true);
  ctx.clip();

  // 背景を描く
  var lingrad = ctx.createLinearGradient(0,-75,0,75);
  lingrad.addColorStop(0, '#232256');
  lingrad.addColorStop(1, '#143778');
  
  ctx.fillStyle = lingrad;
  ctx.fillRect(-75,-75,150,150);

  // 星を描く
  for (var j=1;j<50;j++){
    ctx.save();
    ctx.fillStyle = '#fff';
    ctx.translate(75-Math.floor(Math.random()*150),
                  75-Math.floor(Math.random()*150));
    drawStar(ctx,Math.floor(Math.random()*4)+2);
    ctx.restore();
  }
  
}

function drawStar(ctx,r){
  ctx.save();
  ctx.beginPath();
  ctx.moveTo(r,0);
  for (var i=0;i<9;i++){
    ctx.rotate(Math.PI/5);
    if(i%2 === 0) {
      ctx.lineTo((r/0.525731)*0.200811,0);
    } else {
      ctx.lineTo(r,0);
    }
  }
  ctx.closePath();
  ctx.fill();
  ctx.restore();
}

コードの始めの数行で、背景として canvas と同サイズの黒い背景を描いて、原点を中央に移動します。次に、円弧を描いて clip() を呼び出すことで、円形のクリッピングパスを作成します。クリッピングパスは、canvas の状態として保存されるもののひとつでもあります。元のクリッピングパスを維持したい場合は、新しいクリッピングパスを作成する前に保存した canvas の状態があるとよいでしょう。

クリッピングパスを作成した後に描いたものはすべて、パスの内部にあるものだけが見える状態になります。これは、次に描いている線形グラデーションで明らかです。この後に独自の drawStar() 関数を使用して、位置や大きさがランダムな星を 50 個描きます。星もまた、クリッピングパスの内部で定義されたものしか見えません。

ScreenshotLive sample

ドキュメントのタグと貢献者

 このページの貢献者: yyss, micahcarroll
 最終更新者: yyss,