直入正题,很多人把 step-end / step-start 说的云里雾里的,其实作用非常简单。
有关他们的作用,先看一例:
HTML
<div class="box-origin"></div> <div class="box"></div> <div class="time"></div>CSS
body { height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; } .box, .box-origin { width: 40px; height: 40px; border-radius: 50%; background-color: #333; animation-iteration-count: infinite !important; } .box { animation: sizeExpan 2s step-end; margin-left: 20px; } .box-origin { animation: sizeExpan 2s; } @keyframes sizeExpan { 50% { height: 70px; } } .time { margin: 20px; font-weight: bold; position: absolute; right: 280px; }效果
上图左边是不含 step-end 的,右边是含 step-end 的。
也就是说,step-end 会使 keyframes 动画到了定义的关键帧处直接突变,并没有变化的过程。
文中是 2s 的动画,在 50% 也就是 1s 时我们期望他的高度增长,不带 step-end 的就会有高度增长的过程,而带有 step-end 的就会在 1s 时突然变为关键帧定义的状态,没有变化过程。
step-start 同理,按本文例子来说,如果带上 step-start ,那么在 0% 刚开始的时候就已经变成了 50% 时的状态。
请看一例:
HTML
<div class="circle"></div>JS
CSS.registerProperty({ name: '--color1', syntax: '<color>', initialValue: 'transparent', inherits: true }); CSS.registerProperty({ name: '--color2', syntax: '<color>', initialValue: 'transparent', inherits: true }); CSS.registerProperty({ name: '--pos', syntax: '<length-percentage>', initialValue: '0', inherits: true })普通的 css 变量是不可以发生渐变过程的,只能突变,为了使 css 变量也能有变化过程(在 animation 内),需要使用 CSS.registerProperty() 定义 可变化的 css 变量。
MDN:CSS.registerProperty()
其中:
name :css 变量名syntax :css type 类型,全部可取值见 CSS data types 下的 PropertiesinitialValue :变量的初始值inherits :是否可继承CSS
body { height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; } .circle { --color1: #333; width: 100px; height: 100px; background: conic-gradient(var(--color1) var(--pos), var(--color2) 0); border-radius: 50%; animation: circle1 1s linear, circle2 2s step-end, circle3 2s step-end; animation-iteration-count: 2; } @keyframes circle1 { to { --pos: 100%; } } @keyframes circle2 { 50% { --color1: transparent; } } @keyframes circle3 { 50% { --color2: #333; } }效果
首先,我们定义了最长时长为 2s 的 animation 。
在第 1s 内,锥形渐变百分比由 0 -> 100% ,颜色是 --color1 所定义的 #333 ,进度是由 --pos 定义的百分比值,只有使用 CSS.registerProperty() 定义的 css 变量才能发生过程渐变!(也就是此处的 --pos 从 0 -> 100%)
在第 1s 时,到了触发 circle2 和 circle3 这两个动画的关键帧了,由于 step-end 的特性,只在定义的关键帧处突变,于是在 1s 时 --color1 和 --color2 发生了突变交换,单这并不影响视图显示。
不影响视图的原因是,在 1s 之前,锥形渐变的 #333 颜色进度是由 --color1 产生的,此时 --color2 是 transparent ,到了 1s 时,由于没有定义 forwards 保持动画后的状态,--pos 回复到最初 0 的状态,而此时 --color1 又和 --color2 发生了突变交换,所以相当于反过来了(此时进度是透明的,为 0)
接上文,由于此时进度是 transparent ,而且定义了 animation-iteration-count: 2; ,也就是 1s 的动画 circle1 会再运行一次,推动 transparent 的 --color1 填充满整个圆。
到此为止,animation 结束。
可见 step-end 突变错位的特性,配合可以变化的 css 变量,可以做到意想不到的效果。
我们可以联想到,假设有两个 @keyframes 动画,分别为 key-1 和 key-2 :
我们把 key-1 作为执行流畅的动画(也就是可以变化的 css 变量或者属性)
把 key-2 作为切换流程,采用 step-end 只在指定的关键帧处改变一些 css 变量,从而影响到 key-1 的变化,根据时长定义的不同,key-2 可以很长,key-1 由于 css 变量改变展示不同的状态!