为什么CSS动画没有持续时间?

时间:2015-06-04 19:10:04

标签: css css-animations

我有一些应该从一个州到另一个州的动画。从状态empty到州bit的工作正常,从bitlarge的工作正常,但是当我尝试使用我添加为类的反向动画时,动画没有持续时间。这是我的代码片段:

@keyframes empty-bit {
  0%   {width: 0%;}
  100% {width: 4px;}
}
@keyframes bit-large {
  0%   {width: 4px;}
  100% {width: 100%;}
}
.timeline-empty-bit {
  animation-name: empty-bit;
  animation-fill-mode: forwards;
  animation-duration: 200ms;
  animation-timing-function: ease-in-out;
  animation-delay: 200ms;
}
.timeline-bit-large {
  animation-name: bit-large;
  animation-fill-mode: forwards;
  animation-duration: 200ms;
  animation-timing-function: ease-in-out;
}
.timeline-large-bit {
  animation-name: bit-large;
  animation-fill-mode: forwards;
  animation-duration: 200ms;
  animation-timing-function: ease-in-out;
  animation-direction: reverse;
  animation-delay: 200ms;
}
.timeline-bit-empty {
  animation-name: empty-bit;
  animation-fill-mode: forwards;
  animation-duration: 200ms;
  animation-timing-function: ease-in-out;
  animation-direction: reverse;
}

这是一个小伙伴:https://jsfiddle.net/9tmm46fz/ 使用箭头(左,右)查看动画。

1 个答案:

答案 0 :(得分:2)

动画 有持续时间。问题是动画已经完成播放,除非动画名称属性发生变化,否则更改类将不会从头开始播放动画。因此,解决此问题的一种方法是为bit-emptylarge-bit类创建单独的动画:

.timeline-gauge {
    height: 20px;
}
.timeline-gauge-container {
    display: inline-block;
    height: 100%;
}
.timeline-gauge-part {
    display: block;
    height: 100%;
    width: 0%;
}
@keyframes empty-bit {
    0%   {width: 0%;}
    100% {width: 4px;}
}
@keyframes bit-empty {
    0%   {width: 0%;}
    100% {width: 4px;}
}
@keyframes bit-large {
    0%   {width: 4px;}
    100% {width: 100%;}
}
@keyframes large-bit {
    0%   {width: 4px;}
    100% {width: 100%;}
}
.timeline-empty-bit {
    animation-name: empty-bit;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
    animation-delay: 200ms;
}
.timeline-bit-large {
    animation-name: bit-large;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
}
.timeline-large-bit {
    animation-name: large-bit;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
    animation-direction: reverse;
    animation-delay: 200ms;
}
.timeline-bit-empty {
    animation-name: bit-empty;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
    animation-direction: reverse;
}

var containers = document.getElementsByClassName("timeline-gauge-container");
var length = containers.length;

for (var i = 0; i < length; i++) {
    containers[i].style.width = containers[i].getAttribute("percentage");
}

var parts = document.getElementsByClassName("timeline-gauge-part");
var length = parts.length;

for (var i = 0; i < length; i++) {
    parts[i].style.backgroundColor = parts[i].getAttribute("color");
}

var index = 0;

parts[0].classList.add("timeline-empty-bit");

function removeAnimation(part) {
    part.classList.remove("timeline-empty-bit");
    part.classList.remove("timeline-bit-large");
    part.classList.remove("timeline-large-bit");
    part.classList.remove("timeline-bit-empty");
}

document.onkeydown = function(event) {
    if (event.keyCode == 37 && index > 0) {
        removeAnimation(parts[index - 1]);
        parts[index - 1].classList.add("timeline-large-bit");
        
        if (index != length) {
            removeAnimation(parts[index]);
            parts[index].classList.add("timeline-bit-empty");
        }
        
        index--;
    }
    
    if (event.keyCode == 39 && index < length) {
        removeAnimation(parts[index]);
        parts[index].classList.add("timeline-bit-large");
        
        if (index != length - 1) {
            removeAnimation(parts[index + 1]);
            parts[index + 1].classList.add("timeline-empty-bit");
        }
        
        index++;
    }
};
.timeline-gauge {
    height: 20px;
}
.timeline-gauge-container {
    display: inline-block;
    height: 100%;
}
.timeline-gauge-part {
    display: block;
    height: 100%;
    width: 0%;
}
@keyframes empty-bit {
    0%   {width: 0%;}
    100% {width: 4px;}
}
@keyframes bit-empty {
    0%   {width: 0%;}
    100% {width: 4px;}
}
@keyframes bit-large {
    0%   {width: 4px;}
    100% {width: 100%;}
}
@keyframes large-bit {
    0%   {width: 4px;}
    100% {width: 100%;}
}
.timeline-empty-bit {
    animation-name: empty-bit;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
    animation-delay: 200ms;
}
.timeline-bit-large {
    animation-name: bit-large;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
}
.timeline-large-bit {
    animation-name: large-bit;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
    animation-direction: reverse;
    animation-delay: 200ms;
}
.timeline-bit-empty {
    animation-name: bit-empty;
    animation-fill-mode: both;
    animation-duration: 200ms;
    animation-timing-function: ease-in-out;
    animation-direction: reverse;
}
<div class="timeline-container">
    <div class="timeline-gauge">
        <div class="timeline-gauge-container" percentage="5%"><span class="timeline-gauge-part" color="#4f5f6b"></span></div><div class="timeline-gauge-container" percentage="20%"><span class="timeline-gauge-part" color="#237487"></span></div><div class="timeline-gauge-container" percentage="10%"><span class="timeline-gauge-part" color="#00b188"></span></div><div class="timeline-gauge-container" percentage="20%"><span class="timeline-gauge-part" color="#008e6c"></span></div><div class="timeline-gauge-container" percentage="25%"><span class="timeline-gauge-part" color="#99ca34"></span></div><div class="timeline-gauge-container" percentage="20%"><span class="timeline-gauge-part" color="#9059a2"></span></div>
    </div>
</div>

View JSFiddle

更好的解决方案是根本不使用动画。在我看来,在这种情况下,转换是一个更好的工具:

.timeline-gauge {
    height: 20px;
}
.timeline-gauge-container {
    display: inline-block;
    height: 100%;
}
.timeline-gauge-part {
    display: block;
    height: 100%;
    width: 0%;

    transition: width 200ms ease-in-out;
}

.timeline-empty-bit {
    width: 4px;
    transition-delay: 200ms;
}
.timeline-bit-large {
    width: 100%;
}
.timeline-large-bit {
    width: 4px;
    transition-delay: 200ms;
}
.timeline-bit-empty {
    width: 0%;
}

var containers = document.getElementsByClassName("timeline-gauge-container");
var length = containers.length;

for (var i = 0; i < length; i++) {
    containers[i].style.width = containers[i].getAttribute("percentage");
}

var parts = document.getElementsByClassName("timeline-gauge-part");
var length = parts.length;

for (var i = 0; i < length; i++) {
    parts[i].style.backgroundColor = parts[i].getAttribute("color");
}

var index = 0;

parts[0].classList.add("timeline-empty-bit");

function removeAnimation(part) {
    part.classList.remove("timeline-empty-bit");
    part.classList.remove("timeline-bit-large");
    part.classList.remove("timeline-large-bit");
    part.classList.remove("timeline-bit-empty");
}

document.onkeydown = function(event) {
    if (event.keyCode == 37 && index > 0) {
        removeAnimation(parts[index - 1]);
        parts[index - 1].classList.add("timeline-large-bit");
        
        if (index != length) {
            removeAnimation(parts[index]);
            parts[index].classList.add("timeline-bit-empty");
        }
        
        index--;
    }
    
    if (event.keyCode == 39 && index < length) {
        removeAnimation(parts[index]);
        parts[index].classList.add("timeline-bit-large");
        
        if (index != length - 1) {
            removeAnimation(parts[index + 1]);
            parts[index + 1].classList.add("timeline-empty-bit");
        }
        
        index++;
    }
};
.timeline-gauge {
    height: 20px;
}
.timeline-gauge-container {
    display: inline-block;
    height: 100%;
}
.timeline-gauge-part {
    display: block;
    height: 100%;
    width: 0%;
    
    transition: width 200ms ease-in-out;
}

.timeline-empty-bit {
    width: 4px;
    transition-delay: 200ms;
}
.timeline-bit-large {
    width: 100%;
}
.timeline-large-bit {
    width: 4px;
    transition-delay: 200ms;
}
.timeline-bit-empty {
    width: 0%;
}
<div class="timeline-container">
    <div class="timeline-gauge">
        <div class="timeline-gauge-container" percentage="5%"><span class="timeline-gauge-part" color="#4f5f6b"></span></div><div class="timeline-gauge-container" percentage="20%"><span class="timeline-gauge-part" color="#237487"></span></div><div class="timeline-gauge-container" percentage="10%"><span class="timeline-gauge-part" color="#00b188"></span></div><div class="timeline-gauge-container" percentage="20%"><span class="timeline-gauge-part" color="#008e6c"></span></div><div class="timeline-gauge-container" percentage="25%"><span class="timeline-gauge-part" color="#99ca34"></span></div><div class="timeline-gauge-container" percentage="20%"><span class="timeline-gauge-part" color="#9059a2"></span></div>
    </div>
</div>

View JSFiddle