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

sou*_*ust 4 css css-animations

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

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

下面的标记和 CSS (Sass) 代码片段是它现在没有反向的工作方式。

<div class="container">
  <div class="line"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

 

$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;
}
Run Code Online (Sandbox Code Playgroud)

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

&.active {
  .line {
    animation-name: line-out;
    animation-direction: reverse;
  }
}
Run Code Online (Sandbox Code Playgroud)

我相信这与使用相同的动画有关,因为如果我只设置animation-direction: reverse和 使用animation-name: line-in,它会正确地反向播放行内动画。

Lar*_*ars 6

很好的问题。你已经注意到这animation-direction: reverse;确实有效。您几乎可以自己弄清楚这个 css 怪癖。

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

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

因此,当您单击元素并设置line-out动画时:

  • 动画将从 0% 开始
  • 朝您设定的任何方向演奏。

当只应用一个新的动画方向时:

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

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

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);
    });
  });
});
Run Code Online (Sandbox Code Playgroud)
@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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

为了调试这个。您可以在浏览器的 Web 开发工具中检查动画状态: 在此处输入图片说明

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

根据动画的复杂程度,与动画帧相比,使用 css 过渡可能会更好。您不必担心反转/重置动画。