曲线的画法
canvas 提供了绘制二次贝塞尔曲线的方法
1 | quadraticCurveTo(x1,y1,x2,y2) |
其中(x1,y1)是控制点,(x2,y2)是结束点
在使用该方法之前需要设置起始点:
1 | contex.moveTo(x0,y0) |
流动的效果原理
如果你曾经制作过动画或者动态图,你应该了解动画的形成原理。即每个小的时间片的动作逐个播放,由于人大脑的反应是延后的,故这些小时间片的离散动作视觉上为一组连续的动作。这个小的时间片我们称为帧。在制作动画时,我们做好每帧的动作并使其连续播放即可。
线由连续的点组成,使小球沿着线的轨迹运动,并制作拖尾,可以实现线的流动效果。
小球运动实现
在根据贝塞尔曲线公式,计算每帧小球的位置坐标,连续重新绘制小球,实现canvas小球运动动画。二阶公式如下:
1 | B(t) = (1-t)^2 * P0 + 2 * t * (1-t) * P1 + t^2 * P2 |
三阶公式如下:
1 | B(t) = P0 * (1-t)^3 + 3 * P1 * t * (1-t)^2 + 3 * P2 * t^2 * (1-t) + P3 * t^3 |
每帧小球位置计算
计算小球运动起始位置和终止位置,均需根据经纬度坐标计算出屏幕坐标。
(x1,y1) 为起始位置,(x2,y2) 为控制点坐标,(x3,y3) 为终止位置。
(ox,oy) 为小球某一帧坐标,我们可以通过循环更改 t 来获取每一帧小球的位置,连续播放即为小球运动动画。
1 | var t = 0.01 |
拖尾效果实现
一个小球运动略显单薄,所以要制作小球拖尾效果,即小球运动过后的虚影。利用多个小球跟着第一个小球运动,后面的小球半径逐渐变小,透明度逐渐降低,每个小球的时间距离为2个帧。以下代码为设置小球渐变透明,位置的计算参考上一步代码。
1 | var linearGradient = ctx.createLinearGradient(fx,fy,tx,ty) |
使用循环不断重绘小球位置。
1 | ballruntimer = setInterval(function(){ |
注意
- 图层进行重绘时,关闭所有小球运动定时器,防止陷入死循环。
- 贝斯艾尔曲线控制点不是唯一的,可根据需要自行确定控制点计算公式。