【问题标题】:How do I properly get the mouse position in Javascript?如何在 Javascript 中正确获取鼠标位置?
【发布时间】:2016-03-21 22:22:38
【问题描述】:

我制作了一个小 JS 程序,它应该模拟球的物理特性,其中 HTML 画布应该调整到窗口高度。我已经使画布调整大小,但是当它调整大小时,鼠标位置无法正常工作,并且在单击时球不会出现在屏幕上(就像它们应该出现的那样)。我一直在使用 clientX 和 clientY 来获取鼠标位置,但我不知道这是否是最好的方法。代码如下:

<!DOCTYPE <!DOCTYPE html>

<html>

<head>

	<style type="text/css">


		BODY {
            background: #00000;
		}

		#myCanvas {
			background-color: black;
		}



	</style>

	<title>Ball Simulator</title>

	<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>

	<script type="text/javascript">
		
	$(function() {
	  c = document.getElementById('myCanvas');
	  ctx = c.getContext("2d");
	  objects = [];
	  init()
	  c.addEventListener("mousedown", onMouseDown);
	  c.addEventListener("mouseup", onMouseUp);
	  ctx.fillStyle = "#FFFFFF";
	});

	function resizeCanvas() {
	  c.width = window.innerWidth;
	  c.height = window.innerHeight;
	}

	function ball(x, y, radius, xVel, yVel) {
	  this.x = x;
	  this.y = y;
	  this.radius = radius;
	  this.xVel = xVel;
	  this.yVel = yVel;
	  this.direction = Math.random() * Math.PI * 2

	  objects.push([x, y, radius, xVel, yVel, this.direction])
	};

	function stylusBall(x, y, radius) {

	  ctx.beginPath();
	  ctx.arc(x, y, radius, 0, 2 * Math.PI);
	  ctx.fill();

	}

	function getDistance(x1, y1, x2, y2) {

	  return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));

	};

	function getVerticalDistance(y1, y2) {
	  return y2 - y1
	};

	function getAngle(x1, y1, x2, y2) {

	  return Math.atan2(x2 - x1, y2 - y1);

	};

	function updateData() {
	  ctx.clearRect(0, 0, 6000, 3100);
	  for (i = 0; i < objects.length; i++) {
	    var close = false
	    var x = objects[i][0];
	    var y = objects[i][1];
	    var radius = objects[i][2];
	    var xVel = objects[i][3];
	    var yVel = objects[i][4];
	    var dir = objects[i][5];

	    for (n = 0; n < objects.length; n++) {

	      if (n != i) {
	      	close = false
	        var nX = objects[n][0];
	        var nY = objects[n][1];
	        var nRadius = objects[n][2];
	        var nAngle = getAngle(x, y, nX, nY);

	        var distance = getDistance(x, y, nX, nY);

	        if (distance == (nRadius + radius) || distance < (nRadius + radius)) {

	          var bounceForce = 1.5
	          xVel = xVel * -1 + bounceForce * Math.cos(nAngle);
	          yVel = yVel * -1 + bounceForce * Math.sin(nAngle);
	          close = true

	        };

	      };

	    }

	    if (getVerticalDistance(y, window.innerHeight - 5 - radius) > 0 && !close) {
	      yVel += 2;
	    } else if (getVerticalDistance(y, window.innerHeight - 5 - radius) < 0) {
	      yVel = yVel * -1;

	      if (getVerticalDistance(y, window.innerHeight - 5 - radius) < -20) {
	        y = y - 50
	      }
	    }

	    yVel *= 0.97;
	    xVel *= 0.99;

	    objects[i][3] = xVel
	    objects[i][4] = yVel

	    objects[i][0] = x + xVel
	    objects[i][1] = y + yVel

	  };

//	  window.requestAnimationFrame(updateData)

	};

	function drawArrow(x1, y1, x2, y2) {

	}

	function mouseMove(e) {
	  mouseX = e.clientX;
	  mouseY = e.clientY;
	}

	function onMouseDown() {
	  createRadius = 5;

	  anim = requestAnimationFrame(increase);
	};

	function increase() {
	  if (createRadius < 80) {
	    createRadius += 3;
	  }
	  newStylus = new stylusBall(mouseX, mouseY, createRadius)
	  anim = requestAnimationFrame(increase);
	};

	function onMouseUp() {
	  window.cancelAnimationFrame(anim);
	  newBall = new ball(mouseX, mouseY, createRadius, 0, 0);
	};

	function render() {

	  for (i = 0; i < objects.length; i++) {
	    ctx.beginPath();

	    ctx.arc(objects[i][0], objects[i][1], objects[i][2], 0, 2 * Math.PI);

	    ctx.fill();
	  };
//	  window.requestAnimationFrame(render)
	};


	function loop() {
		c.width = window.innerWidth;
		c.height = window.innerHeight;
		updateData();
		render();
		window.requestAnimationFrame(loop);
	}

	function init() {
	  loop();
	}
	</script>

</head>

  <body style="margin: 0;">

    <canvas id='myCanvas' onmousemove="mouseMove(event)">

  </body>

</html>

【问题讨论】:

  • 您可能有兴趣尝试这个流行的动画框架:Phaser。请参阅ball 示例。
  • 首先,格式化您的代码。现在很难读。接下来,制作最小的、可行的示例来显示您的问题。接下来,clientX 和 clientY 应该可以正常工作。到底出了什么问题?
  • 查看以前的Q&A,它展示了如何在用户调整大小和滚动时有效地获取鼠标位置。

标签: javascript jquery html canvas


【解决方案1】:

我认为这可以提供帮助,您需要获取鼠标相对于画布的位置。所以创建一个函数来获取鼠标位置:

function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

然后,当您为 mousedown 和 mouseup 事件添加事件侦听器时,您可以设置鼠标位置:

canvas.addEventListener('mousedown', function(evt) {
    isMouseDown = true;
    mousePos = getMousePos(canvas, evt);
    message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
    writeMessage(canvas, message);

  }, false);

【讨论】:

  • 这是一个“好的”解决方案。它可以变得更高效,因为边界矩形通常只在调整大小和滚动时发生变化。因此,您可以保存 rect.leftrect.top 并在 `getMousePos' 中重用它们(而不是重新计算它们)。
【解决方案2】:

如果您想获取相对于画布左上角的鼠标位置,您应该使用 event.offsetX 和 event.offsetY(假设您已将 mousemove 事件处理程序附加到画布元素)。

试试这个:

function mouseMove(e) {
      var mouseX = e.offsetX;
      var mouseY = e.offsetY;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 2013-05-14
    相关资源
    最近更新 更多