JavaScript 在页面刷新后中断

JavaScript Breaks After Page Refresh

本文关键字:中断 刷新 JavaScript      更新时间:2023-09-26

学校项目:我和同学自己正在编程"Agar.io"(用于练习)。做得好,测试不同的东西,然后我们得到一个我们无法弄清楚的问题。看似"随机"的JavaScript在使用各种浏览器打开时不会完全执行。除了偶尔在页面加载时随机不执行之外,每次刷新页面时,JavaScript 都会像以前一样中断。它仅在完全关闭浏览器后才起作用,然后再重新打开页面。1:为什么现在会发生这种情况,而不是以前?2: 我们如何解决它?源代码在下面有评论,谢谢,-汤姆

var pixelconversion = 100 * Math.PI; //conversion from made-up "mass" (really area), to area in pixels, which will be converted to a radius
var circleX = 400;
var circleY = 250;
var mouseX = 400;
var mouseY = 250;
var mass = 30;
var radius = 20; //just to make it global
function start() {
  drawCircles();
  var interval = setInterval(mainloop, 50);
}
function mainloop() {
  math();
  var can = document.getElementById("canvas");
  var ctx = can.getContext("2d");
  ctx.clearRect(0, 0, 801, 501); //clears the canvas
  drawCircles();
  sleep(100); //more efficient than having the set interval at 150 instead
}
function getCoordinates(e) { //gets the cursors coordinates
  mouseX = e.clientX;
  mouseY = e.clientY;
}
function math() {
  var movement = mass / 4; //arbitrary "4", will be replaced with: 1/mass * someConversion
  radius = Math.sqrt((mass * pixelconversion) / Math.PI); //from area in "mass" to area in pixels, to radius in pixels
  var difY = Math.abs(mouseY - circleY) //finds the difference of each
  var difX = Math.abs(mouseX - circleX) //for "A" and "B" of the triangle
  var c = Math.sqrt(Math.pow(difX, 2) + Math.pow(difY, 2)); //pythagareon theorem to find diagonal distance from mouse to circle
  var scale = movement / c; //use scale to find "A" and "B" of smaller triangle
  if (mouseX > circleX) { //if and else statements are for "movement" in the right direction, (towards the mouse)
    circleX = circleX + difX * scale; //aditional if statements will be added to (next comment)
  } else {
    circleX = circleX - difX * scale; //stop the circle from going back and forth past the cursor
  }
  if (mouseY > circleY) {
    circleY = circleY + difY * scale; //the differce * scale is vital; (fourth comment up)
  } else {
    circleY = circleY - difY * scale;
  }
}
function drawCircles() {
  var can = document.getElementById("canvas");
  var ctx = can.getContext("2d");
  ctx.beginPath();
  ctx.arc(circleX, circleY, radius, 0, 2 * Math.PI); //draws the circle
  ctx.closePath();
  ctx.lineWidth = 5; //just for style
  ctx.fillStyle = 'green';
  ctx.fill();
  ctx.strokeStyle = 'darkgreen'; //just for style
  ctx.stroke();
}
function sleep(milliseconds) { //"homemade" "sleep" "command"
  var start = new Date().getTime();
  for (var i = 0; i < 1; i++) {
    if ((new Date().getTime() - start) > milliseconds) {
      break;
    }
  }
}
<body onload="start()">
  <canvas id="canvas" height="501" width="801" onmousemove="getCoordinates(event)"></canvas>
</body>

此行

var scale = movement / c; //use scale to find "A" and "B" of smaller triangle

c 可以为零 - 这使得尺度 NaN 破坏了一切

试试这个

var scale = c ? movement / c : 0;

我还添加了一个片段,演示了requestAnimationFrame与笨拙的睡眠功能相比是多么流畅

        var pixelconversion = 100 * Math.PI; //conversion from made-up "mass" (really area), to area in pixels, which will be converted to a radius
        var circleX = 400;
        var circleY = 250;
        var mouseX = 400;
        var mouseY = 250;
        var mass = 30;
        var radius = 20; //just to make it global
        function start() {
          document.getElementById("canvas").addEventListener('mousemove', getCoordinates);
          mainloop();
        }
        function mainloop() {
          math();
          drawCircles();
          requestAnimationFrame(mainloop);
        }
        function getCoordinates(e) { //gets the cursors coordinates
          mouseX = e.clientX;
          mouseY = e.clientY;
        }
        function math() {
          var movement = mass / 4; //arbitrary "4", will be replaced with: 1/mass * someConversion
          radius = Math.sqrt((mass * pixelconversion) / Math.PI); //from area in "mass" to area in pixels, to radius in pixels
          var difY = Math.abs(mouseY - circleY) //finds the difference of each
          var difX = Math.abs(mouseX - circleX) //for "A" and "B" of the triangle
          var c = Math.sqrt(Math.pow(difX, 2) + Math.pow(difY, 2)); //pythagareon theorem to find diagonal distance from mouse to circle
          
          var scale = c ? movement / c : 0; //use scale to find "A" and "B" of smaller triangle
          if (mouseX > circleX) { //if and else statements are for "movement" in the right direction, (towards the mouse)
            circleX = circleX + difX * scale; //aditional if statements will be added to (next comment)
          } else {
            circleX = circleX - difX * scale; //stop the circle from going back and forth past the cursor
          }
          if (mouseY > circleY) {
            circleY = circleY + difY * scale; //the differce * scale is vital; (fourth comment up)
          } else {
            circleY = circleY - difY * scale;
          }
        }
        function drawCircles() {
          var can = document.getElementById("canvas");
          var ctx = can.getContext("2d");
          ctx.clearRect(0, 0, 801, 501); //clears the canvas
          ctx.beginPath();
          ctx.arc(circleX, circleY, radius, 0, 2 * Math.PI); //draws the circle
          ctx.closePath();
          ctx.lineWidth = 5; //just for style
          ctx.fillStyle = 'green';
          ctx.fill();
          ctx.strokeStyle = 'darkgreen'; //just for style
          ctx.stroke();
        }
window.addEventListener('load', start);
<canvas id="canvas" height="501" width="801"></canvas>

我会让你弄清楚为什么圆圈像看日本动画片的孩子一样跳舞

根据评论中的要求:

Window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数以在下次重绘之前更新动画。该方法将重绘之前要调用的回调作为参数。

每当准备好更新屏幕上的动画时,都应调用此方法。这将请求在浏览器执行下一次重绘之前调用您的动画函数。回调次数通常为每秒 60 次,但根据 W3C 建议,通常与大多数 Web 浏览器中的显示刷新率相匹配。在后台选项卡或隐藏选项卡中运行时,回调速率可能会降低到较低的速率,以提高性能和电池寿命。

回调方法传递单个参数(DOMHighResTimeStamp ),该参数指示由 requestAnimationFrame 排队的回调开始触发的当前时间。因此,单个帧中的多个回调都会收到相同的时间戳,即使在计算每个先前回调的工作负载期间已经过去了时间。此时间戳是一个十进制数字,以毫秒为单位,但最小精度为 1 毫秒 (1000 μs)。

来源: https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame