I found out a difference between css3 keyframes and web animation api try this demo https://code.h5jun.com/pizi/edit?html,css,js,output
same options:
@keyframes test {
0% { transform: translateX(0px) translateY(0px);}
20% { transform: translateX(0px) translateY(50px);}
40% { transform: translateX(0px) translateY(100px);}
60% { transform: translateX(0px) translateY(150px);}
80% { transform: translateX(0px) translateY(200px);}
100% { transform: translateX(0px) translateY(300px);}
}
web animation api version:
block.animate([
{transform: 'none'},
{transform: 'translateY(100px)', offset: 0.2},
{transform: 'translateY(200px)', offset: 0.4},
{transform: 'translateY(300px)', offset: 0.6},
{transform: 'translateY(400px)', offset: 0.8},
{transform: 'none'},
], {
duration: 5000,
easing: 'ease',
})
but the result are totally different and i don't know why
In CSS animations, easing is applied between each keyframe. Any keyframe that doesn't specify an explicit animation-timing-function
, gets the computed animation-timing-function
from the element to which it is applied.
Since the initial value for animation-timing-function
is ease
, when your animation is applied, it is expanded to:
@keyframes test {
0% {
transform: translateX(0px) translateY(0px);
animation-timing-function: ease;
}
20% {
transform: translateX(0px) translateY(50px);
animation-timing-function: ease;
}
40% {
transform: translateX(0px) translateY(100px);
animation-timing-function: ease;
}
60% {
transform: translateX(0px) translateY(150px);
animation-timing-function: ease;
}
80% {
transform: translateX(0px) translateY(200px);
animation-timing-function: ease;
}
100% {
transform: translateX(0px) translateY(300px);
/* Note that specifying a timing function for an 100% / to
* keyframe has no effect since it applies until the _next_
* keyframe. */
}
}
Web Animations, on the other hand, allows you to specify easing on either the keyframe level or on the level of the whole animation (or both!). When you specify it for the whole animation, it runs across all keyframes, not between them individually.
In your example, you are setting the easing on the whole animation:
block.animate(
[
{ transform: 'none' },
{ transform: 'translateY(100px)', offset: 0.2 },
{ transform: 'translateY(200px)', offset: 0.4 },
{ transform: 'translateY(300px)', offset: 0.6 },
{ transform: 'translateY(400px)', offset: 0.8 },
{ transform: 'none' },
],
{
duration: 5000,
easing: 'ease', // <-- Whole animation easing
}
);
To specify it on each keyframe you could write:
block.animate(
[
{ transform: 'none', easing: 'ease' },
{ transform: 'translateY(100px)', easing: 'ease', offset: 0.2 },
{ transform: 'translateY(200px)', easing: 'ease', offset: 0.4 },
{ transform: 'translateY(300px)', easing: 'ease', offset: 0.6 },
{ transform: 'translateY(400px)', easing: 'ease', offset: 0.8 },
{ transform: 'none' },
],
5000
);
Or more simply:
block.animate(
{
transform: [
'none',
'translateY(100px)',
'translateY(200px)',
'translateY(300px)',
'translateY(400px)',
'none',
],
easing: 'ease',
},
5000
);
(Although this last syntax might not be supported as well in older versions of some browsers.)