【笔记】WAAPI动画
Sep 8, 2019笔记js动效WAAPI动画
Web Animations API,WAAPI 允许同步和定时更改网页的呈现, 即DOM元素的动画。它通过组合两个模型来实现:时序模型 和 动画模型。
概念
WAAPI将浏览器动画引擎向开发者打开,并由JavaScript进行操作。这些API被设计成 CSS Animations and CSS Transitions的接口,未来会对这些API做补充以丰富更多的功能。它是对网络上动画化的支持最有效的方式之一,让浏览器进行自己的内部,不需要hacks,或者强迫,或者Window.requestAnimationFrame()。
通过Web动画API,我们可以将交互式动画从样式表移动到JavaScript,将表现与行为分开。 我们不再需要依赖DOM重的技术,如将CSS属性和范围类写入元素来控制播放方向。 与纯粹的声明式CSS不同,JavaScript还允许我们动态地将属性值设置为持续时间。 对于构建自定义动画库和创建交互式动画,WAAPI可能是完成工作的完美工具。
性能表现
WAAPI 有着和 CSS 动画一样的性能表现,虽然这不意味着你可以毫无顾忌的使用动画。
从CSS动画过渡到WAAPI
假如我们有这样一个css动画:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17.a-demo {
animation: demorun infinite 3s linear;
}
@keyframes demorun {
0% {
color: #000;
transform: rotate(0) translate3D(-50%, -50%, 0);
}
30% {
color: #431236;
}
100% {
color: #000;
transform: rotate(360deg) translate3D(-50%, -50%, 0);
}
}
动画很简单,接着改为WAAPI:
首先要做的是创建一个对应于我们的CSS @keyframes
块的关键帧对象1
2
3
4
5var demoTumbling = [
{ transform: 'rotate(0) translate3D(-50%, -50%, 0)', color: '#000' },
{ color: '#431236', offset: 0.3},
{ transform: 'rotate(360deg) translate3D(-50%, -50%, 0)', color: '#000' }
];
这里我们使用一个包含多个对象的数组。 每个对象代表原始CSS中的一个键。 然而,与CSS不同,Web动画API不需要明确地告知每个键出现的动画的百分比。 它将根据您给出的按键数量自动将动画划分为相等的部分。
当我们想要明确地设置一个键与其他键的偏移量时,我们可以直接在对象中指定一个偏移量,并与逗号分隔。如上第2个键。
注意,必须至少指定两个关键帧(表示动画序列的开始和结束状态).如果您的关键帧列表只有一个条目, Element.animate() 将抛出不支持的异常报错.
接着,创建表示时间属性1
2
3
4var demoTiming = {
duration: 3000,
iterations: Infinity
}
它与CSS的表示有所差异:
- 持续时间是毫秒ms,而不是秒s
- 线性方式是easing,而不是animation-timing-function
- 播放次数是iterations, 而不是 animation-iteration-count
最后,整合这些特性1
2
3
4document.getElementById("demo").animate(
demoTumbling,
demoTiming
)
即:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<p id="demo" style="width: 70px; height: 70px; background-color: red">123</p>
<script>
var demoTumbling = [
{ color: 'blue', transform: 'rotate(0) translate3D(-50%, -50%, 0)' },
{ color: '#fff' },
{ color: 'red', transform: 'rotate(360deg) translate3D(-50%, -50%, 0)' },
];
var demoTiming = {
duration: 3000,
iterations: Infinity
};
var animate = document.getElementById('demo').animate(demoTumbling, demoTiming);
console.log(animate)
</script>
上面定义将返回一个Animation对象。其中Element.animate()中时间属性可以为Number。
Animation构造函数
语法1
var animation = new Animation(effect, timeline);
其中:
- effect: 可选。
将KeyframeEffect对象分配给动画。(在将来,其他类型的效果,如SequenceEffects或GroupEffects是可能被实现的,但现在,唯一的效果是KeyframeEffect。) - timeline: 可选。
指定与动画关联的时间轴。默认为Document.timeline。 这也可以设置为null。
如:1
var rabbitDownAnimation = new Animation(rabbitDownKeyframes, document.timeline);
Animation实例属性
- Animation.currentTime:动画的当前时间值(以毫秒为单位),无论是正在运行还是已暂停。 如果动画缺少timeline或尚未播放,其值为null。
- Animation.effect:实验属性,
获取或设置与此动画相关联的KeyframeEffect。 - Animation.finished: 实验属性,只读。返回此动画的当前完成的状态。
- Animation.id。获取或设置用于标识动画的字符串。
- Animation.playState: 只读。返回描述动画播放状态的枚举值。
- Animation.playbackRate:返回或设置动画的播放速率。
- Animation.ready:实验属性,只读。返回此动画的当前就绪状态。
- Animation.startTime:获取或设置动画播放应开始的预定时间。
- Animation.timeline:实验属性。获取或设置与此动画相关联的timeline。
Animation实例事件处理
- Animation.oncancel:实验事件,获取并设置取消事件的事件处理程序。
- Animation.onfinish:实验事件,获取并设置完成事件的事件处理程序。
Animation方法
- Animation.cancel():实验方法,清除此动画的所有keyframeEffects,并中止播放。
- Animation.finish():实验方法,设置动画中止播放。
- Animation.pause():实验方法,暂停播放动画。
- Animation.play():实验方法,开始或恢复播放动画,或者如果之前完成,则重新开始动画。
- Animation.reverse():实验方法,反转播放动画,直到播放到动画开始时停止。 如果动画完成或未播放,它将从头到尾播放。
具体兼容情况请见后文。
动画控制
将CSS动画转为js并不是WAAPI最强大的地方,它真正厉害的是操纵动画的播放。Web动画API提供了一些控制播放的有用方法:play(),pause(),reverse()和playbackRate。
暂停pause()和启动play()
假如我们定义了这样一个动画1
2
3
4
5
6
7
8
9var demoAnimate = document.getElementById('demo').animate(
[
{ transform: 'translateY(0)' },
{ transform: 'translateY(-80%)' }
], {
fill: 'forwards',
easing: 'steps(4, end)',
duration: aliceChange.effect.timing.duration / 2
});
Element.animate() 方法会在调用后立即执行。不过我们可以通过调用 Animation.pause()暂停动画。1
demoAnimate.pause();
然后我们可以在我们想播放的时候调用Animation.play()播放动画。1
demoAnimate.play();
其他控制方法
除了暂停和播放,我们可以使用以下动画方法:
- Animation.finish() 动画结束.
- Animation.cancel() 终止动画.
- Animation.reverse() 设置动画播放速度
- Animation.playbackRate,控制动画播放速率,负值可将动画倒放。如
animate.playbackRate = -1
兼容情况
原生WAAPI的兼容情况很是不好,如图所示
现在也有个页面可以用来检测当前浏览器环境WAAPI各属性方法的兼容情况:https://codepen.io/danwilson/pen/xGBKVq/
不兼容的环境下使用WAAPI
现在已经有完善的polyfill-web-animations-js,使得我们现在可以在生产环境下使用它。
使用非常简单,如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<!-- Include the polyfill -->
<script src="web-animations.min.js"></script>
<!-- Set up a target to animate -->
<div class="pulse" style="width: 150px;">Hello world!</div>
<!-- Animate! -->
<script>
var elem = document.querySelector('.pulse');
var animation = elem.animate({
opacity: [0.5, 1],
transform: ['scale(0.5)', 'scale(1)'],
}, {
direction: 'alternate',
duration: 500,
iterations: Infinity,
});
</script>
当然,在不支持WAAPI的浏览器上动画的执行是通过DOM,这样的性能不如CSS3动画。
其他
个人目前WAAPI的优势还不是很明显,主要是兼容的原因,其次CSS动画的控制问题我们也可以通过DOM操作弥补。不过作为较为新兴的API我们可以实现了解。WAAPI的动画控制很像视频控制或者是lottie,个人认为统一的控制形式会受到更多开发者的支持。
Author
My name is Micheal Wayne and this is my blog.
I am a front-end software engineer.
Contact: michealwayne@163.com