xxx xxx - 4 months ago 24
jQuery Question

How do I properly get the mouse position in Javascript?

I made a small JS program that is supposed to simulate ball physics, where the HTML canvas is supposed to resize to the window height. I have made it so that the canvas resizes, but when it resizes the mouse position doesn't work right, and the balls don't appear on the screen when it is clicked (like they're supposed to). I've been using clientX & clientY to get the mouse position, but I don't know if that's the best method. Here is the code:



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




Answer

If you want to get the mouse position relative to the canvas top-left point, you should use event.offsetX and event.offsetY (given that you have attached the mousemove event handler to the canvas element).

Try this:

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