حركات CSS: نصائح وحيل

من موسوعة حسوب
< CSS
اذهب إلى التنقل اذهب إلى البحث
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

تتيح حركات CSS القيام بأشياء لا تصدق على العناصر التي تشكل صفحات مواقعك وتطبيقاتَك الخاصة. ومع ذلك، هناك أشياء ترغب في القيام بها لكنها ليست واضحة، أو طرق ذكية للقيام بأشياء قد لا تتوصل إليها على الفور. هذه المقالة عبارة عن مجموعة من النصائح والحيل التي قد تسهل عملك مع حركات CSS، بما في ذلك كيفية توقيف الحركة وتشغيلها مرة أخرى.

إعادة تشغيل الحركة

لا تقدم طبيعة حركات CSS طريقةً لإعادة تشغيل الحركة مرة أخرى. لا توجد دالة مثل ()resetAnimation فعَّالة للعناصر، ولا يمكنك حتى ضبط حالة تشغيل الحركة (أي الخاصية animation-play-state) للعنصر على "running" ثانيةً. بدلًا من ذلك، يجب عليك استخدام الحيل الذكية لإعادة تشغيل الحركة بعد توقفها.

إليك طريقة متوازنة وموثوقة يمكن أن تُقتَرح للقيام بذلك.

محتوى HTML

أولاً، دعنا نحدد الحاوية <div> التي نود تحريكها والزر الذي سيشغل (أو سيعيد) الحركة:

<div class="box">
</div>

<div class="runButton">Click me to run the animation</div>

محتوى CSS

سنقوم الآن بتعريف الحركة نفسها باستخدام CSS. بعض شيفرات CSS غير المهمة (تنسيقات زر التشغيل) ستجد أنها غير معروضة هنا، للإيجاز.

@keyframes colorchange {
  0% { background: yellow }
  100% { background: blue }
}

.box {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

.changing {
  animation: colorchange 2s;
}

تم استخدام صنفان هنا، صنف "box" يشمل الوصف الأساسي لمظهر الصندوق، دون أن يحتوي أي معلومات عن الحركة، فتفاصيل الحركة يتم تضمينها في الصنف "changing" الذي ينص بالقاعدة @keyframes القاعدة أن الإطارات المفتاحية المسماة "colorchange" يجب أن تُستخدَم على مدار ثانيتين لتحريك المربع.

لاحظ أنه بسبب هذا؛ فإن المربع لا يبدأ بأي تأثيرات للحركة في مكانه، لذلك لن يكون متحركًا في أصله.

محتوى JavaScript

سنلقي نظرة على شِيفرة JavaScript التي تعمل معنا، جوهر هذه التقنية هو في الدالة ()play، والتي تُستدعى عندما ينقر المستخدم على زر "Run".

function play() {
  document.querySelector(".box").className = "box";
  window.requestAnimationFrame(function(time) {
    window.requestAnimationFrame(function(time) {
      document.querySelector(".box").className = "box changing";
    });
  });
}

هذا يبدو غريبًا، أليس كذلك؟ ذلك لأن الطريقة الوحيدة لتشغيل الحركات مرة أخرى هي إزالة تأثير الحركة، والسماح للمستند بإعادة تشغيل أنماط CSS، ثم إضافة تأثير الحركة مرة أخرى للعنصر. لتحقيق ذلك، علينا أن نكون مبدعين.

إليك ما يحدث عندما يتم استدعاء الدالة ()play:

  1. يتم تعيين قائمة أصناف CSS الخاصة بالمربع إلى "box" فقط. هذا تأثير إزالة أي أصناف أخرى مطبقة حاليًا على المربع، بما في ذلك صنف "changing" الذي تتعامل معه الحركات. بمعنى آخر، قمنا بإزالة تأثير الحركات من المربع. ومع ذلك، لا تسري التغييرات التي تم إجراؤها على قائمة الأصناف حتى تكتمل إعادة تشكيل النمط وعمل تحديث لإظهار التغيير.
  2. للتأكد من إعادة تشغيل الأنماط، نستخدم التابع ()window.requestAnimationFrame، مع تحديد رد اتصال. يتم تنفيذ رد الاتصال قبل إعادة التخطيط التالي للمستند، وبسبب ذلك، لم تتم إعادة صياغة النمط لدينا بعد!
  3. رد النداء لدينا يقوم باستدعاء ()requestAnimationFrame مرة ثانية بذكاء! هذه المرة، يُشغَّل رد النداء قبل إعادة التخطيط التالي، والذي يكون بعد حدوث إعادة تشغيل النمط. يضيف رد الاتصال هذا الصنف "changing" مرة أخرى إلى المربع، بحيث يتسبب إعادة التخطيط في تشغيل الحركة ثانيةً.

بالطبع، نحتاج أيضًا إلى إضافة معالج حدث إلى زر التشغيل لدينا، "Run"، حتى يقوم بعمل إضافي:

document.querySelector(".runButton").addEventListener("click", play, false);

إيقاف الحركة

ببساطة، إزالة الخاصية animation-name من العنصر تجعله ينتقل لحالته التالية، إذا كنت ترغب بدلًا من ذلك في إكمال الحركة ثم توقيفها، فعليك تجربة طريقة مختلفة. التلميحات الرئيسية هي:

  1. اجعل حركاتك قائمة بذاتها قدر الإمكان، هذا يعني أنك يجب ألا تعتمد على animation-direction: alternate، بل يجب أن تكتب بوضوح رسمًا متحركًا للإطار المفتاحي يمر بالحركات الكاملة في تكرار واحد متتابع.
  2. استخدم JavaScript وقم بتفريغ الحركات المستخدمة عند انطلاق حدث تكرار الحركة (animationiteration).

توضح التجرية الحية هذه كيف يمكنك تحقيق تقنية JavaScript المذكورة أعلاه:

  • شيفرة CSS:
.slidein {
  animation-duration: 5s;
  animation-name: slidein;
  animation-iteration-count: infinite;
}

.stopped {
  animation-name: none;
}

@keyframes slidein {
  0% {
    margin-left: 0%;
  }
  50% {
    margin-left: 50%;
  }
  100% {
    margin-left: 0%;
  }
}
  • شيفرة HTML:
<h1 id="watchme">Click me to stop</h1>
  • شيفرة JavaScript:
let watchme = document.getElementById('watchme')

watchme.className = 'slidein'
const listener = (e) => {
  watchme.className = 'slidein stopped'
}
watchme.addEventListener('click', () =>
  watchme.addEventListener('animationiteration', listener, false)
)

اقرأ أيضًا

المصادر