I want to get the correct coordinates when the element that moves with CSS Animation stops.
The getBoundingClientRect value continues to change during the animation. My goal is to get the exact coordinate values of the elements when I pause the animation.
I paused the animation and got the coordinates. But the coordinates were not accurate.
The way I tried to force myself to achieve my goal is the 'thinkCoords' Function in the code below.
Delay with setTimeout to obtain the correct current coordinates.
But what I want is no delay. I want to get the correct coordinates at the same time as the animation pause.
To get the exact current coordinates the moment the animation stops, What should I do?
let el = document.getElementById('el');
let stopCoords = document.getElementById('stopCoords');
let currentCoords = document.getElementById('currentCoords');
let thinkCoords =
document.getElementById('thinkCoords');
let stopCoordsText = document.getElementById('stopCoordsText');
let currentCoordsText = document.getElementById('currentCoordsText');
let thinkCoordsText = document.getElementById('thinkCoordsText');
stopCoords.addEventListener('click',()=>{
el.classList.toggle('stop')
let coordsX = el.getBoundingClientRect().x;
stopCoordsText.innerText = `${coordsX}`;
})
currentCoords.addEventListener('click',()=>{
let coordsX = el.getBoundingClientRect().x;
currentCoordsText.innerText = `${coordsX}`;
})
thinkCoords.addEventListener('click',()=>{
el.classList.toggle('stop');
setTimeout(()=>{
let coordsX = el.getBoundingClientRect().x;
thinkCoordsText.innerText = `${coordsX}`;
},1000)
})
#el {
width: 2px;
height: 20px;
background: #000;
animation-name: moving;
animation-duration: 0.9s;
animation-delay: none;
animation-iteration-count: infinite;
animation-play-state: running;
animation-timing-function: ease;
animation-fill-mode: fowards;
}
#el.stop{
animation-play-state: paused;
}
@keyframes moving{
0% {
transform:translate(0em);
}
50%{
transform:translate(10em);
}
100%{
transform:translate(0em);
}
}
button {
margin-top:100px;
}
<div id="el"></div>
<button id='stopCoords'>anime Paused and Coords value</button>
<button id='currentCoords'>Current Coords value</button>
<button id='thinkCoords'>
Try my think code
</button>
<p>stopping Coords : <span id='stopCoordsText'></span> </p>
<p>current Coords : <span id='currentCoordsText'></span> </p>
<p>Try my think Coords : <span id='thinkCoordsText'></span> </p>
The animation's time will get updated only later on (I would have thought at the next painting frame, but at least in Firefox it seems to not be always the case...), and that's only in this time update that the pause will become effective.
We apparently don't have an event for when the animation's pause actually occur, so there doesn't seem to be a bullet-proof hook for this.
However since you wanted to have it all synchronous, this can actually be done by updating the .currentTime
of the animation through its Animation
interface:
let el = document.getElementById('el');
let stopCoords = document.getElementById('stopCoords');
let currentCoords = document.getElementById('currentCoords');
let thinkCoords = document.getElementById('thinkCoords');
let stopCoordsText = document.getElementById('stopCoordsText');
let currentCoordsText = document.getElementById('currentCoordsText');
let thinkCoordsText = document.getElementById('thinkCoordsText');
stopCoords.addEventListener('click', () => {
// access you animation as an Animation object
const anim = el.getAnimations()[0];
anim.pause();
anim.currentTime = anim.currentTime; // force pausing synchronously
let coordsX = el.getBoundingClientRect().x;
stopCoordsText.innerText = `${coordsX}`;
})
currentCoords.addEventListener('click', () => {
let coordsX = el.getBoundingClientRect().x;
currentCoordsText.innerText = `${coordsX}`;
})
#el {
width: 2px;
height: 20px;
background: #000;
animation-name: moving;
animation-duration: 0.9s;
animation-delay: none;
animation-iteration-count: infinite;
animation-play-state: running;
animation-timing-function: ease;
animation-fill-mode: fowards;
}
#el.stop {
animation-play-state: paused;
}
@keyframes moving {
0% {
transform: translate(0em);
}
50% {
transform: translate(10em);
}
100% {
transform: translate(0em);
}
}
button {
margin-top: 100px;
}
<div id="el"></div>
<button id='stopCoords'>anime Paused and Coords value</button>
<button id='currentCoords'>Current Coords value</button>
<p>stopping Coords : <span id='stopCoordsText'></span> </p>
<p>current Coords : <span id='currentCoordsText'></span> </p>