使用canvas繪製dribble風格水波浪

先放一張簡單的效果圖


傳送門html

😔原理

sin函數估計你們都會,用到的公式爲amplitude * sin(frequency * x) + displacement函數

咱們能夠經過改變函數的振幅和頻率來達到控制曲線動畫。動畫


😈開始

定義一個Wavethis

```

class Wave {rest

  constructor(color) {
    this.t = 0;
    this.step = w / 300;
    this.color = color;
    this.speed = 0.1;
    this.a = 30;
    this.f = 20;
    this.d = 20;
  }
  caculate(x) {
    this.amplitude = this.a;
    this.frequency = this.f * (1 / w);
    this.displacement = this.d;
    // A*sin(Bx + C) + D
    return (
      this.amplitude * Math.sin(this.frequency * x + this.t) + this.displacement
    );
  }
  render() {
    this.t += this.speed;
    ctx.save();
    ctx.beginPath();
    ctx.translate(0, h / 2);
    ctx.lineWidth = 1;
    ctx.moveTo(0, 0);
    for (let i = this.step; i < w; i += this.step) {
      ctx.lineTo(i, this.caculate(i));
    }
    ctx.lineTo(w, this.caculate(w));
    ctx.lineTo(w, h);
    ctx.lineTo(0, h);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
    ctx.restore();
  }
}
```

這裏面沒有什麼特別的魔法,很容易就可以畫出一條波浪。
code

傳送門cdn

可是稍微有點感受的人就會發現整個動畫特別僵硬,就像是一張圖片在作平移同樣。做爲一個有理想的人怎麼能夠忍。htm


😄改進

很容易發現讓人以爲僵硬的緣由是波浪的波峯一直是這麼高,若是能讓波峯的大小也隨着改動的畫就OK了。blog

添加一點小小的細節,定義一個this.k的值,而後修改圖片

this.amplitude = this.a;

改成

this.amplitude = this.a * sin(((this.t / this.k) * this.k) / 5);

看到這裏你可能會好奇這迷同樣的函數怎麼來的,咱們的目標是讓振幅也跟着變更,因此就乘以了一個sin函數來讓振幅也能夠高高低低變化。


🐔最後

案例簡單實現


傳送門


參考連接

codepen.io/waynecz/pen…

dribbble.com/shots/36529…

dribbble.com/shots/37814…

相關文章
相關標籤/搜索