我正在为一个按钮设置动画。根据我的应用程序状态分配一个类。这在Svelte中实际实现如下:
<div class="default"
class:run-animation="{$animate === true}">
但在没有Svelte的香草javascript中,等效的是:
let element = document... (find element)
element.classList.add("run-animation")
... later ...
element.classList.remove("run-animation)
为了获得一个可重复性最小的例子,我试图在两个类之间动画化/转换的类看起来是这样的:
.default {
top: 20px;
color: white;
}
@keyframes button-animation {
from {
top: 20px;
color: white;
}
20% {
top: 23px;
color: white;
}
25% {
color: red;
}
100% {
top: 23px;
color: red;
}
}
.run-animation {
animation-name: button-animation;
animation-duration: 2s;
/* Preserve the effect of the animation at ending */
animation-fill-mode: forwards;
}
我将类添加到元素中,按钮按我希望的方式设置动画。当我删除类时,问题就出现了。我希望这个按钮能顺利地转换回默认的CSS。我已经尝试将动画添加到run animate类中:
.run-animation {
animation-name: ... ;
top: 23px;
color: red;
}
我遇到过很多人说,如果我在默认类中添加一个转换属性,那么类删除时的转换将适用。我试过如下:
.default {
...
transition: all 3s linear;
}
但它不起作用。添加动画时动画会平滑运行,但删除类时样式会立即恢复为默认样式(无平滑过渡(。
我的目标:当移除动画类时,我希望从动画的结束状态平滑地过渡到默认类。这可能吗
理想情况下,我添加的类顶部有Svelte逻辑,因此动画不应该在javascript中触发,而是作为类分配的结果自然发生。
(我在实践中的代码比显示的要复杂一点,按钮有另一个类的样式根本没有动画化,动画包括更多的样式,如框阴影和文本阴影。不过,我不明白为什么这会比上面包含的颜色和顶部更成问题(
// JS only toggles '.animation'
document.querySelector("button").addEventListener("click", () => {
document.querySelector("div.default").classList.toggle("animation");
});
body {display: flex}
button {position: absolute; left: 120px}
div.default {
position: absolute;
width: 100px;
height: 100px;
background: darkgreen;
}
/* Above code to make a visible working example */
div.default {
top: 20px;
color: white;
transition: top 0.4s, color 0.1s 0.4s;
}
@keyframes define-animation {
from {
top: 20px;
color: white;
}
}
div.default.animation {
animation-name: define-animation;
animation-duration: 2s;
top: 24px;
color: red;
}
<div class="default">I'm colourful</div>
<button>Toggle ".animation"-class</button>
上面是一个工作片段,在添加类时运行动画,在删除类时没有反向转换。我曾尝试在.default和.animation中将动画方向设置为相反的值。我曾尝试将类和/或关键帧中的.animate结束状态属性定义为属性。
编辑:它现在起作用了!怎样您不能申请:动画填充模式:向前;结束属性需要在animate类中定义,而不是在关键帧中定义。
添加类时将播放动画。移除类时(如果动画已完成(将使用过渡计时。
要获得转换效果,可以使用transition
-属性transition
-属性可以在这里使用,因为要设置动画的每个属性都只有一个开始值和结束值。
将动画百分比转换为秒
要将CSS动画的百分比button-animation
转换为秒,只需计算'percentage' * 'animation-duration'
这适用于transition-duration
-属性和transition-delay
-属性。
示例:color
的动画从20%设置为25%,持续时间为5%,延迟为20%
总而言之,动画应该需要2秒钟。所以我们计算:
transition-duration
:5% * 2s = 0.1s
transition-delay
:20% * 2s = 0.4s
这样,我们就可以将transition: color 0.1s 0.4s
添加到.default
-类中。
为什么要将其添加到.default
,而不是.animation
如果我们将transition
-属性添加到.animation
,则会发生以下情况:
- 添加
.animation
时,将产生转换效果,因为元素现在定义了transition
-属性 - 但是,当删除
.animation
时,元素将不再定义transition
-属性,这意味着不会有转换
现在,我们希望在添加和删除.animation
时进行转换,这意味着我们希望在.animation
存在和不存在时都定义一个transition
-属性。也就是说,transition
不应该在.animation
中定义。
// JS only toggles '.animation'
document.querySelector("button").addEventListener("click", () => {
document.querySelector("div.default").classList.toggle("animation");
});
body {display: flex}
button {align-self: center}
div.default {
position: relative;
border: 2px solid black;
width: 100px;
height: 100px;
background: darkgreen;
}
/* Above code to make a visible working example */
div.default {
top: 20px;
color: white;
transition: top 0.4s, color 0.1s 0.4s;
}
div.default.animation {
top: 23px;
color: red;
}
<div class="default">Some text to see the "color"-property</div>
<button>Toggle ".animation"-class</button>
为什么它的行为不同
。。。将属性放置在动画的to
部分中时,而不是将它们放置在.animation
本身中时?
也就是说,因为属性并没有直接应用于元素本身,而是元素在其动画中停止(就在最后(,只给出实际应用的属性的外观
删除animation-fill-mode: forwards
将显示动画播放后实际应用的属性。那些实际应用的属性将是删除.animation
之后transition
的起始值。
在.animation
中定义这些属性时,它们将本质上是动画的to
值(如果在动画本身中未另行定义(,和是元素的应用属性
这意味着,当删除.animation
时,转换将从那里开始。