2016-03-21 16 views
-1

Ich habe ein kleines JS-Programm gemacht, das Ballphysik simulieren soll, wobei der HTML-Canvas sich an die Fensterhöhe anpassen soll. Ich habe es so gemacht, dass die Leinwand die Größe ändert, aber wenn es die Größe ändert, funktioniert die Mausposition nicht richtig, und die Bälle erscheinen nicht auf dem Bildschirm, wenn sie geklickt wird (wie sie sollen). Ich habe clientX & clientY verwendet, um die Mausposition zu erhalten, aber ich weiß nicht, ob das die beste Methode ist. Hier ist der Code:Wie bekomme ich richtig die Mausposition in 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

Sie könnten bei dem Versuch, diese beliebten Animations-Framework interessiert sein: [Phaser] (http://phaser.io/). Siehe das Beispiel [ball] (http://phaser.io/examples/v2/arcade-physics/multiball). – Roberto

+2

Formatieren Sie zunächst Ihren Code. Es ist momentan schwer zu lesen. Als nächstes machen Sie das kleinste, funktionierende Beispiel, das Ihr Problem zeigt. Als nächstes sollten ClientX und ClientY gut funktionieren. Was läuft genau falsch? –

+0

Dies wurde hier beantwortet ** http: //stackoverflow.com/questions/3011418/onmousemove-get-mouse-position** –

Antwort

0

Wenn Sie möchten, Wenn Sie die Mausposition relativ zum linken oberen Bildschirmrand abrufen, sollten Sie event.offsetX und event.offsetY verwenden (vorausgesetzt, Sie haben den Ereignishandler mousemove an das Element canvas angefügt).

Try this:

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

Ich denke, das es das, was helfen kann, müssen Sie die Mausposition in Bezug auf die Leinwand zu bekommen. So eine Funktion der Erstellung der Mausposition erhalten:

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

Dann, wenn Sie einen Ereignis-Listener für beide mousedown- & mouseup Ereignisse hinzufügen, können Sie die Mausposition gesetzt:

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

    }, false); 
+0

Dies ist eine "ok" -Lösung. Es könnte effizienter gemacht werden, da sich das Begrenzungsrechteck normalerweise nur bei der Größenänderung und beim Scrollen ändert. Sie können also "rect.left" und "rect.top" speichern und in "getMousePos" wiederverwenden (anstatt sie neu zu berechnen). – markE

+0

danke! Behält das im Hinterkopf. – lili2311

Verwandte Themen