3

I'm using a small script to follow the cursor with a div element. This script makes the element strictly follow the cursor. What I'm trying to do is to add some kind of duration to the process of "following" the cursor. I tried CSS transitions but the animation always ended up breaking. Can somebody please help me with this?

Let's say mouse is somewhere, and then it changes position by around 100px. I want to specify the duration like if i was using CSS... But the thing is that I can not use any transitions but only some javascript magic instead...

document.body.addEventListener("mousemove", function(e) {

  var curX = e.clientX;
  var curY = e.clientY;

  document.querySelector('mouse').style.left = curX - 10 + 'px';
  document.querySelector('mouse').style.top = curY - 10 + 'px';

});
body {
  background: #333;
  height: 500px;
  width: 500px;
}
mouse {
  display: block;
  position: fixed;
  height: 20px;
  width: 20px;
  background: #fff;
  border-radius: 50%;
}
<body>
  <mouse></mouse>
</body>
I was wondering how to add a transition without using the CSS but I'm not the most advanced when it comes to JavaScript.

[edit] : I don't wanna use window.setTimeout.

[edit 2] : I wanted to use transition: 0.1s; but as I said it broke the effect when user moved the mouse too quickly.

7
  • Hi there, does this look like what you are trying to do? codepen.io/matthewpageuk/pen/ZwYEKp the ball follows the mouse? Commented Jan 22, 2019 at 19:19
  • Yes exactly! But i'm wondering... your code executes only on mouse move... and when the mouse stops mooving... then I have a problem... Thanks anyway! Commented Jan 22, 2019 at 19:38
  • So if the mouse is not triggering events, and you don't want CSS transitions nor setTimeout, then how do you imagine doing the animation? Commented Jan 22, 2019 at 19:48
  • Then the animation would have to run constantly but it's not a good idea... Commented Jan 22, 2019 at 19:53
  • Have you looked at window.requestAnimationFrame() , it was kind of meant for this type of thing. You basically want to do what you do in the mousemove block but 30 or 60 times per second. Commented Jan 22, 2019 at 20:05

2 Answers 2

2

There's a whole bunch of ways to do this, as you can see in the other answers, each with its own "feel". I'm just adding one more, where the dot approaches the cursor by a percentage of the remaining distance.

let curX = 0, curY = 0, elemX = null, elemY = null;
document.body.addEventListener("mousemove", function(e) {
  curX = e.clientX;
  curY = e.clientY;
  if (elemX === null) [ elemX, elemY ] = [ curX, curY ];
});

let amt = 0.1; // higher amount = faster tracking = quicker transition
let elem = document.querySelector('mouse');
let frame = () => {
  requestAnimationFrame(frame);
  elemX = (elemX * (1 - amt)) + (curX * amt);
  elemY = (elemY * (1 - amt)) + (curY * amt);
  elem.style.left = `${elemX}px`;
  elem.style.top = `${elemY}px`;
};
frame();
body {
  position: absolute;
  background: #333;
  left: 0; top: 0; margin: 0; padding: 0;
  height: 100%;
  width: 100%;
}
mouse {
  display: block;
  position: absolute;
  height: 20px; margin-left: -10px;
  width: 20px; margin-top: -10px;
  background: #fff;
  border-radius: 50%;
}
<body>
  <mouse></mouse>
</body>

Sign up to request clarification or add additional context in comments.

1 Comment

Good solution if you ask me!
1

You can use setTimeout() function, to introduce a delay:

document.body.addEventListener("mousemove", function(e) {
  var delay=250 //Setting the delay to quarter of a second
  setTimeout(()=>{
      var curX = e.clientX;
      var curY = e.clientY;
      
      document.querySelector('mouse').style.left = curX - 10 + 'px';
      document.querySelector('mouse').style.top = curY - 10 + 'px';
  },delay)

});
body {
  background: #333;
  height: 500px;
  width: 500px;
}
mouse {
  display: block;
  position: fixed;
  height: 20px;
  width: 20px;
  background: #fff;
  border-radius: 50%;
}
<body>
  <mouse></mouse>
</body>

Or, to avoid trailing, use an interval and move the cursor to the correct direction (change ratio to set the speed ratio):

var curX,curY
document.body.addEventListener("mousemove", function(e) {
    curX = e.clientX;
    curY = e.clientY;

});
setInterval(()=>{
    var ratio=5
    var x=document.querySelector('mouse').offsetLeft+10
    var y=document.querySelector('mouse').offsetTop+10
    document.querySelector('mouse').style.left=((curX-x)/ratio)+x-10+"px"
    document.querySelector('mouse').style.top=((curY-y)/ratio)+y-10+"px"
},16)
body {
  background: #333;
  height: 500px;
  width: 500px;
}
mouse {
  display: block;
  position: fixed;
  height: 20px;
  width: 20px;
  background: #fff;
  border-radius: 50%;
}
<body>
  <mouse></mouse>
</body>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.