尚有一个就是,一旦我们这个 tick 写的欠好,setInterval 就有大概产生积存。因为它是牢靠 16 毫秒轮回执行的,所以 interval 之间是不会管上一个 interval 中的代码是否已经执行完,第二个 interval 的代码就会进入 interval 的行列。这个也是取决于欣赏器的底层实现,每一个欣赏器有大概选择差异的计策。
因为我们这里实现的动画库,不需要思量到旧欣赏器的兼容性。我们这里就选择利用 requestAnimationFrame。
接下来的时间轴库中,我们就会利用 requestAnimationFrame 来做一个自反复的操纵。
这里还要提到一个和 requestAnimationFrame 对应的一个 cancelAnimationFrame。假如我们声明一个变量来储存 requestAnimationFrame,我们就可以传入这个变量到 cancelAnimationFrame 让这个动画遏制。
let tick = () => { let handler = requestAnimationFrame(tick); cancelAnimationFrame(handler); }
这样我们就可以制止一些资源的挥霍。
实现 Timeline 时间轴开头我们讲过,在做动画的时候,我们就需要把 tick 这个对象给包装成一个 Timeline。
接下来我们就来一起实现这个 Timeline(时间轴) 类。正常来讲,我们一个 Timeline 只要 start(开始)就可以了,并不会有一个 stop(遏制)的状态。因为一个时间轴,必定是会一直播放到竣事的,并没有中间遏制这样的状态。
不外它是会有 pause(暂停) 和 resume(规复)这种组合。而这一组状态也是 Timeline 中很是重要的成果。好比,我们写了一大堆的动画,我们就需要把它们都放到同一个动画 Timeline 内里去执行,而在执行的进程中,我可以让所有这些动画暂停和规复播放。
别的就是这个 rate(播放速率),不外这个不是所有的时间线城市提供。rate 会有两种要领,一个是 set、一个是 get。因为播放的速率是会有一个倍数的,我们可以让动画快进、慢放都是可以的。
在设计这个动画库时,尚有一个很是重要的观念,叫 reset(重启)。这个会把整个时间轴清理清洁,这样我们就可以去复用一些时间线。
这个教程中实现的 set 和 get 的 rate 就不做了,因为这个是较量高级的时间线成果。假如我们要做这个就要讲许多相关的常识。可是 pause 和 resume 对付我们的 carousel(轮播图)是至关重要的,所以这里我们是必然要实现的。
讲了那么多,我们赶忙开工吧!~
实现 start 函数在我们的 start 要领中,就会有一个启动 tick 的进程。这里我们会选择把这个 tick 酿成一个私有的要领(把它藏起来)。否则的话,这个 tick 谁都可以挪用,这样很容易就会被外部的利用者粉碎掉整个 Timeline 类的状态体系。
那么我们怎么才气把 tick 完美的藏起来呢?我们会在 animation.js 这个文件的全局域中声明一个常量叫 TICK。而且用 Symbol 来建设一个 tick。这样除了在 animation.js 傍边可以获取到我们的 tick 之外,其他任那里所都是无法得到 tick 这个 Symbol 的。
同理 tick 中的 requestAnimationFrame 也同样可以建设一个全局变量 TICK_HANDLER 来储存。这个变量也会利用一个 Symbol 来包裹起来,这样就可以限定只能在本文件中利用。
对 Symbol 不是很熟悉的同学,其实我们可以领略它为一种 “非凡字符”。就算我们把两个传入 Symbol 的 key 都叫 ‘tick',建设出来的两个值城市是纷歧样的。这个就是 Symbol 的一个特性。
其实我们之前的《前端进阶》的文章中也有具体讲过和利用过 Symbol。好比,我们利用过 Symbol 来代表 EOF(End Of File)文件竣事标记。所以它作为工具的一个 key 并不是独一的用法,Symbol 这种具有独一特性,是它存在的一个意义。
有了这两个常量,我们就可以在 Timeline 类的结构函数中初始化 tick。
初始化好 Tick 我们就可以在 start 函数中直接挪用全局中的 TICK。这样我们 Timeline(时间线)中的时间就开始以 60 帧的播放率开始运行。
最儿女码就是如下: