jar*_*red 2 html javascript graphics drawing canvas
笔: https: //codepen.io/jaredstanley/pen/gvmNye
var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
var centerw = canvas.width/2;
var centerh = canvas.height/2;
var sq_w = 80;
//
ctx.beginPath();
//draw rectangle
ctx.rect(this.centerw-(sq_w/2), 0,sq_w, canvas.height);
//draw circle
ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2, true);
//fill
ctx.fill();
Run Code Online (Sandbox Code Playgroud)
两个形状都绘制出来,但形状的交集是空白的。
想要拥有一个单一的填充形状,但得到以下结果:[
要求:不能使用CanvasRenderingContext2D.globalCompositeOperation,因为我正在将其用于其他用途;这需要用作单个形状,以便我可以使用该形状来...clip()。
注意:当使用两个 rect() 调用时,它可以工作,当使用两个 arc() 调用时,它可以工作,但混合它们似乎会导致问题。
看起来应该很容易,但我很困惑,缺少一些我认为基本的东西。谢谢!
小智 5
只需删除(或设置为)方法false上的逆时针标志,否则这将定义影响用于填充的默认非零缠绕算法的“相反”方向的路径:arc()
//ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2, true); ->
ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2);
Run Code Online (Sandbox Code Playgroud)
根据非零缠绕规则,我们将从“发出”线的点开始计数的缠绕相加。对于点线的每一条线相交,我们检查相交线的方向,并为一个方向赋予+1,如果相反方向则赋予-1,并将它们相加。
为了显示:

对于左侧的插图,我们可以看到前两条线交点的方向之和(如果点位于 y 的左侧和中心)将为 0(“零”),因此中心部分没有填充。如果一个点从中心顶部向下穿过形状发送一条线,也会发生这种情况。
然而,在右图中,当我们到达内部部分时,总和不为零,因此它也被填充。
arc()使用顺时针方向代替//ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2, true); ->
ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2);
Run Code Online (Sandbox Code Playgroud)
var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
var centerw = canvas.width/2;
var centerh = canvas.height/2;
var sq_w = 120;
//
ctx.beginPath();
//draw rectangle
ctx.rect(centerw-(sq_w/2), 0,sq_w, canvas.height);
//draw circle
ctx.moveTo(centerw + 185, centerh); // create new sub-path (is unrelated, see below)
ctx.arc(centerw, centerh, 185, 0, Math.PI * 2); // <- don't use the CCW flag
//fill
ctx.fill();Run Code Online (Sandbox Code Playgroud)
不相关但要记住的事情:您还需要为圆弧创建一个新的子路径,以避免冒从矩形的角到圆弧上的起始角度点的线的风险。只需在添加圆弧之前添加此行:
ctx.moveTo(centerw + 185, centerh);
ctx.arc(centerw, centerh, 185, 0, Math.PI * 2);
Run Code Online (Sandbox Code Playgroud)