コンポジット方式
キャンバスが必要な場合は、単純に複合モードを使用できます (またはborder-radius
、他の回答のように CSS3 をお勧めします)。
ライブデモはこちら
var rect = [20, 20, 300, 300],
cr = 25; // corner radius
角丸四角形のパスを作成します。
var pi = Math.PI, // cache it here to make code more readable
x1 = rect[0], // cache points
y1 = rect[1],
x2 = rect[2] + x1,
y2 = rect[3] + y1;
// create a rounded rectangle path
ctx.beginPath();
ctx.arc(x1 + cr, y1 + cr, cr, pi, 1.5 * pi); // upper left corner
ctx.arc(x2 - cr, y1 + cr, cr, 1.5 * pi, 0); // upper right corner
ctx.arc(x2 - cr, y2 - cr, cr, 0, 0.5 * pi); // lower right corner
ctx.arc(x1 + cr, y2 - cr, cr, 0.5 * pi, pi); // lower left corner
ctx.closePath();
これで、角丸長方形のパスができました。次に行う必要があるのは、単色を作成して、これを合成モードで使用できるようにすることです。ここでは、デフォルトの塗りつぶし色を使用します。
ctx.fill();
これで、次に描画されるものを現在のピクセル (塗りつぶされたピクセル) の上に描画する必要があると言うように、コンポジット モードを設定できます。
ctx.globalCompositeOperation = 'source-atop';
// draw in image
ctx.drawImage(img, x1, y1, x2 - x1, y2 - y1);
次に、合成モードをリセットして、通常どおりに描画できるようにします (これは、保存/復元を使用するよりも高速で低コストです)。
ctx.globalCompositeMode = 'source-over'; /// default composite mode
// draw a thick border
ctx.lineWidth = 20;
ctx.stroke();
複合モードとクリッピングの欠点と利点。
もう 1 つの方法はclip()
パスで使用することですが、現時点ではクリッピングをリセットするクリーンな方法がないため、クリッピングによってsave()
/を使用する必要があることに注意してください (将来的に修正される可能性があります)。保存/復元は、すべての設定をスタックに保存し、復元時にすべての設定をポップバックする必要restore()
があるため、コストのかかる操作です。
最初にクリッピングを削除せずにパスをストロークすると、ストロークは半分にカットされます。
合成の欠点は、新しい画像の背景に他のコンテンツが既に描画されている場合です。解決するには、オフスクリーン キャンバスを使用してこの操作を行い、その結果をメイン キャンバスに描画する必要があります。