2016-03-21 3 views
-1

Я сделал небольшую программу JS, которая должна имитировать физику шара, где холст HTML должен изменяться до высоты окна. Я сделал это так, чтобы размер холста изменился, но когда он изменил размер, положение мыши не работает правильно, и шары не отображаются на экране при нажатии (как и предполагалось). Я использую clientX & clientY, чтобы получить позицию мыши, но я не знаю, лучший ли это метод. Вот код:Как правильно получить положение мыши в Javascript?

<!DOCTYPE <!DOCTYPE html> 
 

 
<html> 
 

 
<head> 
 

 
\t <style type="text/css"> 
 

 

 
\t \t BODY { 
 
      background: #00000; 
 
\t \t } 
 

 
\t \t #myCanvas { 
 
\t \t \t background-color: black; 
 
\t \t } 
 

 

 

 
\t </style> 
 

 
\t <title>Ball Simulator</title> 
 

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

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

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

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

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

 
\t function stylusBall(x, y, radius) { 
 

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

 
\t } 
 

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

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

 
\t }; 
 

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

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

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

 
\t }; 
 

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

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

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

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

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

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

 
\t   }; 
 

 
\t  }; 
 

 
\t  } 
 

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

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

 
\t  yVel *= 0.97; 
 
\t  xVel *= 0.99; 
 

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

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

 
\t }; 
 

 
// \t window.requestAnimationFrame(updateData) 
 

 
\t }; 
 

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

 
\t } 
 

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

 
\t function onMouseDown() { 
 
\t createRadius = 5; 
 

 
\t anim = requestAnimationFrame(increase); 
 
\t }; 
 

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

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

 
\t function render() { 
 

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

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

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

 

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

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

 
</head> 
 

 
    <body style="margin: 0;"> 
 

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

 
    </body> 
 

 
</html>

+0

Вы можете быть заинтересованы в попытке это популярные рамок анимации: [Phaser] (http://phaser.io/). См. Пример [ball] (http://phaser.io/examples/v2/arcade-physics/multiball). – Roberto

+2

Сначала отформатируйте свой код. Трудно читать прямо сейчас. Затем сделайте наименьший рабочий пример возможным, который показывает вашу проблему. Затем клиент и клиент должны работать нормально. Что именно не так? –

+0

Это ответ здесь ** http: //stackoverflow.com/questions/3011418/onmousemove-get-mouse-position** –

ответ

0

если вы хотите получить положение мыши относительно верхней левой части холста, вы должны использовать event.offsetX и event.offsetY (учитывая, что вы прикрепляли обработчик события mousemove к элементу canvas).

Попробуйте это:

function mouseMove(e) { 
     var mouseX = e.offsetX; 
     var mouseY = e.offsetY; 
} 
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); 
+0

Это «хорошо» решение. Это можно сделать более эффективным, поскольку ограничивающий прямоугольник обычно изменяется только при изменении размера и при прокрутке. Таким образом, вы можете сохранить 'rect.left' и' rect.top' и повторно использовать их (вместо их пересчета) в 'getMousePos '. – markE

+0

спасибо! Это будет иметь в виду. – lili2311

Смежные вопросы