为了账号安全,请及时绑定邮箱和手机立即绑定

移动圆弧上出现半径线

移动圆弧上出现半径线

牛魔王的故事 2023-08-05 21:04:53
我试图创建这些移动的形状,该形状由半圆形和对称的上弧和下弧组成。它们应该只是前面的形状,但现在当它们移动时,后面会拖着一条像尾巴一样的线。 这些线似乎来自上下弧的 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();    }
查看完整描述

1 回答

?
MMTTMM

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();


  }

}


查看完整回答
反对 回复 2023-08-05
  • 1 回答
  • 0 关注
  • 65 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信