38

HTML5キャンバスに円(円弧)があるとします。私はこのようにそれを埋めることができます:

ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fill();

それは御馳走を動作します。しかし、どうすれば反対の領域を埋めることができますか?これで白に黒の円が表示されますが、次の画像(白が背景色、黒が塗りつぶし色)の線に沿って配置したいと思います。

反対側のエリア

黒の背景を使って白い円を描くこともできますが、背景は何でもかまいません(以前はいろいろなものが描かれていたので、色を入れ替えるだけではいけません)。

もう1つは、キャンバス全体を塗りつぶすのではなく、円のある正方形をキャンセルする必要があるということです。

私は考えてglobalCompositeOperationいましたが、どれも私が必要とするものに従って行動しないので、それは私のニーズに合わないようです。

では、例の画像のように「反対側」の領域を埋めるにはどうすればよいでしょうか。

4

4 に答える 4

57

OPで黒い形を描きます。つまり、中央から円を切り取った長方形を描きます。

最初にbeginPath();を呼び出します。次に、円を時計回りに描きます。次に、長方形を反時計回りに描画します(またはその逆)。そして最後にfill()。

var ctx = $('#cv').get(0).getContext('2d');

ctx.fillStyle = "grey";
ctx.beginPath();
ctx.arc(200, 200, 100, 0, 2 * Math.PI);
ctx.rect(400, 0, -400, 400);
ctx.fill();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="400" height="400" id="cv"></canvas>

そこにあるほとんどのドキュメントからは明らかではないかもしれませんが、1回のfill()、stroke()、またはclip()操作で複数のサブパスを組み合わせることができます。ある形に穴を開けるには、反対方向に穴の形を描くだけです。beginPath()メソッドは、現在のパスをリセットします。fill()およびclip()の場合、Canvasはゼロ以外の回転数ルールを使用します。これを読んだ場合、より明確になるはずです。

于 2012-08-02T01:53:17.773 に答える
22

別のキャンバスをマスクとして使用してそれを行うことができます:

// This is the canvas where you want to draw
var canvas = document.getElementById('your-canvas');
var ctx = canvas.getContext('2d');

// I'll use a skyblue background that covers everything
// Just to demonstrate
ctx.fillStyle = "skyblue";
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Create a canvas that we will use as a mask
var maskCanvas = document.createElement('canvas');
// Ensure same dimensions
maskCanvas.width = canvas.width;
maskCanvas.height = canvas.height;
var maskCtx = maskCanvas.getContext('2d');

// This color is the one of the filled shape
maskCtx.fillStyle = "black";
// Fill the mask
maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
// Set xor operation
maskCtx.globalCompositeOperation = 'xor';
// Draw the shape you want to take out
maskCtx.arc(30, 30, 10, 0, 2 * Math.PI);
maskCtx.fill();

// Draw mask on the image, and done !
ctx.drawImage(maskCanvas, 0, 0);
<canvas id="your-canvas">

ここでデモ

于 2011-06-07T21:29:49.237 に答える
5

これが通常行われる方法は、描画操作が適用されるエリアマスクを作成する「クリッピング領域」を使用することです。HTML5キャンバスには、円自体であるクリッピングマスクを作成する機能があります...

http://www.html5canvastutorials.com/tutorials/html5-canvas-clipping-region-tutorial/

...しかし、Google Gears Canvasにあるsubtract()操作が欠けています。これは、私が見つけたもので、「HTML5から」であると彼らは主張しました...しかし、明らかにそうではありません。

ここでclip()を反転する方法について誰かが答えましたが、これにはオフスクリーンキャンバスが含まれます。

キャンバスの「クリップ」リバースアクション?

うまくいけば、他の誰かがより良い提案をするでしょう。:-/

于 2011-06-07T21:16:49.270 に答える
0

キャンバスマスクでXOR関数を使用すると、不透明な塗りつぶしでのみ機能します(つまり、globalAlphaとは互換性がありません)。これを回避する1つの方法は、.clip()関数を使用して、クリップされた領域をバックグラウンドにあるもので埋めることです。次に、クリップされた領域を元のキャンバスの上にオーバーレイして、必要な塗りつぶしを実行できます。

于 2017-04-17T21:19:04.403 に答える