Синхронизация анимации — введение в циклы по времени
Создайте небольшой цикл анимации, используйте обновления с учётом времени (дельты), смоделируйте requestAnimationFrame и добавьте простое сглаживание
«Синхронизация анимации — введение в циклы по времени» — бесплатный урок JavaScript Academy на CoddyKit. Это урок 3 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения JavaScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс JavaScript Academy содержит 3 уроков всего.
Зачем нужна анимация с учётом времени
Цель: создавать плавное движение с обновлениями, зависящими от времени.
- Имитировать requestAnimationFrame
- Измерять разницу во времени
- Перемещать объект с заданным числом единиц в секунду
- Добавить небольшое сглаживание

Имитация rAF
Здесь нет DOM, поэтому мы имитируем requestAnimationFrame с помощью setTimeout примерно на 16 мс.
// 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);
});

Основы разницы во времени
Вычисляйте разницу во времени для каждого кадра: (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);

Единицы в секунду
Используйте speed × dt для обновления положения, чтобы движение оставалось одинаковым при разной частоте кадров.
// 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();

Небольшая демонстрация сглаживания
Сглаживание формирует кривую движения. Здесь 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);

Знакомство с фиксированным шагом
Фиксированный шаг может стабилизировать логику; накопитель наверстывает отставание, если кадр запаздывает.
// 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();

Тест по разнице во времени и фиксированному шагу
Быстрая проверка: зачем нужна разница во времени.

Итоги
Итоги: Вы имитировали rAF с помощью setTimeout, измеряли разницу во времени, перемещали объект с заданным числом единиц в секунду, добавили замедление к концу и познакомились с фиксированным шагом и накопителем.

Часто задаваемые вопросы
Урок «Синхронизация анимации — введение в циклы по времени» бесплатный?
Да — полный текст урока «Синхронизация анимации — введение в циклы по времени» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс JavaScript Academy, подпишись на CoddyKit PRO. Курс JavaScript Academy содержит 3 уроков всего.
Чему я научусь в уроке «Синхронизация анимации — введение в циклы по времени»?
Создайте небольшой цикл анимации, используйте обновления с учётом времени (дельты), смоделируйте requestAnimationFrame и добавьте простое сглаживание Ты практикуешь JavaScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать JavaScript Academy?
Предыдущий опыт не требуется. JavaScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 3.
Сколько времени занимает урок «Синхронизация анимации — введение в циклы по времени»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке JavaScript Academy?
Да. Каждый урок JavaScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- setTimeout, setInterval и дрейф таймера
- Debounce и throttle — реализация вручную
- Синхронизация анимации — введение в циклы по времени