1 回答
TA贡献1869条经验 获得超4个赞
这是因为该arc方法在内部跟踪 alineTo从当前指针的位置到弧的开头(由 cx、cy和startAngle 定义)。
要解决这个问题,您需要处于moveTo该位置。
下面是一个使用半圆且设置startAngle为 0 rad 的更简单演示:
const canvas = document.createElement( "canvas" );
document.body.append( canvas );
const ctx = canvas.getContext( "2d" );
ctx.lineWidth = 2;
const cx = 50;
const cy = 50;
const rad = 30;
ctx.beginPath();
ctx.moveTo( cx, cy );
ctx.arc( cx, cy, rad, 0, Math.PI );
ctx.strokeStyle = "red";
ctx.stroke();
ctx.translate( 80, 0 );
const first_point_x = cx + rad; // startAngle is 0
// so we just have to add 'rad'
// to find the x coord
ctx.beginPath();
ctx.moveTo( first_point_x, cy );
ctx.arc( cx, cy, rad, 0, Math.PI );
ctx.strokeStyle = "green";
ctx.stroke();
因此,您必须计算弧线起点和moveTo
该点的坐标。
这是可行的,但我对 trigo 不是最好的,并且您的值非常复杂,因此,这里有一个使用 Path2D 对象的解决方法。
如果该arc
命令是子路径的第一个,它将直接指向moveTo
该初始点(因为还没有“当前指针的位置”)。
因此,我们可以将所有弧初始化为独立的 Path2D 对象,仅由这些arc
命令组成。然后我们只需将这些 Path2D 对象合并到最后一个对象中并绘制它:
const canvas = document.createElement("canvas");
document.body.append(canvas);
const c = canvas.getContext("2d");
c.lineWidth = 2;
const fish = new Fish(150, 50, 50, 50, 50);
fish.draw();
function Fish(x, y, dx, dy, radius) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.radius = 30;
this.draw = function() {
const p1 = new Path2D();
p1.arc(this.x / 0.6, this.y, this.radius, Math.PI * 1.5, Math.PI * 0.5, false)
//Upper Arc
const p2 = new Path2D();
p2.arc(this.x / 0.6, this.y + (3 * this.radius), this.radius * 4, Math.PI * 229 / 180, Math.PI * 1.5, false)
//Lower Arc
const p3 = new Path2D();
p3.arc(this.x / 0.6, this.y - (3 * this.radius), this.radius * 4, Math.PI * 131 / 180, Math.PI * 0.5, true)
// merge in a single Path2D object
const path = new Path2D();
path.addPath(p1);
path.addPath(p2);
path.addPath(p3);
c.strokeStyle = "green";
c.stroke(path);
}
}
但在您的情况下,通过更改绘制 Path 的顺序并且从不调用moveTo.
const canvas = document.createElement("canvas");
document.body.append(canvas);
const c = canvas.getContext("2d");
c.lineWidth = 2;
const fish = new Fish(150, 50, 50, 50, 50);
fish.draw();
function Fish(x, y, dx, dy, radius) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.radius = 30;
this.draw = function() {
c.beginPath();
c.arc(this.x / 0.6, this.y, this.radius, Math.PI * 1.5, Math.PI * 0.5, false)
// Lower Arc
c.arc(this.x / 0.6, this.y - (3 * this.radius), this.radius * 4, Math.PI * 0.5, Math.PI * 131 / 180, false)
// Upper Arc
// (inverse startAngle and endAngle + switch swipe to false)
c.arc(this.x / 0.6, this.y + (3 * this.radius), this.radius * 4, Math.PI * 229 / 180, Math.PI * 1.5, false)
c.strokeStyle = "green";
c.stroke();
}
}
添加回答
举报