现实的鼠标移动坐标在javascript

Realistic mouse movement coordinates in javascript?

本文关键字:坐标 javascript 移动 鼠标      更新时间:2023-09-26

在javascript中,是否有一种方法可以创建一个变量和一个"模拟"平滑鼠标移动的函数?例如,假设该函数模拟用户从浏览器窗口的左下角开始,然后向随机方向缓慢移动鼠标…

函数将在每次调用时返回鼠标将移动的下一个位置的x和y值(可能会使用类似setInterval的东西来不断调用它以获得下一个鼠标位置)。移动应该限制在屏幕的宽度和高度,假设鼠标永远不会离开它。

我不想要的是鼠标跳得太快。我喜欢流畅的动作/位置返回

如果没有上下文,"逼真的鼠标移动"没有任何意义:

每个鼠标用户对这个设备都有不同的行为,他们甚至不会做出相同的手势,因为他们的屏幕上有。

如果你是一款FPS游戏,那么移动将主要是在一个小的垂直范围内,沿着整个水平屏幕。
这是我在玩一些FPS游戏时记录鼠标运动的"滴画"。

如果我们以谷歌主页为例,我甚至不用鼠标。输入已经聚焦了,我只需要使用键盘。

在一些无限滚动的网站上,我的鼠标可以在同一个位置停留几十分钟,然后在某个点进入链接。

我认为,为了获得更逼真的鼠标移动,你必须记录所有用户的手势,并再现它们。

此外,一个好的策略可能是获得更有可能吸引用户光标的元素的坐标(如SO问题下的"close"链接),并使移动指向这些元素的坐标。

无论如何,这里我做了一个片段,使用Math.random()requestAnimationFrame(),以使一个对象顺利移动,有一些暂停时间,和可变的速度。

// 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>

上次我听说浏览器的鼠标位置不能用JavaScript改变,所以这个问题真的没有答案"as is"。鼠标位置可以被锁定。我不确定是否有可能实现允许设置位置的自定义光标。这将包括隐藏和锁定股票游标。

让一些东西平滑地跟随光标是非常直接的。你也许可以逆转这个过程来达到你所需要的。下面的代码片段每帧计算光标和div之间的距离,然后将div向光标移动该距离的10%:

http://jsfiddle.net/hpp0qb0d/

var p = document.getElementById('nextmove')
var lastX,lastY,cursorX,cursorY;
window.addEventListener('mousemove', function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
})
setInterval(function(){
    var newX = p.offsetLeft + (cursorX - lastX)/10
    var newY = p.offsetTop + (cursorY - lastY)/10
    p.style.left = newX+'px'
    p.style.top = newY+'px'
    lastX = p.offsetLeft
    lastY = p.offsetTop
},20)