Kodokon kodokon.com

الانتقالات والرسوم المتحركة: @keyframes وtransform والتوقيت

حرّك على المُركِّب باستخدام transform وopacity، ونظّم @keyframes، واحترم تفضيلات المستخدمين بشأن الحركة.

10 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

قبل اختيار ما ستحرّكه، تذكّر خط أنابيب التصيير: التخطيط (الهندسة)، الرسم (البكسلات)، التركيب (تجميع الطبقات على وحدة معالجة الرسوميات). تحريك width أو top يُطلق تخطيطًا في كل إطار، يتبعه غالبًا رسم: وهذه وصفة للتقطّع دون 60 إطارًا في الثانية. أما transform وopacity فيتولاهما المُركِّب مباشرةً، دون العودة عبر المرحلتين الأوليين. القاعدة المهنية: حرّك هاتين الخاصيتين فقط كلما أمكن، وحاكِ الباقي (translate بدلًا من top، وscale بدلًا من width).

CSS
.button {
  transform: translateY(0);
  transition:
    transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 0.15s ease-out;
}

.button:hover {
  transform: translateY(-2px);
}

.button:active {
  transform: translateY(0) scale(0.97);
}
انتقال ملائم للمُركِّب مع منحنى مخصص

عندما لا يعود الانتقال كافيًا (خطوات وسيطة، تكرار، بدء تلقائي)، انتقل إلى @keyframes. إعدادان يصنعان الفرق بين رسم متحرك نظيف وخلل بصري: animation-fill-mode يتحكم في الحالة قبل البدء (backwards يطبّق الإطار المفتاحي الأول أثناء التأخير) وبعد النهاية (forwards يجمّد الأخير)؛ وboth يجمع بين الاثنين. لاحظ أيضًا أن دالة التوقيت تُطبَّق بين كل زوج من الأطر المفتاحية، لا على المدة الكلية: يمكنك إعادة تعريفها داخل إطار مفتاحي.

CSS
@keyframes slide-in {
  from {
    transform: translateX(-100%);
    opacity: 0;
  }
  70% {
    transform: translateX(8px);
    opacity: 1;
  }
  to {
    transform: translateX(0);
  }
}

.toast {
  animation: slide-in 0.35s ease-out both;
}
دخول مع تجاوز طفيف

أداتان متكاملتان تستحقان المعرفة. will-change: transform يرقّي العنصر إلى طبقته الخاصة قبل الرسم المتحرك، متجنبًا رسترة متأخرة؛ لكن كل طبقة تكلّف ذاكرة وحدة معالجة الرسوميات، لذا طبّقه قبيل الرسم المتحرك مباشرةً وأزِله بعده، لا كأسلوب دائم على عشرات العناصر. أما steps(n) فيستبدل الاستكمال المتصل بقفزات منفصلة: ضروري للأشكال المتحركة، ومؤشرات على طريقة الآلة الكاتبة، والساعات.

CSS
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
احترام prefers-reduced-motion

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. لماذا نفضّل transform: translateX(100px) على left: 100px لحركة مُحرَّكة؟
    • transform مدعوم بشكل أفضل في المتصفحات القديمة
    • transform يتولاه المُركِّب دون إعادة حساب التخطيط في كل إطار
    • left يعمل فقط على العناصر المموضعة بشكل مطلق، بينما transform يعمل في كل مكان
    • transform يقبل قيمًا سالبة، بخلاف left
  2. ماذا يفعل animation-fill-mode: both؟
    • يُشغّل الرسم المتحرك إلى الأمام ثم إلى الوراء
    • يطبّق الرسم المتحرك على العنصر وعلى أحفاده
    • تُطبَّق أنماط الإطار المفتاحي الأول أثناء التأخير، وتبقى أنماط الإطار المفتاحي الأخير بعد النهاية
  3. ما الاستخدام الصحيح لـ will-change؟
    • تطبيقه عالميًا على * لتسريع الصفحة بأكملها
    • إضافته قبيل رسم متحرك مكلف مباشرةً وإزالته بعده
    • دمجه دائمًا مع transform: translateZ(0)
    • استخدامه بدلًا من transition للتفاعلات الدقيقة