2019年6月25日,W3C正式发布了首个关于CSS ANIMATION WORKLET API的工作草案。
Animation Worklet API 可以让开发者通过脚本的方式来实现一系列动画效果,并且这些动画效果是由一个单独的线程来处理的,不会占用主线程。
通常情况下,我们在网页中实现动画有下面两种方式:
- setTimeout 、setInterval、requestAnimationFrame
- CSS
第一种方式,代码都是在主线程运行的,容易阻塞主线程,造成掉帧等问题,影响用户体验。
第二种方式,CSS可以实现更流畅的动画,但是CSS代码写起来局限太多。
所以,Animation Worklet API诞生了。
来看一下W3C的示例代码:
// In document scope.<div id='scrollingContainer'> <div id='header' style='height: 150px'></div> <div id='avatar'><img></div></div> <script>await CSS.animationWorklet.addModule('twitter-header-animator.js');const animation = new WorkletAnimation( 'twitter-header', [new KeyframeEffect($avatar, /* scales down as we scroll up */ [{transform: 'scale(1)'}, {transform: 'scale(0.5)'}], {duration: 1000, iterations: 1}), new KeyframeEffect($header, /* loses transparency as we scroll up */ [{opacity: 0}, {opacity: 0.8}], {duration: 1000, iterations: 1})], new ScrollTimeline({ scrollSource: $scrollingContainer, orientation: 'block', timeRange: 1000, startScrollOffset: 0, endScrollOffset: $header.clientHeight}));animation.play(); // Since this animation is using a group effect, the same animation instance// is accessible via different handles: $avatarEl.getAnimations()[0], $headerEl.getAnimations()[0]</script>
// Inside AnimationWorkletGlobalScope.registerAnimator('twitter-header', class HeaderAnimator extends StatelessAnimator { constructor(options) { this.timing_ = new CubicBezier('ease-out'); } animate(currentTime, effect) { const scroll = currentTime; // scroll is in [0, 1000] range // Drive the output group effect by setting its children local times individually. effect.children[0].localTime = scroll; effect.children[1].localTime = this.timing_(clamp(scroll, 0, 500)); }}); function clamp(value, min, max) { return Math.min(Math.max(value, min), max);}
关于Animation Worklet API的更多内容,可到W3C查看: