2016-03-21 13 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

はこれを試してみてください。 [ball](http://phaser.io/examples/v2/arcade-physics/multiball)の例を参照してください。 – Roberto

+2

まず、コードを書式設定します。今読むのは難しいです。次に、あなたの問題を示す最小の実用的な例を作成します。次に、clientXとclientYは正常に動作しているはずです。何が間違っているのですか? –

+0

これはここで答えられました** http://stackoverflow.com/questions/3011418/onmousemove-get-mouse-position** –

答えて

0

をキャンバスの左上の点を基準にしてマウスの位置を取得するには、event.offsetXとevent.offsetYを使用する必要があります(mousemoveイベントハンドラをcanvas要素にアタッチした場合)。 [フェイザー](http://phaser.io/):あなたはこの人気のアニメーションフレームワークを試みることに興味があるかもしれない

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 
    }; 
} 

あなたは、両方のマウスダウン&のmouseupイベントのイベントリスナーを追加しているときに、あなたがマウス位置に設定することができます:あなたがしたい場合は

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

    }, false); 
+0

これは「OK」ソリューションです。境界矩形は、通常、サイズ変更時とスクロール時にのみ変更されるため、効率を高めることができます。だから、 'rect.left'と' rect.top'を保存して、 'getMousePos 'に(再計算する代わりに)それらを再利用することができます。 – markE

+0

ありがとう!それを覚えておいてください。 – lili2311

関連する問題