キャンバスから領域をクリアする唯一の方法は、clearRect()コマンドを使用することです-円をクリアする必要があります(塗りつぶされたキャンバス、この特定のケースではポイントライト)から領域をマスクし、すべての試行にもかかわらず不可能のようです。
アルファ値が0の円を描画しようとしましたが、アルファがそれよりも高い場合を除いて、何も表示されません(これは、ポイント:Pに対応します)。contex.fill()は、それを置換ではなく追加として描画するため、 。
マスクの目的で円を(すばやく)クリアする方法についての提案はありますか?
_.arc
_を使用して円形のストロークを作成し、次に.clip()
を使用して現在のクリッピング領域にします。
次に、.clearRect()
を使用してキャンバス全体を消去できますが、変更されるのはクリップされた領域のみです。
ゲームや、パフォーマンスのあらゆる部分を絞ることが重要な何かを作成している場合は、私がこの答えをどのように作成したかを確認してください: キャンバス-完全に透明なすべての領域で長方形を塗りつぶします
具体的には、これにつながる回答の編集: http://jsfiddle.net/a2Age/2/
ここの巨大なプラス:
(1)私は実際に これについて不平を言いました そして、それが原因でresetClip()が公式仕様に入れられましたが、ブラウザが実装するまでにはしばらくかかりますそれ。
var ctx = document.getElementById('canvas1').getContext('2d'),
ambientLight = 0.1,
intensity = 1,
radius = 100,
amb = 'rgba(0,0,0,' + (1 - ambientLight) + ')';
addLight(ctx, intensity, amb, 200, 200, 0, 200, 200, radius); // First circle
addLight(ctx, intensity, amb, 250, 270, 0, 250, 270, radius); // Second circle
addLight(ctx, intensity, amb, 50, 370, 0, 50, 370, radius, 50); // Third!
ctx.fillStyle = amb;
ctx.globalCompositeOperation = 'xor';
ctx.fillRect(0, 0, 500, 500);
function addLight(ctx, intsy, amb, xStart, yStart, rStart, xEnd, yEnd, rEnd, xOff, yOff) {
xOff = xOff || 0;
yOff = yOff || 0;
var g = ctx.createRadialGradient(xStart, yStart, rStart, xEnd, yEnd, rEnd);
g.addColorStop(1, 'rgba(0,0,0,' + (1 - intsy) + ')');
g.addColorStop(0, amb);
ctx.fillStyle = g;
ctx.fillRect(xStart - rEnd + xOff, yStart - rEnd + yOff, xEnd + rEnd, yEnd + rEnd);
}
canvas {
border: 1px solid black;
background-image: url('http://placekitten.com/500/500');
}
<canvas id="canvas1" width="500" height="500"></canvas>
要件を考えると、これらの回答は問題ありません。しかし、あなたが私のようなもので、追加の要件があるとしましょう:
最初の要件の解決策は、_context.globalCompositeOperation = 'destination-out'
_を使用することです。青色は最初の形状で、赤色は2番目の形状です。ご覧のように、_destination-out
_は最初の形状からセクションを削除します。
ここにいくつかのサンプルコードがあります:
_ explosionCanvasCtx.fillStyle = "red"
drawCircle(explosionCanvasCtx, projectile.radius, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'destination-out' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
drawCircle(explosionCanvasCtx, projectile.radius + 20, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
_
これに関する潜在的な問題は次のとおりです。2番目のfill()
は、背景を含め、その下にあるすべてのすべてをクリアします。最初のシェイプだけをクリアしたいが、その下にあるレイヤーを表示したい場合があります。
これを解決するには、これを一時キャンバスに描画し、次にdrawImage
を使用して一時キャンバスをメインキャンバスに描画します。コードは次のようになります。
_ diameter = projectile.radius * 2
console.log "<canvas width='" + diameter + "' height='" + diameter + "'></canvas>"
explosionCanvas = $("<canvas width='" + diameter + "' height='" + diameter + "'></canvas>")
explosionCanvasCtx = explosionCanvas[0].getContext("2d")
explosionCanvasCtx.fillStyle = "red"
drawCircle(explosionCanvasCtx, projectile.radius, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'destination-out' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
durationPercent = (projectile.startDuration - projectile.duration) / projectile.startDuration
drawCircle(explosionCanvasCtx, projectile.radius + 20, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'source-over' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
ctx.drawImage(explosionCanvas[0], projectile.pos.x - projectile.radius, projectile.pos.y - projectile.radius) #center
_
いくつかのオプションがあります。
まず、円を塗りつぶすために使用する関数を次に示します。
_var fillCircle = function(x, y, radius)
{
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
};
_
clip()
_var clearCircle = function(x, y, radius)
{
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.clip();
context.clearRect(x - radius - 1, y - radius - 1,
radius * 2 + 2, radius * 2 + 2);
};
_
jsFiddle でこれを参照してください。
globalCompositeOperation
_var clearCircle = function(x, y, radius)
{
context.save();
context.globalCompositeOperation = 'destination-out';
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
context.restore();
};
_
jsFiddle でこれを参照してください。
どちらも画面上で望ましい結果をもたらしましたが、エフェクトのためにフレームごとに多数の円を描画してクリアしていたため、私の場合、パフォーマンスは十分ではありませんでした。結局、弧に太い線を描くだけで、同じような効果を得るための別の方法を見つけましたが、上記の方法は、パフォーマンス要件が異なる人にも役立ちます。
ここで、x =左位置、y =右位置、r =半径、ctx =キャンバス:
function clearCircle( x , y , r ){
for( var i = 0 ; i < Math.round( Math.PI * r ) ; i++ ){
var angle = ( i / Math.round( Math.PI * r )) * 360;
ctx.clearRect( x , y , Math.sin( angle * ( Math.PI / 180 )) * r , Math.cos( angle * ( Math.PI / 180 )) * r );
}
}
canvas.getContext("2d").arc(...)
を使用して、背景色のある領域に円を描画しますか?
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.arc(x, y, r, 0, 2*Math.PI, false);
context.fillStyle = "#FFFFFF";
context.fill();