Reputation: 100
I watched Jake Archibald's talk recently. He gave an example in his speech where he says to use requestAnimationFrame twice to delay applying a CSS style to perform a CSS animation.
See https://youtu.be/cCOL7MC4Pl0?t=1337
I reproduced the example to test it, but without luck:
Jake Archibald's a solution was proposed. use a two-layer nested requestAnimationFrame
But it doesn't seem to work for me. Why?
Here is the code snippet that should work but doesn't:
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
box.style.transition = 'transform 1s ease-out';
requestAnimationFrame(()=>{
requestAnimationFrame(()=>{
box.style.transform = 'translateX(250px)';
});
});
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
}
<div id="box">box</div>
Upvotes: 0
Views: 146
Reputation: 136755
I really hate videos so I didn't checked it entirely, but certainly they already had that #box
element translated before they call that javascript.
If they didn't then it would actually perform the transition from translateX(0)
to translateX(1000px)
during one frame, and right after transition from wherever it was (probably not far from begining left) to translateX(250px)
.
So for a fix, you can set the initial translateX
value in CSS.
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
box.style.transition = 'transform 1s ease-out';
requestAnimationFrame(()=>{
requestAnimationFrame(()=>{
box.style.transform = 'translateX(250px)';
});
});
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
transform: translateX(1000px);
}
You have to scroll to the right now.
<div id="box">box</div>
Now, you should really not use that double requestAnimationFrame hack. Instead identify the problem and use a proper fix (i.e force a reflow).
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
box.offsetWidth; // force reflow so our box is translated to initial position
box.style.transition = 'transform 1s ease-out';
box.style.transform = 'translateX(250px)';
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
}
<div id="box">box</div>
Upvotes: 0
Reputation: 497
Something like this ?
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
requestAnimationFrame(()=>{
box.style.transition = 'transform 1s ease-out';
requestAnimationFrame(()=>{
box.style.transform = 'translateX(250px)';
});
});
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
}
<div id="box">box</div>
Upvotes: 2