为了账号安全,请及时绑定邮箱和手机立即绑定

在运行 60fps 的循环内移动对象

在运行 60fps 的循环内移动对象

慕桂英3389331 2023-08-18 14:18:47
我正在尝试设置一个运行循环,每秒执行 60 次 - 在我的示例中,我想在每次循环运行时简单地将 px 移动到 div 的左侧位置,但我认为我'我做错事了。如果每次循环运行时操作此块有任何帮助,我将不胜感激。function runLoop() {    var counter = counter + 1;    var redBlock = document.getElementById("block");    redBlock.style.left = counter + "px";}setInterval(function () {    runLoop();}, 60)#block {  background-color: red;  width: 100px;  height: 100px;  position: absolute;  display: block;}<div id="block"></block>
查看完整描述

3 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

您永远不应该使用 setInterval/setTimeout 进行动画,因为您设置的延迟 X 实际上是“当 X 过去时”。动画也可能发生在屏幕的帧更新之间,这使得动画看起来很卡顿。

var counter = 0,

    running = true;


function runLoop() {

    counter = counter + 1;

    var redBlock = document.getElementById("block");

    redBlock.style.left = counter + "px";

}


setInterval(function () {

    runLoop();

}, 60)

#block {

  background-color: red;

  width: 100px;

  height: 100px;

  position: absolute;

  display: block;

}

<div id="block"></block>

我建议使用requestAnimationFramewhich 进行计算,然后等待下一个屏幕更新来绘制新位置。它可能看起来很棘手,但一旦您意识到这只是对自身的回调,它就会比看起来更容易。


我添加了两个按钮,以便您可以播放动画。


请注意与 相比,动画有多流畅setInterval。


此外,在循环之外进行变量声明以提高性能。


let counter = 0,

    isRunning = true;


const redBlock = document.getElementById("block");


function runLoop() {

  counter = counter + 1;

  redBlock.style.left = counter + "px";

  

  if (isRunning) {

    requestAnimationFrame(runLoop);    

  }

}


function restart() {

  counter = 0;

  

  if (!isRunning) { runLoop(); } 

}


function pause() {

  isRunning = !isRunning;

  

  if (isRunning) { runLoop(); } 

}


requestAnimationFrame(runLoop);

#block {

  background-color: red;

  width: 100px;

  height: 100px;

  position: absolute;

  top: 30px;

  display: block;

}

<div id="block"></div>


<button onclick="pause()">Pause</button>


<button onclick="restart()">Restart</button>


查看完整回答
反对 回复 2023-08-18
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

要让该函数runLoop每秒调用 60 次,需要以 (1000 / 60) 毫秒的间隔调用。


另外,还counter需要进行初始化。


(您还需要一些条件来确定何时停止计数以避免溢出)。


<script>

  function runLoop(xcoord) {

      var redBlock = document.getElementById("block");

      redBlock.style.left = xcoord + "px";

  }


  var counter = 0;

  setInterval(runLoop, 16.7, counter++);


</script>


查看完整回答
反对 回复 2023-08-18
?
跃然一笑

TA贡献1826条经验 获得超6个赞

setInterval的参数是错误的,如果你想每秒运行60次,你需要将间隔设置为1000 / 60。


现在我猜你正在尝试设置动画循环。您可能想看看为此目的而制作的函数。


requestAnimationFrame(someCallback);

基本上,它是一个函数,它将注册一个回调,以便在下一个浏览器渲染调用之前执行。这意味着最多 60 次/秒,但如果浏览器难以计算,则可能会更少。


应用于您的示例,它可能很简单:


function runLoop() {

      var redBlock = document.getElementById("block");

      redBlock.style.left = xcoord + "px";

      requestAnimationFrame(runLoop()); // register recursivaly a call for next animationFrame

 }

  var counter = 0;


  runLoop()


查看完整回答
反对 回复 2023-08-18
  • 3 回答
  • 0 关注
  • 120 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信