我有以下代码:
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('/media/anim.png');
float: left;
background-color: black;
animation: bganim 100ms steps(1, start) infinite;
}
@keyframes bganim {
from { background-position: 0px 0px; }
to { background-position: 0px -72px; }
}
但这部动画只播放一次。我做错了什么?
编辑:请注意,动画播放一次,因此存在视觉差异。但我希望动画循环
顺便说一句:这是我用过的图片:https://i.stack.imgur.com/wJcCl.png
第二版:这是代码片段
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('https://i.stack.imgur.com/wJcCl.png');
float: left;
background-color: black;
animation: bganim 100ms steps(1, start) infinite;
}
@keyframes bganim {
from { background-position: 0px 0px; }
to { background-position: 0px -72px; }
}
<div class="dangerous_b"></div>
第三版:现在使用以下代码:
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('https://i.stack.imgur.com/wJcCl.png');
float: left;
background-color: black;
animation: bganim 100ms steps(1, start) infinite;
}
@keyframes bganim {
50% { background-position: 0px -72px; }
}
原因:
问题是因为animation-timing-function
。值为steps(1,start)
意味着动画只有一个步骤,并且它正好发生在动画本身的开头。
根据MDN(从step-start
的定义中选取,但与steps(1, start)
相同):
使用此计时功能,动画立即跳到结束状态,并保持在该位置,直到动画结束。
第一次迭代的第一步在页面加载(或添加类)后立即发生,因此背景图像立即移动到to
帧内指示的位置。对于第二次迭代,移动回其原始位置(from
帧),然后再次移动到最终位置(to
帧),这意味着你看不到任何视觉差异,看起来元素似乎停留在其位置,没有任何动画。
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 1s steps(1, start) infinite;
}
@keyframes bganim {
from {
background-position: 0px 0px;
}
to {
background-position: 0px -72px;
}
}
<div class='dangerous_b'></div>
同样的行为也可以在小提琴上看到。这不是我的创作,而是对作为designmodo呈现的演示的改编。第一辆车从来没有真正移动过(或者从来没有被看到真正移动过),因为这一步就发生在起点。
解决方案1:使用两个步骤并将结束背景位置加倍
当步数设置为两步时,动画将作为两步过程进行,其中第一步在动画开始时再次发生(由于start
参数)。这意味着:
- 在第一步中,背景移动到开始状态和结束状态之间的一半距离
- 由于第一步正好在开始时发生,所以
background-position
永远不是0px 0px
。(请注意,我已将末尾background-position
加倍) - 在第二步中,背景移动到最终位置。因为背景图像是重复的,所以
0px -144px
等于0px 0px
。这会产生背景移动到其原始位置的错觉
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 1s steps(2, start) infinite;
}
@keyframes bganim {
from {
background-position: 0px 0px;
}
to {
background-position: 0px -144px;
}
}
<div class='dangerous_b'></div>
解决方案2:只使用一步,但将末端位置更改为中途
出于某种原因,这似乎模仿了两步动画。
- 在前半部分中,背景移动到
50%
帧内指示的位置 - 在下半场,它似乎回到了原来的位置(或
100%
位置,两者都相同)。因此,当下一次迭代开始并且图像跳跃时,它从0%
或100%
位置移动到50%
位置,并最终产生所需的动画效果
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 1s steps(1, start) infinite;
}
@keyframes bganim {
0% {
background-position: 0px 0px;
}
50% {
background-position: 0px -72px;
}
100% {
background-position: 0px 0px;
}
}
<div class='dangerous_b'></div>
如果我理解正确,现在运行动画需要1帧。由于你的背景图像正在移动,你看不到它。
https://developer.mozilla.org/nl/docs/Web/CSS/timing-function#The_steps()_class_of_timing函数