Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Realistic mouse movement coordinates in javascript?

Tags:

javascript

In javascript, is there a way I can create a variable and a function that "simulates" smooth mouse movement? i.e., say the function simulates a user starts from lower left corner of the browser window, and then moves mouse in a random direction slowly...

The function would return x and y value of the next position the mouse would move each time it is called (would probably use something like setInterval to keep calling it to get the next mouse position). Movement should be restricted to the width and height of the screen, assuming the mouse never going off of it.

What I don't want is the mouse to be skipping super fast all over the place. I like smooth movements/positions being returned.

like image 589
Rolando Avatar asked Oct 26 '15 06:10

Rolando


People also ask

Can you move mouse with JavaScript?

You can't move the mouse pointer using javascript, and thus for obvious security reasons. The best way to achieve this effect would be to actually place the control under the mouse pointer.

How do I find my mouse pointer coordinates?

Once you're in Mouse settings, select Additional mouse options from the links on the right side of the page. In Mouse Properties, on the Pointer Options tab, at the bottom, select Show location of pointer when I press the CTRL key, and then select OK. To see it in action, press CTRL.


1 Answers

A "realistic mouse movement" doesn't mean anything without context :

Every mouse user have different behaviors with this device, and they won't even do the same gestures given what they have on their screen.

If you take an FPS game, the movements will in majority be in a small vertical range, along the whole horizontal screen.
Here is a "drip painting" I made by recording my mouse movements while playing some FPS game.

If we take the google home page however, I don't even use the mouse. The input is already focused, and I just use my keyboard.

On some infinite scrolling websites, my mouse can stay at the same position for dozens of minutes and just go to a link at some point.

I think that to get the more realistic mouse movements possible, you would have to record all your users' gestures, and repro them.

Also, a good strategy could be to get the coordinates of the elements that will attract user's cursor the more likely (like the "close" link under SO's question) and make movements go to those elements' coordinates.

Anyway, here I made a snippet which uses Math.random() and requestAnimationFrame() in order to make an object move smoothly, with some times of pausing, and variable speeds.

// Canvas is here only to show the output of  function
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
document.body.appendChild(canvas);
var maxX = canvas.width = window.innerWidth;
var maxY = canvas.height = window.innerHeight;

window.onresize = function(){  
  maxX = canvas.width = window.innerWidth;
  maxY = canvas.height = window.innerHeight;
  }
gc.onclick = function(){
  var coords = mouse.getCoords();
  out.innerHTML = 'x : '+coords.x+'<br>y : '+coords.y;
  }

var Mouse = function() {
  var that = {},
    size = 15,
    border = size / 2,
    maxSpeed = 50, // pixels per frame
    maxTimePause = 5000; // ms

  that.draw = function() {
    if (that.paused)
      return;
    that.update();
    // just for the example
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if(show.checked){
      ctx.drawImage(that.img, that.x - border, that.y - border, size, size)
      }
    // use requestAnimationFrame for smooth update
    requestAnimationFrame(that.draw);
  }

  that.update = function() {
    // take a random position, in the same direction
    that.x += Math.random() * that.speedX;
    that.y += Math.random() * that.speedY;
    // if we're out of bounds or the interval has passed
    if (that.x <= border || that.x >= maxX - border || that.y <= 0 || that.y >= maxY - border || ++that.i > that.interval)
      that.reset();
  }
  that.reset = function() {
    that.i = 0; // reset the counter
    that.interval = Math.random() * 50; // reset the interval
    that.speedX = (Math.random() * (maxSpeed)) - (maxSpeed / 2); // reset the horizontal direction
    that.speedY = (Math.random() * (maxSpeed)) - (maxSpeed / 2); // reset the vertical direction
    // we're in one of the corner, and random returned farther out of bounds
    if (that.x <= border && that.speedX < 0 || that.x >= maxX - border && that.speedX > 0)
    // change the direction
      that.speedX *= -1;
    if (that.y <= border && that.speedY < 0 || that.y >= maxY - border && that.speedY > 0)
      that.speedY *= -1;
    // check if the interval was complete
    if (that.x > border && that.x < maxX - border && that.y > border && that.y < maxY - border) {
      if (Math.random() > .5) {
        // set a pause and remove it after some time
        that.paused = true;
        setTimeout(function() {
          that.paused = false;
          that.draw();
        }, (Math.random() * maxTimePause));

      }
    }
  }

  that.init = function() {
    that.x = 0;
    that.y = 0;
    that.img = new Image();
    that.img.src ="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAABJUlEQVRIic2WXbHEIAyFI6ESKgEJkVIJlYCTSqiESIiESqiEb19gL9Od3f5R5mbmPPHwBTgnIPJfChiAGbCkCQgtG7BpmgAWIALaDDyOI2bGuq40BasqIoKZATgwNAWHEEjHbkBsBhYRVJUYIwBNwVlFaVOwiDDPMylmQ1OwquY7d0CBrglYkuEeidoeOKt61I6Cq0ftKFhqR+0MOKuo2BQsInnndvnOr4JvR+0qWO5G7Q44K0XtOXDf96jqh9z9WXAy1FJ8l0qd+zbtvU7lWs7wIzkuh8SvpqqDi3zGndPQauDkzvdESm8xZvbh4mVZ7k8ud/+aR0C3YPk7mVvgkCZPVrdZV3dHVem6bju1roMPNmbAmq8kG+/ynD7ZwNsAVVz9dL0AhBrZq7F+CSQAAAAASUVORK5CYII=";
    that.reset();
  }
  that.getCoords = function(){
    return {x: that.x, y:that.y};
  }
  that.init()
  return that;
}
var mouse = new Mouse()
mouse.draw();
html,body {margin: 0}
canvas {position: absolute; top:0; left:0;z-index:-1}
#out{font-size: 0.8em}
<label for="show">Display cursor</label><input name="show" type="checkbox" id="show" checked="true"/><br>
<button id="gc">get cursor Coords</button>
<p id="out"></p>
like image 82
Kaiido Avatar answered Oct 31 '22 10:10

Kaiido