我做了这个:http://codepen.io/yayoni/pen/pgXoWY
当我点击小按钮时,我想逆转动画,但是我所做的不工作,我不明白为什么。
function anim() {
var div = document.getElementById('fab');
div.className = "anim";
}
function animrev() {
var div = document.getElementById('fab');
div.className = "animrev";
}html,
body {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#fab {
margin-right: 30px;
color: white;
font-size: 45px;
outline: 0;
border: 0;
height: 150px;
width: 150px;
border-radius: 75px;
text-align: center;
background-color: red;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.anim {
animation-name: example;
animation-duration: 1s;
animation-fill-mode: forwards;
}
@keyframes example {
100% {
background-color: green;
left: 0px;
top: 0px;
}
}
@keyframes exampleux {
100% {
background-color: red;
left: 0px;
top: 0px;
}
}
.animrev {
animation-name: exampleux;
animation-duration: 1s;
animation-fill-mode: forwards;
}<div id="content">
<button onclick="anim()" id="fab">+</button>
<button onclick="animrev()" id="fab2">+</button>
</div>
有关更多细节,请参见CodePen
发布于 2016-02-21 07:14:05
如果这是一个简单的颜色变化,我也会推荐CSS转换,比如在马丁的回答中,但是正如您已经解释过的,它是更复杂的东西,Osama8DZ的答复是您最好的解决方案。但这并没有给出你的问题的答案,你的问题说明如下(重点是我的):
当我点击小按钮时,我想反转动画,但是我所做的不工作,,我不明白为什么。
原因:
当您单击导致反向动画触发的按钮时,类名会更改,因此原始动画将被反向动画替换。这实际上是两个步骤-第一是删除原来的动画,第二是添加反向。
每当删除存在于元素上的动画时,该元素立即切换到其原始状态(即动画之前的状态)。在这里,元素的原始状态为红色背景。因此,元素立即获得一个红色背景,然后反向动画没有视觉效果,因为它是动画从红色背景到红色背景。
您可以在下面的片段中看到我所指的示例。我在元素的原始状态中添加了左和上边距,并在前向动画中更改了它。当执行反向按钮单击时,形状立即返回原始状态,然后应用反向动画中提供的左边、顶部边距。
var div = document.getElementById('fab');
function anim() {
div.className = "anim";
}
function animrev() {
div.className = "animrev";
}html,
body {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#fab {
margin-right: 30px;
color: white;
font-size: 45px;
outline: 0;
border: 0;
height: 150px;
width: 150px;
border-radius: 75px;
text-align: center;
background-color: red;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
/* added these for demo */
margin-left: 20px;
margin-top: 10px;
}
.anim {
animation-name: example;
animation-duration: 1s;
animation-fill-mode: forwards;
}
@keyframes example {
100% {
background-color: green;
left: 0px;
top: 0px;
/* added these for demo */
margin-left: 40px;
margin-top: 20px;
}
}
@keyframes exampleux {
100% {
background-color: red;
left: 0px;
top: 0px;
/* added these for demo */
margin-left: 30px;
margin-top: 15px;
}
}
.animrev {
animation-name: exampleux;
animation-duration: 1s;
animation-fill-mode: forwards;
}<div id="content">
<button onclick="anim()" id="fab">+</button>
<button onclick="animrev()" id="fab2">+</button>
</div>
解决方案:
简单和最好的解决方案将是Osama8DZ的答复中提供的解决方案,因为它使原始元素看起来似乎从未恢复到原来的状态。我不会再详细说明这一点,因为这看起来像是在抄袭他的答案(或)剽窃。
但是,我将重点介绍几个不起作用的案例,以及如何解决这些问题。
案例1:当动画有延迟时-当动画(或)都被延迟时,您仍然能够看到它在运行动画之前快速恢复到原始状态。下面的片段显示了实际操作中的问题。
var div = document.getElementById('fab');
function anim() {
div.className = "anim";
}
function animrev() {
div.className = "animrev";
}html,
body {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#fab {
margin-right: 30px;
color: white;
font-size: 45px;
outline: 0;
border: 0;
height: 150px;
width: 150px;
border-radius: 75px;
text-align: center;
background-color: red;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.anim {
animation-name: example;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes example {
100% {
background-color: green;
left: 0px;
top: 0px;
}
}
@keyframes exampleux {
0% {
/* You need to add this */
background-color: green;
left: 0px;
top: 0px;
}
100% {
background-color: red;
left: 0px;
top: 0px;
}
}
.animrev {
animation-name: exampleux;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-delay: 1s;
}<div id="content">
<button onclick="anim()" id="fab">+</button>
<button onclick="animrev()" id="fab2">+</button>
</div>
如何修复它?原因是因为动画将继续保持其原始状态,直到延迟时间过去,因此即使反向动画中的0%关键帧与前向动画的100%关键帧相同,元素仍然会快速恢复,然后再动画。修复方法是将animation-fill-mode设置为both (这意味着,具有forwards和backwards的效果),而不是forwards。这使得元素在延迟期间(由于0% )保持状态与在100%关键帧中的状态相同,并且在动画结束后(由于forwards)仍保持状态为100%关键帧。
var div = document.getElementById('fab');
function anim() {
div.className = "anim";
}
function animrev() {
div.className = "animrev";
}html,
body {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#fab {
margin-right: 30px;
color: white;
font-size: 45px;
outline: 0;
border: 0;
height: 150px;
width: 150px;
border-radius: 75px;
text-align: center;
background-color: red;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.anim {
animation-name: example;
animation-duration: 1s;
animation-fill-mode: both;
animation-delay: 1s;
}
@keyframes example {
100% {
background-color: green;
left: 0px;
top: 0px;
}
}
@keyframes exampleux {
0% {
/* You need to add this */
background-color: green;
left: 0px;
top: 0px;
}
100% {
background-color: red;
left: 0px;
top: 0px;
}
}
.animrev {
animation-name: exampleux;
animation-duration: 1s;
animation-fill-mode: both;
animation-delay: 1s;
}<div id="content">
<button onclick="anim()" id="fab">+</button>
<button onclick="animrev()" id="fab2">+</button>
</div>
案例2:,如果反向动画对于多个元素是常见的,但是前向动画是不同的,就像下面的片段所示。在下面的片段中,第一个元素的前向动画将背景从red更改为green,而第二个元素将其从red更改为blue,但反向动画应该将两者都设置为red。在这种情况下,我们不能将反向动画的0%关键帧设置为前向动画的100%,因为对于这两个前向动画,结束状态是不同的。
var div = document.getElementById('fab');
var div2 = document.getElementById('fab3');
function anim() {
div.className = "anim";
}
function animAlt() {
div2.className = "anim-alt";
}
function animrev() {
div.className = "animrev";
div2.className = "animrev";
}html,
body {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#fab, #fab3 {
margin-right: 30px;
color: white;
font-size: 45px;
outline: 0;
border: 0;
height: 150px;
width: 150px;
border-radius: 75px;
text-align: center;
background-color: red;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.anim {
animation-name: example;
animation-duration: 1s;
animation-fill-mode: forwards;
}
@keyframes example {
100% {
background-color: green;
left: 0px;
top: 0px;
}
}
.anim-alt {
animation-name: example2;
animation-duration: 1s;
animation-fill-mode: forwards;
}
@keyframes example2 {
100% {
background-color: blue;
left: 0px;
top: 0px;
}
}
@keyframes exampleux {
0% {
/* You need to add this */
background-color: green;
left: 0px;
top: 0px;
}
100% {
background-color: red;
left: 0px;
top: 0px;
}
}
.animrev {
animation-name: exampleux;
animation-duration: 1s;
animation-fill-mode: forwards;
}<div id="content">
<button onclick="anim()" id="fab">+</button>
<button onclick="animAlt()" id="fab3">+</button>
<button onclick="animrev()" id="fab2">+</button>
</div>
如何修复?在这种情况下没有纯粹的CSS解决方案(除非您切换到使用转换)。不过,有一个解决办法,就是在元素结束后,通过内联样式将原始动画的最后一个关键帧中的样式添加到元素中。这意味着我们在模仿元素的效果,而不是突然恢复到它原来的状态。
var div = document.getElementById('fab');
var div2 = document.getElementById('fab3');
function anim() {
div.className = "anim";
}
function animAlt() {
div2.className = "anim-alt";
}
function animrev() {
div.className = "animrev";
div2.className = "animrev";
}
div.addEventListener('animationend', function(e) {
if (e.animationName == "example") { /* meaning the forward animation has ended */
this.style.backgroundColor = 'green';
this.style.marginLeft = '40px';
this.style.marginTop = '20px';
}
else
this.style = null;
})
div2.addEventListener('animationend', function(e) {
if (e.animationName == "example2") { /* meaning the forward animation has ended */
this.style.backgroundColor = 'blue';
this.style.marginLeft = '40px';
this.style.marginTop = '20px';
}
else
this.style = null;
})html,
body {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#fab, #fab3 {
margin-right: 30px;
color: white;
font-size: 45px;
outline: 0;
border: 0;
height: 150px;
width: 150px;
border-radius: 75px;
text-align: center;
background-color: red;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
margin-left: 20px;
margin-top: 10px;
}
.anim {
animation-name: example;
animation-duration: 1s;
animation-fill-mode: forwards;
}
@keyframes example {
100% {
background-color: green;
left: 0px;
top: 0px;
margin-left: 40px;
margin-top: 20px;
}
}
.anim-alt {
animation-name: example2;
animation-duration: 1s;
animation-fill-mode: forwards;
}
@keyframes example2 {
100% {
background-color: blue;
left: 0px;
top: 0px;
margin-left: 40px;
margin-top: 20px;
}
}
@keyframes exampleux {
100% {
background-color: red;
left: 0px;
top: 0px;
margin-left: 20px;
margin-top: 10px;
}
}
.animrev {
animation-name: exampleux;
animation-duration: 1s;
animation-fill-mode: forwards;
}<div id="content">
<button onclick="anim()" id="fab">+</button>
<button onclick="animAlt()" id="fab3">+</button>
<button onclick="animrev()" id="fab2">+</button>
</div>
注意:我们不应该将内联样式保留为-,因为这会导致第二次单击原始动画时出现问题。因此,我们必须监听动画的end事件,并删除内联样式(如果有的话)。animationend仍然需要几个版本的浏览器前缀,但是我会把这部分留给您。
我希望上面的所有内容都为您提供了一个完整的解释,说明为什么您的代码(似乎)不能工作,以及如何修复各种场景。
发布于 2016-02-20 16:51:45
事实上,您不需要使用任何CSS3关键帧或动画,只使用transition: background-color 1s linear;来创建颜色转换。
发布于 2016-02-20 18:09:19
尝试:
@keyframes exampleux {
0%
{
background-color: green; left:0px; top:0px; /* You need to add this */
}
100%
{
background-color: red; left:0px; top:0px;
}
}https://stackoverflow.com/questions/35525992
复制相似问题