gpt4 book ai didi

javascript - 反转CSS动画

转载 作者:行者123 更新时间:2023-11-29 19:15:42 28 4
gpt4 key购买 nike

我这样做: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

最佳答案

如果是简单的颜色更改,我也会建议像Martin's answer中那样进行CSS过渡,但是正如您所解释的那样,它更复杂,Osama8DZ's answer是最佳的解决方案。但这并不能回答您的问题,它指出以下内容(强调是我的):


  当我单击小按钮时,我想反转动画,但是我做的没有用,我也不知道为什么。


原因:

当您单击导致反向动画触发的按钮时,类名将更改,因此原始动画将被反向动画替换。这实际上是两个步骤-第一是删除原始动画,第二是添加反向动画。

每当删除元素上存在的动画时,该元素就会立即捕捉到其原始状态(即动画之前的状态)。此处,元素在其原始状态下具有红色背景。因此,该元素立即获得红色背景,然后反向动画没有视觉效果,因为它是从红色背景变为红色背景。

您可以在下面的代码段中看到我的意思的样本。我向元素的原始状态添加了左边界和上边界,并在正向动画期间对其进行了更改。单击反向按钮后,形状立即回到原始状态,然后应用反向动画中提供的左上边缘。



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's answer中提供的解决方案,因为它看起来好像原始元素从未恢复到其原始状态。我将不做进一步的详细说明,因为看起来我在抄袭他的答案(或)窃)。

但是,我将重点介绍无法解决问题的几种情况以及解决方法。



情况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(这意味着同时具有 forwardsbackwards的效果)而不是 forwards。这也使元素在延迟时间段内(由于 0%)也保持在 backwards关键帧的状态,并且即使在动画结束之后(由于 100%)也保持在 forwards关键帧的状态。



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>





注意:我们不应按原样保留内联样式,因为这将导致原始动画在第二次单击时出现问题。因此,我们必须收听动画的结束事件并删除内联样式(如果有)。 animationend仍然需要一些版本的浏览器前缀,但我将留给您。

希望以上所有内容对您的代码为何(似乎)无法正常工作,如何针对各种情况进行修复提供了完整的解释。

关于javascript - 反转CSS动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35525992/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com