我正在尝试使用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
,它会正确地反向播放输入动画。
答案 0 :(得分:2)
非常好的问题。您已经注意到animation-direction: reverse;
确实有效。你在哪里非常接近自己解决这个css的怪癖。
还有一些额外的规则需要注意。
reverse
(而不更改实际动画时)时,动画将从它所处的任何百分比继续。所以当你点击元素并设置line-out
动画:
仅应用新的动画方向时:
你可以用几种形式的技巧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开发工具中检查动画状态:
关于你的重构: 我宁愿在不同的方向上有多个动画,而不是做js技巧以重新启动/反转动画。
根据动画的复杂程度,您可能更喜欢使用css过渡而不是动画帧。你不必担心倒转/重置动画。