يلعب التحريك Animation دورًا كبيرًا في رفع جاذبية تطبيقات ومواقع الويب للمستخدمين الذين أصبحوا يتوقعون دومًا الحصول على واجهات استخدام تفاعلية عالية التجاوب؛ إلا أن تحريك واجهات الاستخدام ليس أمرًا مباشرًا وسهلًا، حيث يستلزم تحديد ما يجب تحريكه وما تأثير هذا التحريك على انطباع وتجربة المستخدمين.
- يُستخدم التحريك لإضفاء الحياة على المشاريع.
- يجب أن يدعم التحريك تفاعل المستخدم.
- يجب الانتباه لتكلفة تحريك الخصائص والتي قد تختلف من خاصيةٍ لأخرى.
أساسيات التحريك
نعرض فيما يلي أهم القضايا الواجب الانتباه إليها عند التحريك:
اختيار الخصائص المناسبة للتحريك
يُضيف التحريك كثيرًا من المتعة للمستخدمين ويرفع من تفاعلهم مع المشروع؛ حيث يُمكن عمليًا تحريك أي شيء، مثل العرض والارتفاع والموضع والألوان والخلفيات؛ ولكن يجب الانتباه في نفس الوقت إلى تأثيرات التحريك على الأداء وانعكاساتها على هوية التطبيق، حيث يُمكن أن يؤثر التحريك المتقطع أو المُختار بصورةٍ سيئة على تردِّي تجربة الاستخدام مما يستلزم الانتباه جيدًا إلى حُسن اختيار التحريك المُناسب والفعّال.
استخدام التحريك لدعم التفاعل
يجب استخدام التحريك بصورةٍ مدروسة بهدف تعزيز تفاعل المستخدمين (وليس فقط لمجرد إمكانية التحريك)، وتجنبًا لمضايقتهم أو إعاقتهم. يُمكن مثلًا استخدام توهجٍ خفيف، أو حركة ارتدادٍ بسيطة لإعلام المستخدم بتلَقّي أفعاله، مثل النقر على أيقونة قائمة، أو السحب لفتح شريط تمرير، أو النقر على زر. يجب تجنُّب التحريك الذي يقطع أو يُعرقل نشاط المستخدم دون أي داعٍ.
تجنب تحريك الخصائص المكلفة
يُعدّ التحريك الذي يؤدي إلى تقطُّعاتٍ في الصفحة من أسوأ أنواع التحريك، والذي يُحبط المستخدمين ويُشعرهم بعدم الرضا لدرجة أنهم يتمنون بألّا يوجد أي تحريكٍ على الإطلاق.
يُمكن أن تكون بعض الخصائص أكثر تكلفةً من غيرها عند تغييرها، كما يُمكن أن يؤدي هذا التغيير إلى ظهور التقطُّعات في الصفحة؛ حيث يُمكن مثلًا أن يتطلب تغيير ظل صندوق box-shadow
لعنصرٍ ما عملية طلاء paint أكثر تكلفةً بكثير من تغيير لون نصه. وبالمثل، من المرجح أن يكون تغيير عرض width
عنصر ما أكثر تكلفةً من تغيير تحويلاته transform
.
نعرض المزيد من الإرشادات حول أداء التحريك في الفقرة الأخيرة من هذه المقالة. يُمكن الالتزام فقط بالتحويلات transforms وتعديلات الشفافية opacity واستخدام "سوف يُعدّل" will-change
في حال عدم الرغبة بقراءة المزيد والخوض في التفصيلات. يُمكن معرفة ماذا ينشُط تمامًا عند تحريك أي خاصية بالرجوع إلى مُشغّلات أنماط CSS.
التحريك باستخدام أنماط CSS موازنة مع استخدام JavaScript
يُمكن التحريك، إما باستخدام أنماط CSS، أو JavaScript؛ حيث يعتمد قرار الاختيار بين واحدٍ منهما على الارتباطات الأخرى للمشروع وعلى أنواع التأثيرات المطلوبة.
- يُستخدم تحريك CSS لتنفيذ الانتقالات البسيطة من النمط "لقطة واحدة one-shot"، مثل تبديل حالات عناصر الواجهة.
- يُستخدم تحريك JavaScript للحصول على تأثيراتٍ متقدمة، مثل الارتداد أو التوقف أو الإيقاف المؤقت أو الإرجاع أو الإبطاء.
- يُمكن استخدام واجهة برمجة التطبيقات للتحريك Web Animations API أو أي إطار عمل حديث مناسب عند اختيار التحريك باستخدام JavaScript.
يُمكن إنشاء معظم عمليات التحريك الأساسية باستخدام CSS أو JavaScript، لكن يختلف الجهد والزمن اللازمين لإنشاء التحريك حسب الطريقة المختارة (راجع الفقرة الأخيرة من هذه المقالة)؛ حيث يوجد لكل طريقةٍ محاسنها ومساوئها، نعرض فيما يلي الإرشادات العامة:
- تُستخدم CSS عندما يكون لعناصر الواجهة حالات أقل محتواة ضمن نفس العنصر؛ حيث تكون الانتقالات والتحريك مثالية لجلب قائمة انتقال إلى جهةٍ معينة مثلًا أو إظهار تلميحٍ ما. يُمكن اللجوء إلى JavaScript للتحكم بالحالات إلا أن التحريك نفسه يكون في CSS.
- تُستخدم JavaScript عند الحاجة للتحكم الواسع في التحريك. تُعدّ واجهة برمجة التطبيقات Web Animations API المنهج المُعتمد على المعايير القياسية والمتاح حاليًا في معظم المتصفحات الحديثة، مما يوفر كائناتٍ حقيقية مثالية للتطبيقات المعقدة الموجهة بالكائنات. تُعدّ JavaScript مفيدةً أيضًا عند الحاجة إلى إيقاف التحريك، أو إيقافه مؤقتًا، أو إبطائه، أو عكسه.
-
يُمكن استخدام إطار التحريك للطلب
requestAnimationFrame
مباشرًة عند الحاجة لتنسيق مشهدٍ كاملٍ يدويًا. يُعدّ ذلك منهجًا متقدمًا في JavaScript، إلا أنه يكون مفيدًا عند إنشاء لعبة أو الرسم على لوحة HTML canvas.
بالمقابل، في حال استخدام إطار عمل JavaScript الذي يتضمن وظائف التحريك، مثل دالة التحريك .animate()
في jQuery، فقد يكون من الأنسب الالتزام بذلك في التحريك عمومًا.
التحريك باستخدام CSS
يُعدّ التحريك باستخدام CSS أبسط طرق تحريك شيءٍ ما على الشاشة، حيث يوصف هذا الأسلوب بأنه تصريحي لأنه يُحدّد ما المطلوب حدوثه.
يُبين المثال التالي تحريك صندوقٍ باستخدام CSS بمقدار 100px
في كلا المحورين X و Y، حيث ضُبط زمن الانتقال ليأخذ 500 ميلي ثانية (نصف ثانية). تتغير القيمة transform
عند إضافة الصف move
ويبدأ الانتقال.
.box { transform: translate(0, 0); transition: transform 500ms; } .box.move { transform: translate(100px, 100px); }
يُمكن تجريب المثال.
يوجد إضافًة إلى مدة الانتقال خياراتٍ للتخفيف easing، والتي تُساهم في جعل التحريك يبدو طبيعيًا. يُمكن الرجوع إلى أساسيات التخفيف لمزيدٍ من التفاصيل.
في حال إنشاء صفوفٍ مستقلة في CSS لإدارة التحريك كما هو الحال في المثال أعلاه، يُمكن استخدام JavaScript لتبديل حالة التحريك نعم/لا on/off.
box.classList.add('move');
يوفِّر ذلك توازنًا جيدًا للتطبيقات؛ إذ يُمكن للمطور التركيز على إدارة الحالة باستخدام JavaScript، وتعيين الصفوف المناسبة للعناصر المستهدفة ببساطة، وترك المتصفح يتعامل مع التحريك. يُمكن في حال اعتماد هذا المنهج الاستماع إلى أحداث نهاية الانتقال transitionend
للعنصر، وذلك في حال قبول التخلي عن دعم الإصدارات الأقدم من Internet Explorer، حيث كان الإصدار 10 هو الإصدار الأول لدعم هذه الأحداث. دعمت جميع المتصفحات الأخرى هذه الأحداث منذ فترة.
تكون شيفرة JavaScript المطلوبة للاستماع إلى حدث انتهاء الانتقال كما يلي:
var box = document.querySelector('.box'); box.addEventListener('transitionend', onTransitionEnd, false); function onTransitionEnd() { //معالجة إنهاء الانتقال }
يُمكن استخدام التحريك في CSS إضافًة إلى استخدام الانتقالات للحصول على مزيدٍ من التحكم في الإطارات الرئيسية للتحريك الفردي والمُدّد الزمنية والتكرارات.
ملاحظة: يُعدّ الإطار الرئيسي keyframe مصطلحًا قديمًا من مصطلحات الرسوم المتحركة المرسومة يدويًا. يُنشئ رسامو الرسوم المتحركة إطاراتٍ مُحدّدةً لجزءٍ من العمل، تُدعى الإطارات الرئيسية، والتي من شأنها أن تلتقط أشياءً مثل الجزء الأكثر تطرفًا في حركةٍ ما، ثم يشرعون في رسم جميع الإطارات الفردية بين الإطارات الرئيسية. يسلك التحريك في CSS سلوكًا مشابهًا؛ حيث يُعلَم المتصفح ببعض قيم خصائص CSS في نقاط مُحدّدة ويُطلب منه ملء القيم الناقصة.
يُمكن مثلًا تحريك صندوق المثال السابق بنفس الطريقة مع انتقالات وبتكرارٍ لا نهائي، ولكن بدون أي تفاعلٍ للمستخدم مثل النقر. كما يُمكن تغيير عدة خصائص في نفس الوقت:
.box { /* اختيار التحريك */ animation-name: movingBox; /* مدّة التحريك */ animation-duration: 1300ms; /* عدد مرات التحريك */ animation-iteration-count: infinite; /* تبديل اتجاه التحريك عند كل دورة فردية */ animation-direction: alternate; } @keyframes movingBox { 0% { transform: translate(0, 0); opacity: 0.3; } 25% { opacity: 0.9; } 50% { transform: translate(100px, 100px); opacity: 0.2; } 100% { transform: translate(30px, 30px); opacity: 0.8; } }
يُمكن تجريب المثال.
يُمكن تعريف التحريك نفسه بصورةٍ مستقلة عن العنصر الهدف، ويُمكن استخدام خاصية اسم التحريك animation-name
لاختيار التحريك المطلوب.
يجب إضافة بادئات البائع vendor prefixes إذا أردنا أن يعمل تحريك CSS على المتصفحات القديمة. ويُمكن للعديد من الأدوات أن تُساعد في إنشاء إصدارات CSS مع البادئة المطلوبة، مما يسمح للمطوّر بكتابة الإصدار دون البادئات في ملفات المصدر الخاصة به.
التحريك باستخدام JavaScript وواجهة برمجة التطبيقات Web Animations API
يُعدّ إنشاء التحريك باستخدام JavaScript أكثر تعقيدًا موازنًة مع كتابة الانتقالات أو التحريك في CSS، إلا أنه يوفر قوةً أكبر للمطورين. يُمكن استخدام واجهة برمجة التطبيقات Web Animations API إما لتحريك خصائص CSS معينة، أو لإنشاء كائناتٍ ذات تأثيرات مركبة.
يكون استخدام JavaScript للتحريك حتميًا مع كتابة التعليمات سطريًا inline ضمن الشيفرة، كما يُمكن تغليفها داخل كائناتٍ أخرى. تُبيّن الشيفرة التالية كيفية إنشاء نفس تحريك CSS المُوضح في المثال السابق:
var target = document.querySelector('.box'); var player = target.animate([ {transform: 'translate(0)'}, {transform: 'translate(100px, 100px)'} ], 500); player.addEventListener('finish', function() { target.style.transform = 'translate(100px, 100px)'; });
تنحصر المهمة الأساسية للتحريك باستخدام Web Animation في تعديل كيفية تقديم وعرض العنصر للمستخدم؛ أما في حال الرغبة ببقاء العنصر في المكان الذي انتقل إليه، فيجب تعديل أنماطه عند انتهاء التحريك كما في المثال السابق.
تُعدّ واجهة برمجة التطبيقات Web Animations API معيارًا جديدًا نسبيًا من W3C، وهو مدعومٌ بصورةٍ أساسية في معظم المتصفحات الحديثة؛ أما بالنسبة للمتصفحات الحديثة غير الداعمة، فيُمكن استخدام المشروع من النوع "نقص الدعم" polyfill المُتاح على github؛ وهو مشروع JavaScript يوفر ميزات Web Animation.
توفّر JavaScript للمطور تحكمًا كاملًا في أنماط العنصر عند أي خطوة؛ أي أنه يُمكن إبطاء التحريك أو إيقافه مؤقتًا أو توقيفه أو عكسه من خلال التعامل مع العناصر بصورةٍ مناسبة، ويكون هذا مفيدًا جدًا في بناء التطبيقات المعقدة كائنية التوجه؛ حيث يتمكن المطور من تغليف سلوك التحريك بصورةٍ مناسبة.
التحريك والأداء
يجب الحفاظ على 60 إطارًا في الثانية عند التحريك دومًا؛ حيث تؤدي أي قيمةٍ أقل من ذلك إلى ظهور التقطيع، أو توقُّف التحريك واللذان يكونان واضحين للمستخدمين مما يؤدي إلى تردّي تجربة الاستخدام.
- يجب الحرص على ألّا يُسبب التحريك أية مشاكل في الأداء؛ حيث يجب معرفة تأثير أي خاصية في أنماط CSS على الأداء.
- يجب الانتباه إلى أن جميع الخصائص التي تُغيُّر في هندسة الصفحة (التخطيط) أو تتسب في الطلاء تكون مُكلفةً على نحوٍ خاص.
- يجب الالتزام بتعديل التحويلات والشفافية ما أمكن ذلك.
-
يُمكن استخدام سوف يُعدّل
will-change
للتأكد من معرفة المتصفح ما يُخطط لتحريكه.
لا يكون تحريك الخصائص مجاني، كما أن تحريك بعض الخصائص أقل كلفةً من غيرها؛ حيث يُعدّل مثلًا تحريك العرض width
والارتفاع height
لعنصرٍ من هندسته، ويُمكن أن يؤدي ذلك إلى تحريك أو تغيير حجوم عناصرٍ أخرى على الصفحة. تُدعى هذه العملية بالتخطيط أو إعادة التدفق في بعض المتصفحات مثل Firefox المعتمدة على محرك المتصفحات Gecko؛ وهي عمليةٌ مكلفةٌ لاسيما إذا احتوت الصفحة على عناصر كثيرة. كلما يُشغّل التخطيط تحتاج الصفحة أو جزءٌ منها إلى إعادة الطلاء والذي يكون أكثر كلفًة من عملية التخطيط نفسها.
يجب تجنُّب تحريك الخصائص التي تؤدي إلى تنشيط التخطيط أو الطلاء ما أمكن ذلك؛ وهذا يعني قصر التحريك على الشفافية opacity
أو التحويلات transform
بالنسبة لمعظم المتصفحات الحديثة، واللتان يتمكن المتصفح من تحسينها بدرجة عالية. لا يُشكّل التعامل مع التحريك باستخدام JavaScript أو CSS فرقًا بالنسبة للأداء.
يُمكن الرجوع إلى CSS Triggers للحصول على قائمةٍ كاملة لما يُنشّط تشغيله عند استخدام خصائص CSS الفردية، كما يُمكن الرجوع للمرجع الكامل لإنشاء تحريك عالي الأداء في عناصر HTML5.
استخدام خاصية will-change
تُعلّم الخاصية will-change
المتصفح بالنية في تعديل خاصية عنصر، مما يسمح للمتصفح بوضع التحسينات الأكثر ملاءمةً في مكانها قبل إجراء التعديل. ومع ذلك، لا يجب الإفراط في استخدام الخاصية will-change
؛ لأن ذلك يؤدي إلى إضاعة الموارد ومزيدًا من مشاكل الأداء.
تنص أحد القواعد التجريبية الأساسية على أنه إذا كان تنشيط التحريك سيبدأ خلال 200 ميلي ثانية القادمة، إما عن طريق تفاعل المستخدم أو بسبب حالة التطبيق، فإن وضع will-change
يُعدّ فكرةً جيدة. يجب تمكين will-change
في معظم الحالات لكل خاصيةٍ يُخطط لتحريكها لاحقًا. فعلى سبيل المثال، ستكون إضافة will-change
للتحويلات والشفافية في أمثلتنا السابقة على النحو التالي:
.box { will-change: transform, opacity; }
ستُجري المتصفحات التي تدعم هذه الخاصية (حاليًا معظم المتصفحات الحديثة) التحسينات المناسبة في الخلفية لدعم تعديل هذه الخصائص أو تحريكها.
أداء CSS موازنة مع أداء JavaScript
يوجد العديد من الصفحات والتعليقات في عالم الويب التي تناقش المزايا النسبية للتحريك باستخدام CSS و JavaScript من منظور الأداء. فيما يلي بعض النقاط التي يجب الانتباه لها:
- يُدعَم التحريك المعتمد على أنماط CSS و Web Animations بصورةٍ أساسية ويُعالج ضمن خيطٍ thread منفصل يُعرف باسم "الخيط المُركَّب compositor thread"؛ والذي يختلف عن "الخيط الرئيسي main thread" للمتصفح، الذي يُنفذّ التصميم والتخطيط والطلاء وسكريبت جافا؛ مما يعني أنه إذا شغَّل المتصفح بعض المهام المكلفة على الخيط الرئيسي، يبقى التحريك مستمرًا دون أي مقاطعة.
- يُمكن في كثيرٍ من الحالات معالجة التعديلات الأخرى على التحويلات والشفافية باستخدام الخيط المُركّب.
- إذا أدى أي تحريكٍ إلى تشغيل الطلاء أو التخطيط أو كليهما، فسيُعهد إلى "الخيط الرئيسي" مهمة تنفيذ العمل وذلك في حالة التحريك المُستند إلى CSS أو JavaScript. يُمكن أن يؤدي الحمل الزائد للتخطيط أو الطلاء إلى بطء أي عملٍ مرتبطٍ بتنفيذ CSS أو JavaScript، مما يجعل المسألة موضع نقاش.
يُمكن العودة إلى CSS Triggers لمزيدٍ من المعلومات حول العمل المُنّشط عند تحريك خاصيةٍ ما.
ترجمة -وبتصرف- للمقالات التالية:
- Animations للمؤلف: Paul Lewis.
- CSS Versus JavaScript Animations للمؤلفين: Paul Lewis و Sam Thorogood.
- Animations and Performance
للمؤلفين: Paul Lewis و Sam Thorogood.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.