I have an animated HTML element (box
) as follow:
<div id="box"></div>
The box is initially animated to 200 pixels to the right with a duration of 4 seconds.
.anim {
animation-name: anim;
animation-duration: 4s;
animation-timing-function: linear; /* cubic-bezier(0.1, -0.6, 0.2, 0); */
}
@keyframes anim {
0% { left: var(--xs); }
100% { left: var(--xe); }
}
Here the JavaScript that starts the animation:
var box = document.getElementById('box');
box.style.setProperty('--xs', '0px');
box.style.setProperty('--xe', '200px');
box.classList.add('anim');
After one second, the final position is updated to 400 pixels:
setTimeout(() => {
box.style.setProperty('--xe', '400px');
},1000)
Of course, when the final position is updated, the box jumps from one position to the other. Is there a way to get a smooth transition to avoid the "teletransportation" effect?
Here is the JSFiddle: https://jsfiddle.net/Imabot/53hLe2zq/
2
Answers
you can use the following code to create a smooth transition between the two states:
CSS:
HTML:
JS:
This will create a smooth transition between the two states, with a duration of 4s.
Here is the JSFiddle: https://jsfiddle.net/1fuq9ebL/
Change its
animation-duration
to 8 seconds:Originally, the box was meant to move 200 pixels in 4 seconds; by a simple division we know that its speed is set to 50px/s.
After one second, when the callback is fired, the length suddenly doubles to 400; this cause the box’s speed to increase to 100px/s. However, since it is already 50px from the original position, it must "teleport" to 100px to be able to travel the rest in 3 seconds.
So, to prevent it from teleporting we need to give it more time, making its speed remain consistent. Again, we need math:
Add it to 1 second we already used to travel the first 50 pixels and we have the final answer: 8 seconds.
And that’s all there is to it! Should your actual input changes, you can simply convert the formula above to a function. Note that this won’t work with any
animation-timing-function
other thanlinear
.Try it: