简体   繁体   English

使用 CSS Animation,如果我们需要再次动画,必须删除 class 并重新添加?

[英]Using CSS Animation, if we need to animate it again, must be remove the class and add it back?

Please see the demo below, or at https://jsfiddle.net/ut7y93hv/请参阅下面的演示,或在https://jsfiddle.net/ut7y93hv/

I am getting a random name out of Peter, Paul, and Mary, and if the name is different from before, then have the "blur out" effect, change the name, and then make it "blur in" (make it sharp again).我从 Peter、Paul 和 Mary 中随机取了一个名字,如果名字和以前不一样,那么就产生“模糊”效果,更改名称,然后使其“模糊”(再次变得清晰) )。

So right now I have to do所以现在我必须做

    setTimeout(() => {
      displayElement.classList.remove("blur-and-back");
    }, 2000);

which is to remove the class name after the animation is done.这是在 animation 完成后删除 class 名称。 Otherwise, if I just add the class name next time, it would be as if nothing happened -- it won't animate again.否则,如果我下次只添加 class 名称,就好像什么都没发生一样——它不会再动画了。 I also double checked: I cannot remove the class name and then immediately add it back, because it also will be as if nothing has happened.我还仔细检查了:我无法删除 class 名称,然后立即将其添加回来,因为它也会好像什么都没发生一样。

The question is: is there a way to do it more elegantly using CSS animation?问题是:有没有办法更优雅地使用 CSS animation? Somehow just to tell the animation to restart itself, without needing to remove the class and add the class back?不知何故只是告诉 animation 重新启动自己,而不需要删除 class 并添加 class 回来? It is also messy when it is done in ReactJS, because we also need to do the setTimeout() to do low level things "under the hood" to make it happen.当它在 ReactJS 中完成时,它也很混乱,因为我们还需要执行setTimeout()来“在后台”执行低级别的事情以实现它。

I may be able to make it a constantly repeating animation, but "pause" after 2 seconds using a setTimeout() , and then restart it again next time, but it may be worse if the setTimeout() is delayed for 16ms or 33ms, and then the animation is shifted more and more, and out of sync, after some time.我可以让它成为一个不断重复的 animation,但是使用setTimeout()在 2 秒后“暂停”,然后下次重新启动它,但如果setTimeout()延迟 16 毫秒或 33 毫秒,情况可能会更糟,然后 animation 移动得越来越多,并且在一段时间后不同步。

The need to start the animation and then set a timer to alter the text is somewhat messy too.需要启动 animation 然后设置一个计时器来更改文本也有点混乱。 I think I can first blur the text, and use the event animationend to change the text, and kickstart making it sharp again, and use the event animationend to remove the class, but this is also a bit messy.我想我可以先模糊文本,然后使用事件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>

No, you don't need to remove it at that time, you can simply remove it just before setting it on again and trigger a reflow in-between:不,您当时不需要将其删除,您可以在再次打开之前将其删除并在其间触发回流

 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>

Note that you could also have a look at the Web Animations API , which offer means to control your animations programmatically.请注意,您还可以查看Web 动画 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>

Just like what I commented, animation is meant to use once or continuous animation, we do have our own style of doing things, but I do recommend to use transition for flexibility of animating it in specific events and time.就像我评论的一样, animation意味着使用一次或连续 animation,我们确实有自己的做事风格,但我建议使用transition来灵活地在特定事件和时间进行动画处理。

Since your animation is set to 2 seconds, you can setup your css transition like this:由于您的 animation 设置为 2 秒,您可以像这样设置 css 转换:

#display {
  font: 36px Arial, sans-serif;
  transition: filter 650ms;
}

then harnessing Javascript:然后利用 Javascript:

function blur_and_back(){
   displayElement.style.filter = "filter:blur(0.72em)";
   setTimeout(() => { displayElement.style.filter = "filter:blur(0)"},650);
}

just call blur_and_back() everytime you want to animate it.每次你想要动画它时只需调用blur_and_back()

EDIT:编辑:

Based on developer.mozilla.org , one component of animation is that animation is:基于developer.mozilla.organimation animation

a style describing the CSS animation and a set of keyframes that indicate the start and end states of the animation's style描述 CSS animation 的样式和指示动画样式的开始和结束状态的一组关键帧

by means of start and end or from and to or 0% and 100% is literally a one time use of animation, or use infinite to continuously animate it.通过startendfromto0%100%从字面上看是 animation 的一次性使用,或使用infinite连续动画它。

They also added that:他们还补充说:

you can create them without even having to know JavaScript.甚至无需知道 JavaScript 就可以创建它们。

meanwhile the transition based on developer.mozilla.org again:同时再次基于developer.mozilla.orgtransition

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, eg linearly or quick at the beginning, slow at the end). CSS 过渡让您可以决定对哪些属性进行动画处理(通过明确列出它们)、animation 何时开始(通过设置延迟)、过渡将持续多长时间(通过设置持续时间)以及过渡将如何运行(通过定义一个时序 function,例如开始时线性或快,结束时慢)。

This is what I mean by flexibility.这就是我所说的灵活性。

I guess it's kinda obvious, even for their literal English definition.我想这有点明显,即使对于他们的字面英文定义也是如此。

Yet, I'll say it again, we do have our own style of doing things, and this is just a recommendation.但是,我再说一遍,我们确实有自己的做事风格,这只是一个建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM