PEN: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();
两个形状都是绘制但形状的交叉是空白的。
希望获得一个单一的填充形状,但得到以下结果:[
要求:
无法使用CanvasRenderingContext2D.globalCompositeOperation
,因为我将其用于其他内容;这需要用作单个形状,所以我可以使用形状... clip()。
注意:当使用两个rect()调用时,它可以正常工作,并且在使用两个arc()调用时它可以工作,但混合它们似乎会导致问题。
似乎应该很容易,但我很难过,我想错过一些基本的东西。谢谢!
答案 0 :(得分:2)
只需删除(或设置为false
)arc()
method上的反时钟标志,否则将定义"反对"的路径。影响用于填充的默认non-zero winding algorithm的方向:
//ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2, true); ->
ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2);
根据非零缠绕规则,我们将从一个线被发送出来的点开始计算绕组数"。对于点线的每个线交点,我们检查交叉线的方向,并给出一个方向+1,如果方向相反,则为-1,并将它们加在一起。
举例说明:
对于左边的插图,我们可以看到两个第一线交点的方向之和(如果点位于左侧,中间位于y上)将为0("零和#34;)所以没有填写中心部分。如果一个点从中心顶部向下发送一条直线穿过形状,也会发生这种情况。
然而,在右边的插图中,当我们来到内部区域时,总和不为零,因此它也会被填满。
arc()
使用顺时针方向
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();
&#13;
<canvas id="c" width="500" height="500"></canvas>
&#13;
不相关但需要注意的事项:您还需要为圆弧创建一个新的子路径,以避免冒险从直角的一条直线移动到圆弧上的起始角点。只需在添加弧之前添加此行:
ctx.moveTo(centerw + 185, centerh);
ctx.arc(centerw, centerh, 185, 0, Math.PI * 2);
答案 1 :(得分:1)
ctx.beginPath();
//draw rectangle
ctx.rect(this.centerw - (sq_w / 2), 0, sq_w, canvas.height);
ctx.fill();
//draw circle
ctx.beginPath();
ctx.arc(this.centerw, this.centerh, 185, 0, Math.PI * 2, true);
//fill
ctx.fill();
答案 2 :(得分:1)
您看到的结果是因为交叉路径包含的表面上的标准操作是要忽略的。
var canvas = document.getElementById('c');
var ctx = canvas.getContext("2d");
var centerw = canvas.width/2;
var centerh = canvas.height/2;
var sq_w = 80;
//draw rectangle
ctx.fillRect(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();
&#13;
<canvas id='c' height=500 width=500/>
&#13;
需要在两轮之间填充形状。或者,在代码片段中,我将ctx.rect更改为ctx.fillRect。
另一种方法是在弧之前开始一条新路径。