توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت
ابنوا حلقة تحريك صغيرة، واستخدموا تحديثات معتمدة على الوقت (delta)، وحاكوا requestAnimationFrame، وأضيفوا easing بسيطًا
توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت درس مجاني في JavaScript Academy على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في JavaScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة JavaScript Academy 3 دروس في المجموع.
لماذا الرسوم المتحركة المعتمدة على الزمن؟
الهدف: تحريك سلس باستخدام تحديثات تعتمد على الزمن.
- محاكاة requestAnimationFrame
- قياس الزمن المنقضي
- الحركة بوحدات/ثانية
- إضافة تنعيم طفيف

محاكاة rAF
لا يوجد DOM هنا، لذا نحاكي requestAnimationFrame باستخدام setTimeout لمدة تقارب 16ms.
// 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، وقستم الزمن المنقضي، وحركتم بوحدات/ثانية، وأضفتم ease-out، وشاهدتم لمحة عن الخطوة الثابتة باستخدام مجمّع.

الأسئلة الشائعة
هل درس «توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت» مجاني؟
نعم — نص درس «توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة JavaScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة JavaScript Academy 3 دروس في المجموع.
ماذا ستتعلم في «توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت»؟
ابنوا حلقة تحريك صغيرة، واستخدموا تحديثات معتمدة على الوقت (delta)، وحاكوا requestAnimationFrame، وأضيفوا easing بسيطًا تتمرن على JavaScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ JavaScript Academy؟
لا تُشترط خبرة سابقة. JavaScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.
كم من الوقت يستغرق درس «توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس JavaScript Academy هذا؟
نعم. كل درس في JavaScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- setTimeout وsetInterval وانحراف المؤقت
- Debounce مقابل Throttle — بالتنفيذ اليدوي
- توقيت التحريك — مقدمة عن الحلقات المعتمدة على الوقت