关于使用Canvas绘制动画并使用requestAnimationFrame解决动画函数重绘问题
两个重点:
1 Canvas绘制动画思路:
canvas绘制动画的核心原理就是:
一个一个的绘制, 所以是通过循环绘制来完成动画的效果的,
我们需要做的就是, 在一次循环中, 清空上一次绘制留下的残影, 然后改变(确定)需要绘制对象(所有的对象)的位置和样式, 然后将对象绘制出来,
总之就是, 逻辑的改变应该在绘制之前, 一次循环应该改变了所有的对象的展示效果
对于持久不变的元素, 可以选择不擦除, 让它一直保留在其原位置即可
元素的运动是通过在绘制的时候不断变换位置所造成的视觉假象而已
结合reqeustAnimationFrame函数会造成很nice的炫酷动画效果
以后绘制动画的思路就是:
(1) 元素分类, 确定那些是相同元素, 相同的元素具有相同的绘制原理
(2) 确定单类元素变换规则, 同类元素是相同的变换规则, 只不过是不同的单个元素具有不同的变换参数而已
(3) 确定不同类元素之间的绘制顺序
(4) 确定好一类元素的变换逻辑后, 确定最终展示状态, 就首先将这些元素绘制出来, 同理执行下一类元素
(5) 注意: 能看见的东西 , 就是一个元素
2 requestAnimationFrame函数使用原理:
基础使用参见MDN
使用时遇到的问题:
(1) 发现requestAnimationFrame使用时存在递归调用的问题, 后来得以明白, reqeustAnimationFrame可以理解为执行一次传入的函数参数(只执行一次), 并不是传入一个函数参数就会每秒执行60次
至于能够每秒执行60次是因为reqeustAnimationFrame在函数中递归调用, 按理说递归调用很快很快, 肯定不止每秒60次, 所以这就是reqeustAnimationFrame控制帧率的厉害之处
不过如果一直递归调用, 肯定会导致栈溢出, 所以, 估计requestAnimationFrame在执行函数参数的时候会清空上一个函数栈, 又是一个厉害之处
不用感觉是一个递归调用然后担心requestAnimationFrame的位置, 其实, 不管requestAnimationFrame()写在一个函数中的哪个位置, 当传入requestAnimationFrame执行时, 此函数都会执行完所有函数中的语句
所以, 这是一个假递归, 有递归的一些特点. 但是对于底层实现仍然不解, 不知道会不会反复开辟栈空间
1 function test() { 2 console.log("这里会运行") 3 requestAnimationFrame(test) 4 console.log("这里也会运行") 5 } 6 test()