图形与动画

195 阅读4分钟

这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

前言

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

使用 requestAnimationFrame

很长时间以来计时器和定时执行都是 Javascript 功画最先进的工具。虽然 CSs 过渡和动画方伸了
Web 开发老宓现某此动画,但 JavaScript 列画伙以多牛米进股甚微。 Firefox 4率先在浏览器中为 Java 动画增加了_个名为 mozRequestAnzmatIOnrTameO 力法的 APl 。这个方法会告诉浏览器要执行动画了,于基浏监瞿可以通过最优方式佣疋里后的明用。目从出现之后,这个 APl 被广泛采用、现在化 equestAnimationFrame ()方法已经得到各大浏览器的支持。

以前,在 JavaScript 中创建动画基本上就是使用 setInterval ()来控制动画的执行。下面的例子展示了使用 set Interval ()的基本模式:\

function (){
 function updateAnimations (){
doAnimation1();
doAnimation2(); 
 setInterval ( updateAnimations ,100);
)

注意点

作为一个小型动画库的标配,这个 updateAnimations ()方法会周期性运行注册的动画任务,并反映出每个任务的变化(例如,同时更新滚动新闻和进度条)。如果没有动画需要更新,则这个方法既可以什么也不做,直接退出,也可以停止动画循环,等待其他需要更新的动画。
这种定时动画的问题在于无法准确知晓循环之间的延时。定时间隔必须足够短,这样才能让不同的动画类型都能平滑顺畅,但又要足够长,以便产生浏览器可以渲染出来的变化。一般计算机显示器的屏幕刷新率都是60Hz,基本上意味着每秒需要重绘60次。大多数浏览器会限制重绘频率,使其不超出屏幕的刷新率,这是因为超过刷新率,用户也感知不到。
因此,实现平滑动画最佳的重绘间隔为1000毫秒/60,大约17毫秒。以这个速度重绘可以实现最平滑的动画,因为这已经是浏览器的极限了。如果同时运行多个动画,可能需要加以限流,以免17毫秒的重绘间隔过快,导致动画过早运行完。
虽然使用 setInterval ()的定时动画比使用多个 setTimeout ()实现循环效率更高,但也不是没有问题。无论 setInterval ()还是 setTimeout ()都是不能保证时间精度的。作为第二个参数的延时只能保证何时会把代码添加到浏览器的任务队列,不能保证添加到队列就会立即运行。如果队列前面还有其他任务,那么就要等这些任务执行元再执行。间单来讲,这里毫秒延时并不是说何时这此代码会执行,而只是说到时候会把回调加到任务队列。如来添加到队列后,主线程还被其他任务占用,比如正在处理用户操作,那么回调就不会马上执行