先放一張簡單的效果圖

傳送門html
😔原理
sin函數估計你們都會,用到的公式爲amplitude * sin(frequency * x) + displacement
函數
咱們能夠經過改變函數的振幅和頻率來達到控制曲線動畫。動畫
😈開始
定義一個Wave
類this
```
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…