【问题标题】:Animating a section of a path using canvas使用画布为路径的一部分设置动画
【发布时间】:2016-08-27 01:59:02
【问题描述】:

我正在尝试使用画布为路径的一部分设置动画。基本上我有一条贯穿三个链接的直线。当您将鼠标悬停在链接上时,链接后面的路径部分应动画为正弦波。

我可以将整条路径动画成正弦波的形状,但在动画部分路径时,我不知所措:(

我在下面附上了一张参考图片,以说明我想要实现的目标。

下面是我目前用来为路径设置动画的代码的 jsfiddle。我是一个画布菜鸟,如果它很糟糕,请原谅我......

https://jsfiddle.net/9mu8xo0L/

这里是代码:

class App {

      constructor() {

        this.drawLine();

      }

      drawLine() {

        this.canvas = document.getElementById('sine-wave');
        this.canvas.width = 1000;

        this.ctx = this.canvas.getContext("2d");
        this.cpY = 0;
        this.movement = 1;
        this.fps = 60;

        this.ctx.moveTo(0, 180);
        this.ctx.lineTo(1000, 180);
        this.ctx.stroke();

        this.canvas.addEventListener('mouseover', this.draw.bind(this));

      }

      draw() {

        setTimeout(() => {

          if (this.cpY >= 6) return;

          requestAnimationFrame(this.draw.bind(this));

          // animate the control point
          this.cpY += this.movement;

          const increase = (90 / 180) * (Math.PI / 2);
          let counter = 0;
          let x = 0;
          let y = 180;

          this.ctx.beginPath();

          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

          for(let i = 0; i <= this.canvas.width; i += 6) {

            this.ctx.moveTo(x,y);

            x = i;
            y =  180 - Math.sin(counter) * this.cpY;

            counter += increase;

            this.ctx.lineTo(x, y);
            this.ctx.stroke();

          }

        }, 1000 / this.fps);

      }

    }

【问题讨论】:

    标签: javascript html animation canvas


    【解决方案1】:

    简单地将线条的绘制分成三部分,将 1/3 绘制为直线,为中间部分设置动画并添加最后的 1/3。

    我将演示第一个 1/3 + 动画并将最后一个 1/3 留作练习(还将 stroke() 移到循环之外,这样它就不会过度绘制每个片段) - 有重构的空间和这里的优化,但我没有在这个例子中解决这个问题 -

      let x = this.canvas.width / 3;   // start of part 2 (animation)
      let y = 180;
    
      this.ctx.beginPath();
    
      this.ctx.clearRect(0, x, this.canvas.width, this.canvas.height);
    
      // draw first 1/3
      this.ctx.moveTo(0, y);
      this.ctx.lineTo(x, y);
    
      // continue with part 2
      for(let i = x; i <= this.canvas.width; i += 6) {
        x = i;
        y = 180 - Math.sin(counter) * this.cpY;
    
        counter += increase;
    
        // add to 2. segment
        this.ctx.lineTo(x, y);
      }
    
      // stroke line
      this.ctx.stroke();
    

    Modified fiddle

    【讨论】:

    • 感谢@K3N 的快速回答。这就是我一直在寻找的,唯一的问题是这些部分不是无缝的。看看这个更新的小提琴,看看我的意思。这是我真的不确定...jsfiddle.net/9mu8xo0L/3
    • @Ashmore11 您可以将线延长到 2/3 并强制 y,然后在同一 y 处绘制最后一段。更新了小提琴:jsfiddle.net/epistemex/9mu8xo0L/4
    猜你喜欢
    • 1970-01-01
    • 2017-02-15
    • 2020-11-02
    • 2012-03-27
    • 2013-09-08
    • 2018-06-23
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多