为什么`animation-direction:reverse`对我的CSS关键帧动画不起作用?

时间:2017-12-27 07:57:56

标签: css3 css-animations

我正在尝试使用animation-direction: reverse来重构我的CSS关键帧动画。单击时我有一个容器div将通过jQuery触发一个“活动”类,触发动画(向前或向后取决于“活动”状态)。前向和后向动画完全相同,只是关键帧的顺序相反。我认为animation-direction: reverse可以让我通过只使用一个动画并将其反转为另一个动画来重构它,但它没有像我想象的那样工作。

链接到codepen(不使用animation-direction: reverse): https://codepen.io/soultrust/pen/gogKjN

以下标记和CSS(Sass)代码段是它现在无需反向的方式。

<div class="container">
  <div class="line"></div>
</div>

$width-height: 100px;
$duration: 1s;
$line-width: 10%;
$animation-distance: $width-height * .45;

@keyframes line-in {
  0% { transform: translateY(-$animation-distance); }
  50% { transform: translateY(0); }
  100% { transform: rotate(-135deg); }
}

@keyframes line-out {
  0% { transform: rotate(-135deg); }
  50% { transform: translateY(0); }
  100% { transform: translateY(-$animation-distance); }
}

.container {
  margin: 10rem auto 0;
  width: $width-height;
  height: $width-height;
  position: relative;
  border: 1px solid black;

  &.active {
    .line {
      animation-name: line-in;
      animation-direction: normal;
    }
  }
}

.line {
  width: 100%;
  height: $line-width;
  position: absolute;
  top: 45%;
  background-color: orange;
  animation-direction: normal;
  animation-name: line-out;
  animation-duration: $duration;
  animation-fill-mode: forwards;
}

当我将“活动”动画更改为以下时,两个方向的动画都会停止工作。

&.active {
  .line {
    animation-name: line-out;
    animation-direction: reverse;
  }
}

我认为它与使用相同的动画有关,因为如果我只是设置animation-direction: reverse并使用animation-name: line-in,它会正确地反向播放输入动画。

1 个答案:

答案 0 :(得分:2)

非常好的问题。您已经注意到animation-direction: reverse;确实有效。你在哪里非常接近自己解决这个css的怪癖。

还有一些额外的规则需要注意。

  • 删除/替换css动画时,动画将从0%开始,
  • 当您设置reverse(而不更改实际动画时)时,动画将从它所处的任何百分比继续。

所以当你点击元素并设置line-out动画:

  • 动画将从0%开始
  • 按照你设定的方向进行游戏。

仅应用新的动画方向时:

  • 动画从任何百分比继续,例如,100%。

你可以用几种形式的技巧restart动画。你会看到在重新创建元素时正在反向播放动画。

var clickFunc =function(e) {    
      //toggle the state
      $(this).toggleClass("active");
      //reset the animatino state by cloning and replacing the element.
      var newone = this.cloneNode(true);
      this.parentNode.replaceChild(newone, this);
      // reapply click handler to the cloned element
      $(newone).click(clickFunc)   
}


$(function() {
  $(".question").click(function() {
    $(this).toggleClass("active");
  });
  
    $(".answer").click(clickFunc);

  $(".restart").click(function() {
    $(".line").each(function() {
      var newone = this.cloneNode(true);
      this.parentNode.replaceChild(newone, this);
    });
  });
});
@keyframes line-in {
  0% {
    transform: translateY(-45px);
  }
  50% {
    transform: translateY(0);
  }
  100% {
    transform: rotate(-135deg);
  }
}
@keyframes line-out {
  0% {
    transform: rotate(-135deg);
  }
  50% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-45px);
  }
}
.line {
  width: 100%;
  height: 10%;
  position: absolute;
  top: 45%;
  background-color: orange;
  animation-direction: normal;
  animation-name: line-in;
  animation-duration: 1s;
  animation-fill-mode: forwards;
}

.container {
  margin: 1rem auto 0;
  width: 100px;
  height: 100px;
  position: relative;
  border: 1px solid black;
}
.container.reverse .line {
  animation-name: line-in;
  animation-direction: reverse;
}
.container.active .line {
  animation-name: line-in;
  animation-direction: reverse;
}
.container.active.reverse .line {
  animation-name:line-in;
  animation-direction: normal;
}

.container.out.active .line {
  animation-name: line-out;
  animation-direction: normal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="restart">reset animation state</button><br>
in -out
<div class="container question out">
  <div class="line"></div>
</div>

active reversed
<div class="container question">
  <div class="line"></div>
</div>

<br>

workaround
<div class="container answer reverse">
  <div class="line"></div>
</div>

为了调试这个。您可以在浏览器的Web开发工具中检查动画状态: enter image description here

关于你的重构: 我宁愿在不同的方向上有多个动画,而不是做js技巧以重新启动/反转动画。

根据动画的复杂程度,您可能更喜欢使用css过渡而不是动画帧。你不必担心倒转/重置动画。