使用 CSS 动画,如果我们需要再次动画,是否必须删除 class 并重新添加?
Using CSS Animation, if we need to animate it again, must be remove the class and add it back?
请查看下面的演示,或在 https://jsfiddle.net/ut7y93hv/
我正在从 Peter、Paul 和 Mary 中随机取一个名字,如果名字与以前不同,则有“模糊”效果,更改名称,然后使其“模糊” (再次变尖锐)。
所以现在我必须做
setTimeout(() => {
displayElement.classList.remove("blur-and-back");
}, 2000);
也就是动画完成后去掉class名字。否则,如果我下次只添加 class 名称,就好像什么都没发生一样——它不会再进行动画处理。我也仔细检查过:我不能删除 class 名称然后立即将其添加回去,因为它也好像什么都没有发生一样。
问题是:有没有办法使用 CSS 动画更优雅地做到这一点?不知何故只是告诉动画重新启动自己,而不需要删除 class 并添加 class 回来?当它在 ReactJS 中完成时也很混乱,因为我们还需要做 setTimeout()
来“在幕后”做低级的事情来实现它。
我也许可以让它成为一个不断重复的动画,但是使用 setTimeout()
2 秒后“暂停”,然后下次重新启动它,但如果 [=16] 可能会更糟=] 延迟 16 毫秒或 33 毫秒,然后动画移动越来越多,并且在一段时间后不同步。
需要启动动画然后设置计时器来更改文本也有些混乱。我想我可以先模糊文本,然后使用事件 animationend
更改文本,然后 kickstart 使其再次清晰,然后使用事件 animationend
删除 class,但是这个也有点乱
const names = ["Peter", "Paul", "Mary"];
const displayElement = document.querySelector("#display");
function pickOne(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let name = pickOne(names),
prevName = name;
displayElement.innerHTML = name;
setInterval(() => {
name = pickOne(names);
if (name !== prevName) {
displayElement.classList.add("blur-and-back");
setTimeout(() => {
displayElement.innerHTML = name;
}, 1000);
setTimeout(() => {
displayElement.classList.remove("blur-and-back");
}, 2000);
prevName = name;
}
}, 3000);
#display {
font: 36px Arial, sans-serif;
}
.blur-and-back {
animation: 2s blur_and_back;
}
@keyframes blur_and_back {
0% {
filter: blur(0);
}
50% {
filter: blur(0.72em);
}
100% {
filter: blur(0);
}
}
<div id="display"></div>
不,您当时不需要将其删除,您只需在再次打开之前将其删除即可,trigger a reflow 其间:
const names = ["Peter", "Paul", "Mary"];
const displayElement = document.querySelector("#display");
function pickOne(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let name = pickOne(names),
prevName = name;
displayElement.innerHTML = name;
setInterval(() => {
name = pickOne(names);
if (name !== prevName) {
displayElement.classList.remove("blur-and-back");
displayElement.offsetWidth; // trigger reflow
displayElement.classList.add("blur-and-back");
setTimeout(() => {
displayElement.innerHTML = name;
}, 1000);
prevName = name;
}
}, 3000);
#display {
font: 36px Arial, sans-serif;
}
.blur-and-back {
animation: 2s blur_and_back;
}
@keyframes blur_and_back {
0% {
filter: blur(0);
}
50% {
filter: blur(0.72em);
}
100% {
filter: blur(0);
}
}
<div id="display"></div>
请注意,您还可以查看 Web Animations API,它提供了以编程方式控制动画的方法。
const names = ["Peter", "Paul", "Mary"];
const displayElement = document.querySelector("#display");
const keyframes = [
{ filter: "blur(0)" },
{ filter: "blur(0.72em)" },
{ filter: "blur(0)" }
];
const duration = 2000;
function pickOne(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let name = pickOne(names),
prevName = name;
displayElement.innerHTML = name;
setInterval(() => {
name = pickOne(names);
if (name !== prevName) {
displayElement.animate( keyframes, { duration } );
setTimeout(() => {
displayElement.innerHTML = name;
}, 1000);
prevName = name;
}
}, 3000);
#display {
font: 36px Arial, sans-serif;
}
<div id="display"></div>
就像我评论的一样,
animation
是指使用一次或连续动画,我们确实有自己的做事风格,但我建议使用 transition
以便在特定事件和时间灵活地设置动画。
由于您的动画设置为 2 秒,因此您可以像这样设置 css 过渡:
#display {
font: 36px Arial, sans-serif;
transition: filter 650ms;
}
然后利用 Javascript:
function blur_and_back(){
displayElement.style.filter = "filter:blur(0.72em)";
setTimeout(() => { displayElement.style.filter = "filter:blur(0)"},650);
}
每次你想要动画时调用 blur_and_back()
。
编辑:
基于 developer.mozilla.org,animation
的一个组成部分是 animation
是:
a style describing the CSS animation and a set of keyframes that
indicate the start and end states of the animation’s style
通过start
和end
或from
和to
或0%
和100%
实际上是一次性使用动画,或使用 infinite
使其连续动画化。
他们还补充说:
you can create them without
even having to know JavaScript.
同时 transition
再次基于 developer.mozilla.org:
Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time.
CSS transitions let you decide which properties to animate (by listing
them explicitly), when the animation will start (by setting a delay),
how long the transition will last (by setting a duration), and how the
transition will run (by defining a timing function, e.g. linearly or
quick at the beginning, slow at the end).
这就是我所说的灵活性。
我想这有点明显,即使是他们的字面英文定义。
不过,我再说一遍,我们确实有自己的做事风格,这只是一个建议。
请查看下面的演示,或在 https://jsfiddle.net/ut7y93hv/
我正在从 Peter、Paul 和 Mary 中随机取一个名字,如果名字与以前不同,则有“模糊”效果,更改名称,然后使其“模糊” (再次变尖锐)。
所以现在我必须做
setTimeout(() => {
displayElement.classList.remove("blur-and-back");
}, 2000);
也就是动画完成后去掉class名字。否则,如果我下次只添加 class 名称,就好像什么都没发生一样——它不会再进行动画处理。我也仔细检查过:我不能删除 class 名称然后立即将其添加回去,因为它也好像什么都没有发生一样。
问题是:有没有办法使用 CSS 动画更优雅地做到这一点?不知何故只是告诉动画重新启动自己,而不需要删除 class 并添加 class 回来?当它在 ReactJS 中完成时也很混乱,因为我们还需要做 setTimeout()
来“在幕后”做低级的事情来实现它。
我也许可以让它成为一个不断重复的动画,但是使用 setTimeout()
2 秒后“暂停”,然后下次重新启动它,但如果 [=16] 可能会更糟=] 延迟 16 毫秒或 33 毫秒,然后动画移动越来越多,并且在一段时间后不同步。
需要启动动画然后设置计时器来更改文本也有些混乱。我想我可以先模糊文本,然后使用事件 animationend
更改文本,然后 kickstart 使其再次清晰,然后使用事件 animationend
删除 class,但是这个也有点乱
const names = ["Peter", "Paul", "Mary"];
const displayElement = document.querySelector("#display");
function pickOne(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let name = pickOne(names),
prevName = name;
displayElement.innerHTML = name;
setInterval(() => {
name = pickOne(names);
if (name !== prevName) {
displayElement.classList.add("blur-and-back");
setTimeout(() => {
displayElement.innerHTML = name;
}, 1000);
setTimeout(() => {
displayElement.classList.remove("blur-and-back");
}, 2000);
prevName = name;
}
}, 3000);
#display {
font: 36px Arial, sans-serif;
}
.blur-and-back {
animation: 2s blur_and_back;
}
@keyframes blur_and_back {
0% {
filter: blur(0);
}
50% {
filter: blur(0.72em);
}
100% {
filter: blur(0);
}
}
<div id="display"></div>
不,您当时不需要将其删除,您只需在再次打开之前将其删除即可,trigger a reflow 其间:
const names = ["Peter", "Paul", "Mary"];
const displayElement = document.querySelector("#display");
function pickOne(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let name = pickOne(names),
prevName = name;
displayElement.innerHTML = name;
setInterval(() => {
name = pickOne(names);
if (name !== prevName) {
displayElement.classList.remove("blur-and-back");
displayElement.offsetWidth; // trigger reflow
displayElement.classList.add("blur-and-back");
setTimeout(() => {
displayElement.innerHTML = name;
}, 1000);
prevName = name;
}
}, 3000);
#display {
font: 36px Arial, sans-serif;
}
.blur-and-back {
animation: 2s blur_and_back;
}
@keyframes blur_and_back {
0% {
filter: blur(0);
}
50% {
filter: blur(0.72em);
}
100% {
filter: blur(0);
}
}
<div id="display"></div>
请注意,您还可以查看 Web Animations API,它提供了以编程方式控制动画的方法。
const names = ["Peter", "Paul", "Mary"];
const displayElement = document.querySelector("#display");
const keyframes = [
{ filter: "blur(0)" },
{ filter: "blur(0.72em)" },
{ filter: "blur(0)" }
];
const duration = 2000;
function pickOne(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
let name = pickOne(names),
prevName = name;
displayElement.innerHTML = name;
setInterval(() => {
name = pickOne(names);
if (name !== prevName) {
displayElement.animate( keyframes, { duration } );
setTimeout(() => {
displayElement.innerHTML = name;
}, 1000);
prevName = name;
}
}, 3000);
#display {
font: 36px Arial, sans-serif;
}
<div id="display"></div>
就像我评论的一样,
animation
是指使用一次或连续动画,我们确实有自己的做事风格,但我建议使用 transition
以便在特定事件和时间灵活地设置动画。
由于您的动画设置为 2 秒,因此您可以像这样设置 css 过渡:
#display {
font: 36px Arial, sans-serif;
transition: filter 650ms;
}
然后利用 Javascript:
function blur_and_back(){
displayElement.style.filter = "filter:blur(0.72em)";
setTimeout(() => { displayElement.style.filter = "filter:blur(0)"},650);
}
每次你想要动画时调用 blur_and_back()
。
编辑:
基于 developer.mozilla.org,animation
的一个组成部分是 animation
是:
a style describing the CSS animation and a set of keyframes that indicate the start and end states of the animation’s style
通过start
和end
或from
和to
或0%
和100%
实际上是一次性使用动画,或使用 infinite
使其连续动画化。
他们还补充说:
you can create them without even having to know JavaScript.
同时 transition
再次基于 developer.mozilla.org:
Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time.
CSS transitions let you decide which properties to animate (by listing them explicitly), when the animation will start (by setting a delay), how long the transition will last (by setting a duration), and how the transition will run (by defining a timing function, e.g. linearly or quick at the beginning, slow at the end).
这就是我所说的灵活性。
我想这有点明显,即使是他们的字面英文定义。
不过,我再说一遍,我们确实有自己的做事风格,这只是一个建议。