Please see the demo below, or at 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).
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. Otherwise, if I just add the class name next time, it would be as if nothing happened -- it won't animate again. 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.
The question is: is there a way to do it more elegantly using CSS animation? Somehow just to tell the animation to restart itself, without needing to remove the class and add the class back? 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.
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.
The need to start the animation and then set a timer to alter the text is somewhat messy too. 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.
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>