JavaScript的动画requestAnimationFrame

188 阅读3分钟

这是我参与2022首次更文挑战的第25天,活动详情查看:2022第一次更文挑战

前言:

图形和动画已经日益成为浏览器中现代 Web 应用程序的必备功能,但实现起来仍然比较困难。视 觉上复杂的功能要求性能调优和硬件加速,不能拖慢浏览器。目前已经有一套日趋完善的 API 和工具可 以用来开发此类功能。毋庸置疑,是 HTML5 最受欢迎的新特性。这个元素会占据一块页面区域,让 JavaScript可以动态在上面绘制图片。最早是苹果公司提出并准备用在控制面板中的,随着其他浏览器的迅速跟进,HTML5 将其纳入标准。目前所有主流浏览器都在某种程度上支持元素。与浏览器环境中的其他部分一样,自身提供了一些 API,但并非所有浏览器都支持这些 API,其中包括支持基础绘图能力的 2D 上下文和被称为 WebGL 的 3D 上下文。支持的浏览器的最新版 本现在都支持 2D 上下文和 WebGL。

一、使用 requestAnimationFrame

很长时间以来,计时器和定时执行都是 JavaScript 动画最先进的工具。虽然 CSS 过渡和动画方便了 Web 开发者实现某些动画,但 JavaScript 动画领域多年来进展甚微。Firefox 4 率先在浏览器中为 JavaScript 动画增加了一个名为 mozRequestAnimationFrame()方法的 API。这个方法会告诉浏览器要执行动画 了,于是浏览器可以通过最优方式确定重绘的时序。自从出现之后,这个 API 被广泛采用,现在作为 requestAnimationFrame()方法已经得到各大浏览器的支持。

1.1 早期定时动画

以前,在 JavaScript 中创建动画基本上就是使用 setInterval()来控制动画的执行。下面的例子展 示了使用 setInterval()的基本模式: (function() { function updateAnimations() { doAnimation1(); doAnimation2(); // 其他任务 } setInterval(updateAnimations, 100); })();

1.2时间间隔的问题

知道何时绘制下一帧是创造平滑动画的关键。直到几年前,都没有办法确切保证何时能让浏览器把 下一帧绘制出来。随着的流行和 HTML5 游戏的兴起,开发者发现 setInterval()和 setTimeout()的不精确是个大问题。 浏览器自身计时器的精度让这个问题雪上加霜。浏览器的计时器精度不足毫秒。以下是几个浏览器 计时器的精度情况:  IE8 及更早版本的计时器精度为 15.625 毫秒;  IE9 及更晚版本的计时器精度为 4 毫秒;  Firefox 和 Safari 的计时器精度为约 10 毫秒;  Chrome 的计时器精度为 4 毫秒。 IE9 之前版本的计时器精度是 15.625 毫秒,意味着 0~15 范围内的任何值最终要么是 0,要么是 15, 不可能是别的数。IE9 把计时器精度改进为 4 毫秒,但这对于动画而言还是不够精确。Chrome 计时器精度是 4 毫秒,而 Firefox 和 Safari 是 10 毫秒。更麻烦的是,浏览器又开始对切换到后台或不活跃标签页中的计时器执行限流。因此即使将时间间隔设定为最优,也免不了只能得到近似的结果。