canvas三角函数模拟水波效果的示例代码

2019-01-28 21:05:26王振洲

最近项目中,ui设计了个水波效果的背景动画,然而并没有gif或svg动画,开始试着用css实现了一下,动画效果并不是很好,网上查了下基本都是用贝赛尔曲线实现,想起以看的各种前波形图,于是想着用三角函数图像初略模拟一下

一、绘制sin函数图像

sin函数表达式如下,

y=Asin(wx+φ)+h

其中 A表示振幅,ω表示角频率(ω=2π/T,T为函数的周期),φ表示初相,h表示图像向y轴正方向平移的长度 ;(这里需要注意一下:h在数学学的本来是表示向上平移的,但在canvas中采用的是屏幕坐标系,即左上角为原点,h则表示向下平移);

绘制代码如下:

(1)添加canvas标签

<canvas id="canvas"></canvas>

(2)添加css样式,设置canvas宽高

html, body { padding: 0; margin: 0; width: 100%; height: 100%; } canvas { width: 100%; height: 100%; }

(3)绘制函数图像

var canvas = document.getElementById("canvas"), ctx = canvas.getContext('2d'), width = canvas.width = canvas.offsetWidth, height = canvas.height = canvas.offsetHeight; //声明参数 var A=50, W=1 / 50, Q=0, H= height / 2; //绘图方法 (function draw(){ ctx.clearRect(0, 0, width, height);//清空画布 ctx.beginPath(); //开始路径 ctx.strokeStyle="#000"; //设置线条颜色 ctx.lineWidth = 1; //设置线条宽度 ctx.moveTo(0, height /2); //起始点位置 for (let x = 0; x <= width; x++) {// 绘制x对应y的 var y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //绘制路径 ctx.closePath(); //闭合路径 })()

这样我们可以得到以下图像:

二、为函数图像添加动画

上面得到的是是一个静态的函数图像,而我们一般见到的的波形图或水波都是随时间连续变化的,这里就要用到上一步中的参数相位φ,(js即代码中的Q) ,我们将φ随时间不断增加或减小,即可得到不同时间的不同图像;使用window.requestAnimationFrame实现帧动画;

修改以上代码为:

var canvas = document.getElementById("canvas"), ctx = canvas.getContext('2d'), width = canvas.width = canvas.offsetWidth, height = canvas.height = canvas.offsetHeight; //声明参数 var A=50, W=1 / 50, Q=0, H= height / 2; //绘图方法 (function draw(){ ctx.clearRect(0, 0, width, height);//清空画布 ctx.beginPath(); //开始路径 ctx.strokeStyle="#000"; //设置线条颜色 ctx.lineWidth = 1; //设置线条宽度 ctx.moveTo(0, height /2); //起始点位置 for (let x = 0; x <= width; x++) {// 绘制x对应y的 var y = A*Math.sin(W*x+Q) +H ctx.lineTo(x, y) } ctx.stroke(); //绘制路径 ctx.closePath(); //闭合路径 })()