我正试图在画布区域内制作一个跟随鼠标的球。但是当鼠标进入画布区域时(例如边缘),球只能获得第一个位置。
由于球在帆布内移动时球不跟随鼠标会出现什么问题?
window.onload = startup;
var ballX = 400;
var ballY = 400;
var mouseX = 0;
var mouseY = 0;
function startup() {
document.getElementById("drawingArea").onmouseover = mouseMove;
setInterval("moveBall()",100);
}
function mouseMove(evt) {
mouseX = evt.clientX;
mouseY = evt.clientY;
}
function moveBall() {
if (ballX > mouseX) {
ballX -= 5;
} else {
ballX += 5;
}
if (ballY > mouseY) {
ballY -= 5;
} else {
ballY += 5;
}
var canvas = document.getElementById("drawingArea");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(ballX, ballY, 40, 0, 2* Math.PI);
ctx.fillStyle = "green";
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
}
#drawingArea
{
border-style: solid;
position: absolute;
top: 0;
left: 0;
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Move Ball</title>
</head>
<body>
<canvas id="drawingArea" width="800" height="800" />
</body>
</html>
答案 0 :(得分:3)
mouseover
事件监听器不像&#34;当鼠标结束时,执行此代码&#34;。它仅在此状态为真时触发,换句话说,当您将鼠标从外部移动到节点上时。
您想要使用的正确事件是mousemove
;只要它发生变化,就会存储鼠标的新位置。
除此之外,我还对您的代码进行了一些其他更改,以便动画更流畅:
这种ballX += mouseX>ballX? 5: -5
的方法容易出现断言,因为当鼠标和球在任何轴上相距小于5px时,它会完全忽略该区域。
另外,请不要将setInterval()
用于游戏循环。 而且更广泛,不要使用setTimeout()
或setInterval()
使用字符串参数(根本)。这是一个不好的做法。不灵活,并强迫您使用全局变量。
更好地使用requestAnimationFrame()
,以便与浏览器呈现保持同步。
window.onload = startup;
var ballX = 400;
var ballY = 400;
var mouseX = 0;
var mouseY = 0;
function startup() {
//`mousemove`, not `mouseover`
document.getElementById("drawingArea").onmousemove = mouseMove;
loop();
}
//use `requestAnimationFrame` for the game loop
//so you stay sync with the browsers rendering
//makes it a smoother animation
function loop(){
moveBall();
requestAnimationFrame(loop);
}
function mouseMove(evt) {
mouseX = evt.clientX;
mouseY = evt.clientY;
}
function moveBall() {
//get the distance between the mouse and the ball on both axes
//walk only the an eight of the distance to create a smooth fadeout
var dx = (mouseX - ballX) * .125;
var dy = (mouseY - ballY) * .125;
//calculate the distance this would move ...
var distance = Math.sqrt(dx*dx + dy*dy);
//... and cap it at 5px
if(distance > 5){
dx *= 5/distance;
dy *= 5/distance;
}
//now move
ballX += dx;
ballY += dy;
var canvas = document.getElementById("drawingArea");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(ballX, ballY, 40, 0, 2 * Math.PI);
ctx.fillStyle = "green";
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
}
&#13;
#drawingArea {
border-style: solid;
position: absolute;
top: 0;
left: 0;
}
&#13;
<canvas id="drawingArea" width="800" height="800" />
&#13;
随意使用移动代码玩一下。退房时,在计算距离时更改* .125
时会发生什么,删除条件时,......
答案 1 :(得分:1)
您还需要添加onmousemove
事件处理程序。
答案 2 :(得分:0)
在这一行:
document.getElementById("drawingArea").onmouseover = mouseMove;
...您需要将onmouseover
更改为onmousemove
。进一步阅读:onmousemove
更改的完整示例:
window.onload = startup;
var ballX = 400;
var ballY = 400;
var mouseX = 0;
var mouseY = 0;
function startup() {
document.getElementById("drawingArea").onmousemove = mouseMove;
setInterval("moveBall()",100);
}
function mouseMove(evt) {
mouseX = evt.clientX;
mouseY = evt.clientY;
}
function moveBall() {
if (ballX > mouseX) {
ballX -= 5;
} else {
ballX += 5;
}
if (ballY > mouseY) {
ballY -= 5;
} else {
ballY += 5;
}
var canvas = document.getElementById("drawingArea");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(ballX, ballY, 40, 0, 2* Math.PI);
ctx.fillStyle = "green";
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
}
#drawingArea
{
border-style: solid;
position: absolute;
top: 0;
left: 0;
}
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Move Ball</title>
</head>
<body>
<canvas id="drawingArea" width="800" height="800" />
</body>
</html>