I wanted my page to start with a simple animation which introduces what I can do “hi, my name is Paul and I make websites” sort of thing.
In order to achieve it I thought using the Javascript Web Animations API would be a good chance to instantly demonstrate my abilities with vanilla javascript (I am making sections for demonstrating my abilities with frameworks and WordPress), however, after beginning I am noticing a few weird things happening, possibly due to my not using it properly.
const fade = (a = 0, b = 1) => {
return [
{ opacity: a },
{ opacity: b }
];
}
const glideX = (a = '-10000px', b = '0px') => {
return [
{ marginLeft: a, position: 'absolute' },
{ display: 'block', offset:0.1 },
{ marginLeft: b, position: 'unset' }
];
}
const glideY = (a = '-10000px', b = '0px') => {
return [
{ marginTop: a, position: 'absolute' },
{ display: 'block', offset:0.1 },
{ marginTop: b, position: 'unset' }
];
}
const animateSettings = (dur = 1500, it = 1, fill = 'forwards', ease = 'ease-in-out') => {
return {
duration: 1500,
iterations: 1,
fill: 'forwards',
easing: 'ease-in-out'
};
}
const start = h1.animate( fade(), animateSettings() );
start.onfinish = () => {
myNameIs.style.display = 'block';
const nameIn = myNameIs.animate( glideX(), animateSettings() );
nameIn.onfinish = () => {
const welcomeGo = h1.animate ( glideY( '0px', '10000px' ), animateSettings() )
welcomeGo.onfinish = () => {
console.log('all done');
}
}
}
Codepen: https://codepen.io/makingstuffs/pen/xxKVoKK
I want the initial text Hi to fade in. When that completes I want My name is Paul to come in from the left When that completes I want Hi to fall down the page.
This is the opening three frames from the animation and I have got it to work using the onfinish event/promise.
However, one issue is that the final frame seems to also affect the text from the frame prior to it.
I wanted to ask if this is something that is a result of how I am using the API or if this is a bug in the API and I would be better of simply using CSS keyframes and chaining event listeners which listen for each transition to finish and then apply a specific keyframes class?
Both are good candidates to use in your project. However do note that the Web Animations API is not (yet) supported in Safari, so it will break there.
A couple of things I'm noticing in your code.
transform
property since it is more performant for animations and does not interfere with other elements in the flow of the document. My guess is that this causes the interference between your elements.finish
event. Although that is an option when the duration of the animation is dynamic, it does not seem relevant to your case. When firing consequent animations you could use the delay
property of an animation.What you want to achieve
The first animation has to start instantly and has a duration of 1500
milliseconds. The seconds animation has to start after the first one has finished. Simply add a delay of 1500
milliseconds to make it start after the first one.
The third animation has to start after the first two animations are finished. This adds up to 1500 * 2
milliseconds in a delay of the starting time. I think that this should get you a bit further.
In CSS it would look like this:
.el-one { animation: first-animation 1500ms forwards ease-in-out; }
.el-two { animation: second-animation 1500ms 1500ms forwards ease-in-out; }
.el-three { animation: third-animation 1500ms 3000ms forwards ease-in-out; }
In your JS you would have to create 3 different animation settings. You already have a functions which offers you control over your animation properties, rewrite it to this:
const animateSettings = (delay = 0) => ({
delay: delay,
duration: 1500,
iterations: 1,
fill: 'forwards',
easing: 'ease-in-out'
});
const animationOne = elementOne.animate(yourFirstAnimation, animateSettings());
const animationTwo = elementTwo.animate(yourSecondAnimation, animateSettings(1500));
const animationThree = elementThree.animate(yourThirdAnimation, animateSettings(3000));
When to use the Web Animations API or CSS Keyframes?
It depends if you need calculations for your animation. If you can't hardcode your animation in CSS and you need to calculate a distance from point a to point b use the Web Animations API or maybe the duration, delay or any other property depends on the input of a user, use the API.
If you already know where point a and point b are going to be in terms of pixels, percentages, etc. then it is easier to use CSS Keyframes.
Why CSS transforms?
Transforms are essential to having animations with good performance. They work so well because when an element is transformed it is never taken away from the flow, but only the visual representation of the element is being manipulated. This prevents the whole page from being repainted every time an element is moved, such as what happens when you use the margin
or top
and left
properties. The chrome devtools have a tool to see what is going on with repaints.
Conclusion
transform
property to manipulate an element, it is better for performance and does not mess up your flow.