steps属性有两个值,第一个值是设定每帧划分几个标记,取值是大于0的整数,数值越大过度越流畅;第二个值表示标记方式以及相邻帧标记如何跳转,取值为:jump-start、jump-end(默认值)、jump-none、jump-both
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
@keyframes run {
0% {
width: 100px;
}
25% {
width: 200px;
}
50% {
width: 300px;
}
75% {
width: 400px;
}
100% {
width: 500px;
}
}
div {
position: absolute;
width: 100px;
height: 100px;
background-color: #f00;
animation: run 8s steps(5, jump-end) infinite;
}
</style>
</head>
<body>
<div>
</div>
<script>
let div = document.querySelector('div')
let w = []
let t = []
const resizeObserver = new ResizeObserver((entries, b) => {
if (w.indexOf(div.clientWidth) < 0) {
let tt = new Date().getTime();
let czt = t.length > 0 ? tt - t[t.length - 1] : 0;
let czw = w.length > 0 ? div.clientWidth - w[w.length - 1] : 0;
w.push(div.clientWidth)
t.push(tt)
console.log(tt, div.clientWidth, czt, czw);
}
})
resizeObserver.observe(div)
</script>
</body>
</html>
上面代码中run动画共有4帧,每帧宽度增加100px,现在steps第一个值固定为5,分别来看第二个值的不同区别
jump-end:该值表示每帧从0%开始向后划分5等份标记,即每帧的0%、20%、40%、60%、80%处做上标记,运行代码后控制台输出如图:
steps(5, jump-end).png
第一项是时间戳,第二项是当前宽度,第三项是每个标记时间间隔,第四项是每个标记增值变化。
整个动画8秒,也就是每帧2秒,每帧5个标记,每个标记相差400毫秒,增值20px;但是最后的500却没输出,那是因为500是最后一帧在100%时的状态,而100%没有标记所以没有动画效果也就没有输出值;而会输出400,是因为这里的400是最后一帧在0%的标记,并不是第三帧100%的标记。
再举个极端的例子,把第一个参数改为1后输出如图:
steps(1, jump-end).png
参数为1意味着,给每帧的0%位置做标记,所以输出的四个数值分别是每一帧的起始值,如果能明白的话就继续往下看。
jump-start:该值和上面的反过来,每帧从100%开始向前划分5等份标记,即每帧的20%、40%、60%、80%、100%,运行后如图:
steps(5, jump-start).png
jump-end能理解的话,这个也能理解。
jump-none:该值表示每帧在包括0%和100%的情况下划分5等份标记,这就意味着如果取该值,那第一个参数最小值为2;例子中取5相当于:0%、25%、50%、75% 、100%五个标记,运行后如图:
steps(5, jump-none).png
每个标记都会输出,但每个标记都有停留时间,所以在上一帧的100%和下一帧的0%处会有双倍间隔。
jump-both:该值表示每帧在0%和100%之间格外划分5等份标记,即:0%,16.66%,33.33%,50%,66.66%,83.33%,100%,如图:
steps(5, jump-both).png
可以看到每个标记输出间隔相同,但0%和100%标记不输出,所以会从上一帧的83.33%直接变化到下一帧的16.66%,也就是双倍增值。