| 技术上没太大难度,有难度的地方是怎么让整个动画比较流畅。一个主要问题是动画的滞后性:当下载进度到某个点的时候,你再用250ms的动画过渡过去,这个时候已经慢了,所以很多人可能因为这个原因或者嫌麻烦,直接就不做动画了,在进度事件触发的时候直接更新进度条相应的位置,不过我们可以尝试实现一下。 最后做出来的效果如下图所示: 小狗奔跑的动画是一个lottie动画,来自codepen。 1. 获取下载进度ajax里面可以拿到下载进度,如下代码所示: [JavaScript] 纯文本查看 复制代码
![]() 一般CDN都会有这个字段。拿到下载进度之后便可用来换算宽度或者位置。 2. 没有动画的loading如果我们不做动画,直接设置translate位置,那么看起来是这样的: 代码如下所示: [JavaScript] 纯文本查看 复制代码
3. 加上transform动画transform动画怎么做呢?方法有很多:jQuery的animate、Web Animation、requestAnimationFrame、CSS动画结合JS控制、其它第三方动画库等等,我比较喜欢用原生Web Animation。 由于progress event触发得比较快,加上做动画的话不需要触发得那么快,所以给它加一个节流。如下代码所示: [JavaScript] 纯文本查看 复制代码
做transform动画的逻辑便在上面的onDownloadProgress这个函数里面处理,如下代码所示: [JavaScript] 纯文本查看 复制代码
另外,由于我们使用了节流很可能会导致最后的那次100%的触发丢了,所以需要在完成的时候手动调一下onProgressDownload,否则会没有完成态。 如果是播放进度条的例子,需要监听video/audio元素的timeupdate事件,这个事件的触发约250ms(实测)触发一次,可以不用节流。 效果如下图所示: 我们发现在最后数字已经显示总大小了即已经下载完成了,但是那条狗离终点还有段距离,在我们这个例子似乎没那么明显,不仔细看还看不太出来。但如果下载速度很快的时候这个问题会更加明显,在播放进度条的例子便是如果进度条很长,但是播放的视频只有10几秒,那么应该也会比较明显。 一个简单的解决方法是假定下一个250ms的下载速度保持一致,每次运动的时候都提前运动250ms,如果在播放video的例子里面这个假定几乎是对的,因为比较匀速,而下载速度不可控,但在连续相同很短的时间内我们估且认为是一样。 所以我们可以记录一下上一次的位置,然后加多一个偏移,如下代码所示: [JavaScript] 纯文本查看 复制代码
这个案例到这里基本就介绍结束,这个例子比较简单,不过你可能会觉得web animation的兼容性不太好。主要是在Chrome的兼容性比较好,其它主流的浏览器的新版本也已经开始支持了。其它不支持的浏览器可以使用谷歌官方的一个polyfill,就是比较大一点。它和CSS动画一样,但是可以用JS去控制开始暂停等,所以它和CSS动画一样具有GPU加速,不占用JS线程等优势。 链接:https://juejin.cn/post/6844903862009069575 |


