[英]How do I clip / use globalCompositeOperation = “desination-out” to exclude 2 circles from my Canvas?
I am trying to figure out CanvasRenderingContext2D.globalCompositeOperation = "destination-out
in order to create a "Fog of War" effect. 我试图弄清楚
CanvasRenderingContext2D.globalCompositeOperation = "destination-out
,以便创建”战争迷雾“效果。
Given this example 给出这个例子
https://jsfiddle.net/wobzpjLL/ https://jsfiddle.net/wobzpjLL/
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// a green background box
ctx.fillStyle = "green";
ctx.fillRect(0,0,300,150);
// a line
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(300, 150);
ctx.stroke();
// Fog of war
ctx.fillStyle = "black";
ctx.fillRect(0,0,300,150);
// Here I want two circles that shows the background (green & line)
// text
ctx.fillStyle = "red";
ctx.font = "30px Arial";
ctx.fillText("Hello World",10,50);
How do I create two circles that excludes the black overlay, so that the user can see the green background and the line, within those two circles, black everywhere else (hence creating a fog of war effect)? 如何创建不包括黑色叠加层的两个圆圈,以便用户可以看到绿色背景和线条(在这两个圆圈内,其他任何地方都是黑色的,因此会产生战争迷雾效果)?
The easiest way to achieve the masking is by creating a offscreen canvas and render the mask onto that. 实现蒙版的最简单方法是创建一个屏幕外画布,然后在其上渲染蒙版。 Then when animating you render the world and then apply the mask with
"destination-in"
. 然后在设置动画时渲染世界,然后使用
"destination-in"
应用蒙版。 You can use the canvas CSS background as the fog (as done in demo) or you can render the fog over the top with "destination-over"
also shown in demo using the text. 您可以使用画布CSS背景作为雾(在演示中进行此操作),也可以使用文本在演示中显示的
"destination-over"
在顶部渲染雾。
Personally and for performance (if code is needing every break it can get) I would avoid globalCompositeOperation
and render the fog over the world by creating the inverse of the mask in the demo. 就个人和性能(如果代码需要尽一切可能中断),我将避免使用
globalCompositeOperation
并通过在演示中创建掩码的globalCompositeOperation
渲染整个世界的迷雾。 This adds only the one extra render call and no need to change composite operations 这仅添加了一个额外的渲染调用,而无需更改复合操作
var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); function createCanvas(){ var c = document.createElement("canvas"); c.width = 300; c.height = 150; c.ctx = c.getContext("2d"); return c; } // draw game world on offscreen canvas function drawBackground(ctx){ ctx.fillStyle = "green"; ctx.fillRect(0,0,300,150); // a line ctx.beginPath(); ctx.lineWidth = 3; ctx.strokeStyle = "#08A"; ctx.lineTo(0, 0); ctx.lineTo(300, 150); ctx.stroke(); } // create and render world var bGround = createCanvas(); drawBackground(bGround.ctx) // create mask var grad = ctx.createRadialGradient(0,0,60,0,0,0); grad.addColorStop(0,"rgba(0,0,0,0.0)"); grad.addColorStop(0.2,"rgba(0,0,0,1)"); grad.addColorStop(1,"rgba(0,0,0,1)"); var mask = createCanvas(); mask.ctx.setTransform(1,0,0,1,75,75); mask.ctx.fillStyle = grad; mask.ctx.beginPath(); mask.ctx.arc(0,0,60,0,Math.PI*2); mask.ctx.fill(); mask.ctx.setTransform(1,0,0,1,225,75); mask.ctx.beginPath(); mask.ctx.arc(0,0,60,0,Math.PI*2); mask.ctx.fill(); document.body.appendChild(mask); // draws the fog function drawFog(ctx,x){ ctx.globalCompositeOperation = "destination-in"; ctx.drawImage(mask, x, 0); ctx.globalCompositeOperation = "source-over"; } ctx.fillStyle = "red"; ctx.font = "30px Arial"; function loop(time){ ctx.drawImage(bGround,0,0); drawFog(ctx,Math.sin(time / 1000) *20); ctx.globalCompositeOperation = "destination-over"; ctx.fillText("Hello World",10,50); ctx.globalCompositeOperation = "source-over"; requestAnimationFrame(loop); } requestAnimationFrame(loop);
canvas { border:1px solid #d3d3d3; }
<canvas id="myCanvas" width="300" height="150" style="background : black;" ></canvas> <div>Pre rendered offscreen mask shown below for display only.</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.