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();
}
}
添加回答
舉報