![4b3b805e843c18da45789fd71d392a5d.png](https://img-blog.csdnimg.cn/img_convert/4b3b805e843c18da45789fd71d392a5d.png)
简单的介绍
说到屏保,想必大家都很熟悉,它就是有动画构成的,或简单,或复杂。
但是,今天我们不仅要做出动画,而且还要让其有些“温度”,能与我们进行互动。
好吧,让我们先来看一些demo:(没有移入鼠标时)
![8f3b2b7211b1b92765bb0d41608c1dd2.png](https://img-blog.csdnimg.cn/img_convert/8f3b2b7211b1b92765bb0d41608c1dd2.png)
加载的时,画布上会出现一定数量的小圆圈,有大有小,不断在画布上移动。
当鼠标移入时:
![cf0aab973a003bb3ec7887f2deafab57.png](https://img-blog.csdnimg.cn/img_convert/cf0aab973a003bb3ec7887f2deafab57.png)
当用户鼠标移入画布,在鼠标范围内的小圆形会逐渐被“放大”到一定值;当圆圈移出鼠标位置时候,会恢复到原来的状态。
那么让我们用Canvas来实现吧。
获取画布
首先我们先获取html中的canvas元素,并对其设置:
document
了解arc
![3055501716c2ac54c64f340c4bcb6b9d.png](https://img-blog.csdnimg.cn/img_convert/3055501716c2ac54c64f340c4bcb6b9d.png)
center point中心点,也就是弧度绘制产生的圆心,也就是坐标x值与y值的相交点;
radius 为弧度半径;
startAngle 起始的弧度;
endAngle 结束的弧度;
anticlockwise false时为顺时针绘制定义的弧度,true为逆时针绘制。
由此可以看出绘制一个圆形startAngle->endAngle 的参数应是0PI->2PI(π);
以上就是对arc(x, y, radius, startAngle, endAngle , anticlockwise),参数的了解。
从0-1
我们定义一个Circle构造函数,包括:
- draw函数依赖arc弧度画圆。
- update函数对所画圆形运动轨迹的约束。
我们在draw函数内使用arc绘制好了圆形,其所依赖的属性都被赋值到Circle私有属性。通过update函数对draw函数进行了约束,使得draw函数按照我们的逻辑绘画。
//声明Circle函数依赖的全局变量
以上我们定义了圆形的最大半径,最小半径(没有进行赋值),存放5个颜色的数组支持Circle中的color属性。
function
通过uptate我们对圆形的运动进行限制:
![07cce78bf85e6b42f49e00287938cefe.png](https://img-blog.csdnimg.cn/img_convert/07cce78bf85e6b42f49e00287938cefe.png)
如图所示,
- 一个圆运动,就是要控制center point的位置(x,y);
- 圆心cp在画布x轴的移动极限为W-R,且圆自左向右运动x轴的数值会不断增大;
- 圆心cp在画布y轴的移动极限为H-R,且圆自上而下运动y轴的数值会不断增大。
我们用偏移量dx,dy,控制W-R,H-R的数值大小变化,也就是构造函数Circle中x,y的极限距离。
绘制多个圆形实例
我们通过init函数中的循环来设置生成的Circle实例数量,然后追加到数组中。
var
function
requestAnimationFrame帧动画接口:
现在我们需要依赖requestAnimationFrame使得我们的圆形动起来,
因为计时器setTimeout 以及 setInterval有些问题:
- 间隔时间不精确,可能被阻塞。计时器的间隔指的是将回调函数推入任务队列的间隔时间,任务队列中的任务只有在主线程任务执行完毕后才会被执行。
- 计时器动画的间隔时间如果设定过短就会出现过度渲染占用大量资源,如果设定过长就会影响动画的流畅度。只能够估计合适的时间间隔。
- 多数浏览器对于计时器动画没有优化。
所以我们使用requestAnimationFrame渲染动画,需要处理浏览器的兼容性,我们先看一下各浏览器兼容情况:
![4af231ba51718b6a901904ffaded5fa6.png](https://img-blog.csdnimg.cn/img_convert/4af231ba51718b6a901904ffaded5fa6.png)
处理requestAnimationFrame兼容性:
//采用IIFE,处理requestAnimationFrame兼容性
加入鼠标交互
现在我们在update中加入鼠标移入规则,为生成的圆形加入动画交互,鼠标移入圆形运动范围内,使得圆不断变大,当圆移动到鼠标之外圆形变小。
//当鼠标移入到x,y圆心的±40的时候
当然这时候我们需要注册一个鼠标移入的事件:
//添加mouse全局变量方便记录mousemove事件中的x,y。
注册全局mousemove事件来实时获取浏览器中鼠标的位置x,y
window
我们打印下当鼠标移入到浏览器窗口时候,mouse.x与y实时记录的鼠标坐标,加深下印象:
![dad2a6abca60df8c9ba30bcd4c4f3ca9.png](https://img-blog.csdnimg.cn/img_convert/dad2a6abca60df8c9ba30bcd4c4f3ca9.png)
完善动画
注册全局resize事件,当浏览器窗口大小改变的时候,将浏览器的可视范围宽高赋值给画布的宽高。
window
思考总结
从0-1我们做了什么:
- 首先我们了解arc方法支撑我们绘制圆形;
- 然后通过Circle函数中的draw方法调用画布arc方法绘制了圆形;
- 通过animate方法中的requestAnimationFrame不停的调用自己完成了动画;
- 通过update方法进行了动画约束,包括圆运动范围规则,鼠标交互规则的定义;
- 当然我们也做了requestAnimationFrame的兼容性,使我们的程序更加健壮。
拓展延伸:但是细心的你会发现我们使用mousemove事件的时候,鼠标在画布上的值会被实时存放到mouse对象中,触发事件的频率很高,这样也就影响到了我们动画执行时候的性能,我们该如何解决呢?
下一个篇文章,我们将开始绘制wifi信号,请持续关注。