【问题标题】:Radius Line Appears on Moving Arc移动圆弧上出现半径线
【发布时间】:2021-02-27 17:16:10
【问题描述】:

我试图创建这些移动的形状,形状由半圆和对称的上弧和下弧组成。 它们应该只是前面的形状,但现在它们移动时有一条像尾巴一样拖在后面的线。 The output shape with unknown tail

似乎这些线来自上下弧的 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();

    }

【问题讨论】:

    标签: javascript html animation canvas


    【解决方案1】:

    这是因为arc 方法在内部跟踪lineTo 从当前指针的位置到圆弧的起点(由 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();
    
      }
    }

    【讨论】:

    • 终于明白那里是怎么回事了!非常感谢您的解释!! >
    猜你喜欢
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    相关资源
    最近更新 更多