Javascript 在画布中标记两个圆之间的相交区域

Javascript 在画布中标记两个圆之间的相交区域,javascript,html5-canvas,Javascript,Html5 Canvas,我试图标记两个圆之间的重叠区域(如维恩图)。我认为这样做的方法是使用两个相交点绘制两条圆弧,然后使用fill()填充路径。 我知道交点的坐标,但如何将其用作arc()函数的输入 ctx.beginPath(); ctx.arc(circle1.x,circle1.y,circle1.r, ? , ? ,true); ctx.fill(); ctx.closePath(); 您可以使用canvas的GlobalComposite操作绘制两个形状的交点 GlobalComposite操作允许您控

我试图标记两个圆之间的重叠区域(如维恩图)。我认为这样做的方法是使用两个相交点绘制两条圆弧,然后使用
fill()
填充路径。 我知道交点的坐标,但如何将其用作
arc()
函数的输入

ctx.beginPath();
ctx.arc(circle1.x,circle1.y,circle1.r, ? , ? ,true);
ctx.fill();
ctx.closePath();

您可以使用canvas的GlobalComposite操作绘制两个形状的交点

GlobalComposite操作允许您控制旧图形和新图形的哪些部分显示在画布上

您可以在此处看到每个合成模式的示例:

我们使用其中两种合成模式来突出显示两个圆的交点:

源顶

假设左圆已经绘制,source TOP将仅绘制右圆的相交部分

    ctx.globalCompositeOperation="source-atop";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
目的地结束

鉴于左圆圈已经绘制,destination over将在现有左圆圈下方绘制右圆圈

    ctx.globalCompositeOperation="destination-over";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
这需要考虑很多,因此您可以注释掉所有图形代码,然后逐个取消注释,以查看每个操作的效果

下面是代码和小提琴:


正文{背景色:象牙;}
画布{边框:1px纯红;}
$(函数(){
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
ctx.fillStyle=“黄色”;
ctx.strokeStyle=“黑色”;
ctx.线宽=3;
var circle1={x:100,y:100,r:50};
var圈2={x:140,y:100,r:50};
//画圆圈1
ctx.save();
ctx.beginPath();
ctx.arc(circle1.x,circle1.y,circle1.r,0,2*Math.PI,false);
ctx.stroke();
ctx.fill();
//用于绘制交叉点的复合模式“源顶部”
ctx.beginPath();
ctx.fillStyle=“橙色”;
ctx.globalCompositeOperation=“source”;
ctx.arc(circle2.x,circle2.y,circle2.r,0,2*Math.PI,false);
ctx.fill();
ctx.stroke();
ctx.restore();
//目的地再次绘制圆圈2的填充
ctx.beginPath();
ctx.globalCompositeOperation=“目的地结束”;
ctx.arc(circle2.x,circle2.y,circle2.r,0,2*Math.PI,false);
ctx.fill();
//返回正常合成模式(最新图纸位于顶部)
ctx.globalCompositeOperation=“源代码结束”;
//再次绘制圆圈1的笔划
ctx.beginPath();
ctx.arc(circle1.x,circle1.y,circle1.r,0,2*Math.PI,false);
ctx.stroke();
//再次绘制圆圈2的笔划
ctx.beginPath();
ctx.arc(circle2.x,circle2.y,circle2.r,0,2*Math.PI,false);
ctx.stroke();
}); // end$(函数(){});

感谢您的详细回答!
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    ctx.fillStyle="yellow";
    ctx.strokeStyle="black";
    ctx.lineWidth=3;

    var circle1={x:100,y:100,r:50};
    var circle2={x:140,y:100,r:50};


    // draw circle1
    ctx.save();
    ctx.beginPath();
    ctx.arc(circle1.x,circle1.y,circle1.r, 0, 2*Math.PI, false);
    ctx.stroke();
    ctx.fill();

    // composite mode "source-atop" to draw the intersection
    ctx.beginPath();
    ctx.fillStyle="orange";
    ctx.globalCompositeOperation="source-atop";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
    ctx.fill();
    ctx.stroke();
    ctx.restore();

    // destination-over to draw fill for circle2 again
    ctx.beginPath();
    ctx.globalCompositeOperation="destination-over";
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
    ctx.fill();

    // back to normal composite mode (newest drawings on top)
    ctx.globalCompositeOperation="source-over";

    // draw the stroke for circle1 again
    ctx.beginPath();
    ctx.arc(circle1.x,circle1.y,circle1.r, 0, 2*Math.PI, false);
    ctx.stroke();

    // draw the stroke for circle2 again
    ctx.beginPath();
    ctx.arc(circle2.x,circle2.y,circle2.r, 0, 2*Math.PI, false);
    ctx.stroke();

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>