0Pricing
JavaScript Academy · 课时

动画计时——使用基于时间的循环入门

构建一个小型动画循环,使用基于时间(增量)的更新,模拟 requestAnimationFrame,并添加简单的缓动效果

动画计时——使用基于时间的循环入门 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 3 节课。

为什么使用基于时间的动画

目标:通过基于时间的更新驱动平滑运动。

  • 模拟requestAnimationFrame
  • 测量时间增量
  • 以单位/秒的速度移动
  • 添加微小的缓动
动画计时——使用基于时间的循环入门 — 插图 1

模拟 rAF

这里没有 DOM,因此我们使用大约每 16 毫秒运行一次的setTimeout来模拟requestAnimationFrame。

// requestFrame: simulate ~60 FPS with setTimeout
function requestFrame(fn) {
  // ~16ms between frames for ~60fps
  return setTimeout(function () { fn(Date.now()); }, 16);
}

function cancelFrame(id) {
  clearTimeout(id);
}

// Tiny demo: schedule one frame
requestFrame(function (ts) {
  console.log("frame at", ts);
});
动画计时——使用基于时间的循环入门 — 插图 2

时间增量基础

在每一帧计算时间增量:(now − last) / 1000。这样可以根据实际时间调整运动。

// Time-based loop: compute delta time in seconds
let running = true;
let last = Date.now();

function loop() {
  if (!running) { return; }
  const now = Date.now();
  const dt = (now - last) / 1000; // seconds
  last = now;

  // Print a tiny delta preview
  console.log("dt", dt.toFixed(3), "s");

  requestFrame(loop);
}

// Start the loop and stop after a few frames
loop();
setTimeout(function () {
  running = false;
  console.log("stop");
}, 60);
动画计时——使用基于时间的循环入门 — 插图 3

每秒单位数

使用speed × 时间增量更新位置,使运动在不同帧率下保持一致。

// Move with a speed in units/second
let x = 0;               // position
const speed = 50;        // units per second

let lastT = Date.now();
let frames = 0;

function moveLoop() {
  const now = Date.now();
  const dt = (now - lastT) / 1000;
  lastT = now;

  // Distance = speed * time
  x = x + speed * dt;
  frames = frames + 1;

  console.log("x", Math.round(x));

  if (frames < 5) {
    requestFrame(moveLoop);
  } else {
    console.log("final x", Math.round(x));
  }
}

moveLoop();
动画计时——使用基于时间的循环入门 — 插图 4

微型缓动演示

缓动会塑造运动曲线。这里的easeOutQuad开始时较快,接近结束时逐渐变慢。

// Ease from 0 to 1 over duration using easeOutQuad
function easeOutQuad(t) {
  // t in [0,1]
  return 1 - (1 - t) * (1 - t);
}

async function tween(durationMs) {
  let start = Date.now();
  let id = null;

  function step() {
    const now = Date.now();
    const t = Math.min(1, (now - start) / durationMs);
    const eased = easeOutQuad(t);
    console.log("eased", eased.toFixed(2));

    if (t < 1) {
      id = requestFrame(step);
    } else {
      cancelFrame(id);
      console.log("done");
    }
  }

  step();
}

tween(60);
动画计时——使用基于时间的循环入门 — 插图 5

体验固定步长

固定步长可以稳定逻辑;如果某一帧延迟,累加器会负责追赶。

// Fixed-step taste: step a physics tick and catch up using an accumulator
let acc = 0;                  // accumulated time
const step = 1 / 30;          // 30 FPS fixed step in seconds
let lastTime = Date.now();
let value = 0;
let fixedFrames = 0;

function fixedLoop() {
  const now = Date.now();
  const dt = (now - lastTime) / 1000;
  lastTime = now;
  acc = acc + dt;

  // Run zero or more fixed steps to catch up
  while (acc >= step) {
    // Update logic at a fixed rate
    value = value + 1;        // pretend physics
    acc = acc - step;
  }

  console.log("value", value);

  fixedFrames = fixedFrames + 1;
  if (fixedFrames < 5) {
    requestFrame(fixedLoop);
  } else {
    console.log("fixed stop");
  }
}

fixedLoop();
动画计时——使用基于时间的循环入门 — 插图 6

时间增量与固定步长测验

快速检查:为什么需要时间增量?

动画计时——使用基于时间的循环入门 — 插图 7

回顾

回顾:您使用setTimeout模拟了 rAF,测量了时间增量,以单位/秒的速度移动,添加了缓出效果,并体验了带累加器的固定步长。

动画计时——使用基于时间的循环入门 — 插图 8

常见问题解答

「动画计时——使用基于时间的循环入门」课时是免费的吗?

是的 — 「动画计时——使用基于时间的循环入门」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 3 节课。

「动画计时——使用基于时间的循环入门」这节课中我会学到什么?

构建一个小型动画循环,使用基于时间(增量)的更新,模拟 requestAnimationFrame,并添加简单的缓动效果 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。

「动画计时——使用基于时间的循环入门」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 JavaScript Academy 课中编写并运行代码吗?

能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. setTimeout、setInterval 与计时器漂移
  2. 防抖与节流——手动实现
  3. 动画计时——使用基于时间的循环入门
← 返回 JavaScript Academy