javascript - 移动圆弧上出现半径线
问题描述
我试图创建这些移动的形状,形状由半圆和对称的上弧和下弧组成。它们应该只是前面的形状,但现在它们移动时有一条像尾巴一样拖在后面的线。 尾部未知的输出形状
似乎这些线来自上下弧的 moveTo 部分,但我不知道如何解决它。我应该在哪里改变以摆脱它?
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)
//Upper Arc
c.moveTo(this.x, this.y);
c.arc(this.x/0.6, this.y+(3*this.radius), this.radius*4, Math.PI * 229/180, Math.PI * 1.5, false)
//Lower Arc
c.moveTo(this.x, this.y);
c.arc(this.x/0.6, this.y-(3*this.radius), this.radius*4, Math.PI * 131/180 , Math.PI * 0.5, true)
c.strokeStyle = "green";
c.stroke();
}
解决方案
这是因为该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);
}
}
但是在您的情况下,您可以通过更改绘制路径的顺序并且从不调用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();
}
}
推荐阅读
- sas - 如何在新列中保留最新值
- go - 接受 interface{} 参数的函数如何通过引用更新它被调用的值?
- http - 如何使用护照为 Google 的 oAuth 流程编写集成测试?
- mysql - Mysql getConnection() 不返回nodejs中的回调函数
- merge - tf merge /discard 报告“没有要合并的更改”,但 tf merge /candidate 显示我要丢弃的变更集
- python - 将 win32client SAPI.SpVoice 与多线程一起使用会导致 pywintypes.com_error
- android - 我应该如何在 android 中维护会话以及我应该存储什么(散列密码或其他内容)以保持登录状态
- python - 插入数据以协调来自链接不同侧的读数的算法?
- javascript - 正则表达式 - 仅获取文本/数字和额外
- reactjs - 我可以使用默认操作弹出窗口更改 chrome 扩展的位置吗?