Weird translation in JavaScript el.animate()

Viewed 62

I try to animate an element in JavaScript. My goal is to move the element from its current position to the cursor. I can't figure out why the element is not moving as expected. The X-translation is OK, but the Y-translation is in the wrong direction.

document.addEventListener('click', function(event) {
    document.getElementById("el").animate([
        { top: (event.clientY)+'px' },
        { left: (event.clientX)+'px' }        
    ], 
    { 
        // timing options
        duration: 1000,
        fill: 'forwards',                
    });
})
#el {
    position:absolute;
    top: 10px;
    left: 10px;
    background-color: cyan;
}
<div id="el">Click to move</div>

4 Answers

You've to include the "coordinates" of the "from" and "to" points. To get the "from" point, you've to store the mouse coordinates outside the click handler, like this:

const coords = {
  x: 10,
  y: 10
};
document.addEventListener('click', function(event) {
  document.getElementById("el").animate([{
      top: coords.y + 'px',
      left: coords.x + 'px'
    },
    {
      top: (event.clientY) + 'px',
      left: (event.clientX) + 'px'
    }
  ], {
    // timing options
    duration: 1000,
    fill: 'forwards',
  });
  coords.x = event.clientX;
  coords.y = event.clientY;
});
#el {
  position: absolute;
  top: 10px;
  left: 10px;
  background-color: cyan;
}
<div id="el">Click to move</div>

I recommend to use transform over left or top. Because with transform you have additional GPU acceleration witch increases the FPS

document.addEventListener('click', function(event) {
  document.getElementById("el").animate([
    { transform: `translate(${event.clientX - 10}px ,${event.clientY - 10}px)` } 
  ], 
  { 
    duration: 1000,
    fill: 'forwards',                
  });
})
#el {
      position:absolute;
    top: 10px;
    left: 10px;
      background-color: cyan;
      cursor: default;
}
<div id="el">Click to move</div>

And this decision is from me. Add a transition rule to your CSS for animation.

#el {
    position:absolute;
    top: 10px;
    left: 10px;
    background-color: cyan;
      
    transition: 1s; /*add this it*/
}

document.addEventListener('click', function(event) {
   let el = document.getElementById('el');
    el.style.left = event.clientX + "px";
    el.style.top = event.clientY + "px";   
});
#el {
    position:absolute;
    top: 10px;
    left: 10px;
    background-color: cyan;
      
    transition: 1s; /*add this it*/
}
<div id="el">Click to move</div>

Don't animate in JavaScript, animate in CSS.

document.addEventListener('click', function(event) {
 document.getElementById("el").style.top = event.clientY + "px";
 document.getElementById("el").style.left = event.clientX + "px";
})
#el {
      position: absolute;
      transition: all 1s;
      left: 10px;
      top: 10px;
      background-color: cyan;
}
<div id="el">Click to move</div>

Related