60行代码,造一个动画库轮子 #98
zhangyu1818
announced in
zh-cn
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
JS
做动画的核心方法是什么,那就是requestAnimationFrame
,所以先来介绍一下它requestAnimationFrame
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行简单来说,可以把它理解为动画版的
setTimeout
,那为什么不用setTimeout
呢,因为在浏览器中,setTimeout
可能会因为种种原因导致不那么准确,而requestAnimationFrame
有一个特点是,它会尽量保持回调函数执行每秒执行60次(60fps),电脑卡除外使用方式
回调函数会接受一个参数,这个参数的值是当前的时间,和
performance.now()
相同可以看出来和
setTimeout
的使用方式基本相似,除了它的调用次数是有浏览器控制,而setTimeout
是时间参数控制开搞开搞
先看看要实现的效果
入口函数
既然有了
class
,那就用class
来写首先,它可以接受一个
options
对象作为参数,这个对象有2个值,element
值表示需要进行动画的元素,duration
表示动画持续时间把动画添加到动画队列
示例中,使用
.then
方法把动画添加进队列,所以需要添加一个then
方法这里有个非常重点的函数,就是
createKeyframes
,它直接关系到在requestAnimationFrame
中,该如何去解析我们的动画原理就是将数字和字符串拆分开,然后在
requestAnimationFrame
中计算数字,再和字符串组合上,赋值给元素的style
,所以现在来讲核心的实现createKeyframes的实现
先讲一下用到的方法
Object.entries
Object.entries
可以把对象转为数组形式split和match
split
方法可以把字符串根据正则拆分,match
则可以匹配正则的元素所以原理就是先使用
Object.entries
遍历对象,在将其中的值使用split
和match
方法转换出来,下面看方法的具体实现现在,已经成功可以把参数转换成动画需要的格式,接下来让动画跑起来
rAF函数的实现
rAF
就是requestAnimationFrame
的缩写嘛,在这个函数里,我们需要根据持续的时间,来计算当前动画的值是多少resumeStyles —— 将值还原为style格式的方法
resumeStyles
函数在整个流程中也是非常重要的,没有这个函数,就无法将值赋值给元素完成后的最终代码
代码量不大,逻辑不算复杂,不过需要注意的是我只在Chrome80里试了,Safari都不行,因为不支持类里的箭头函数,如果想要通用还是需要
bind
或者babel
主要的核心点在于
createKeyframes
和resumeStyles
这两个函数,如果能理解这2个函数是如何运行的,恭喜你,也有一个自己的动画轮子了还差点什么
大家都知道,在
CSS
里的动画,会有ease-out
,ease-in-out
这样的选项,现在我们的动画就是个纯线性,看着也怪怪得其实在我们这个轮子上添加这个很简单,只需要找到一个公式
公式接受一个数字参数,计算出相应的数值,有了它,动画就不再是线性啦
把它添加到我们的轮子
当传入
easing
参数后,动画表现就不一样了,有兴趣的同学可以试试总结
里面的核心动画方式,我都是从animateplus这个库里总结出来的,不过这个轮子的实现方式和它还是不同,并且我们的只能单元素动画,它支持更多的功能和效果,大家如果有兴趣可以去看看源码,只有400行
希望大家都能学会这里面的核心方法,再把它打包成自己的轮子,祝大家工作顺利
Beta Was this translation helpful? Give feedback.
All reactions