I am handling 3 events (codepen): mouseenter scales the element, mousemove rotates and mouseleave resets to original position. Please, see video showing the problem. At the end of the video, the element does not return to its original position. I’ve noticed that this happens more often if you trigger an mousemove event very, very quickly within an element. Less frequently, it can also occur in the case of rapid alternation of mouseenter-mouseleave.
There is one condition and general clarification. This frames cleaner here overAnimation.cancel()
in the mouseleave handler might seem unnecessary. But in my project this element is located in Vue <transition-group>
component and I have to leave cleaner in case to not brake component’s own animation because without cancel()
the component just refuse to play his animation.
<div class="item"></div>
const itemRef = document.querySelector('.item')
let overAnimation = null
itemRef.addEventListener('mouseleave', (e) => {
overAnimation = itemRef.animate([
{
transform: 'none',
}
], {duration: 1000, fill: 'forwards'})
overAnimation.onfinish = () => {
overAnimation.cancel()
}
})
itemRef.addEventListener('mousemove', (e) => {
const x = e.offsetX
overAnimation = itemRef.animate([
{
transform: `scale(1.6) rotate(${x}deg)`,
}
], {duration: 1000, fill: 'forwards'})
})
itemRef.addEventListener('mouseenter', (e) => {
overAnimation?.cancel()
overAnimation = itemRef.animate([
{
transform: 'scale(1.6)',
}
], {duration: 1000, fill: 'forwards'})
})
body {
background: #55b0fa;
}
.item {
width: 200px;
height: 200px;
margin: 100px auto;
background-color: blue;
}