تنظيم الصور المتحركة مع تقديم وعود، وتحسين الأداء باستخدام صور متحركة قابلة للاستبدال، وصور متحركة أكثر سلاسة مع أوضاع مركّبة، والمزيد.
تاريخ النشر: 27 أيار (مايو) 2020
عند استخدامها بشكل صحيح، تُحسِّن الصور المتحركة من إدراك المستخدم وذاكرته لعلامتك التجارية، وترشد إجراءات المستخدم، وتساعد المستخدمين في التنقّل في تطبيقك، ما يقدّم سياقًا في المساحة الرقمية.
Web Animations API هي أداة تتيح للمطوّرين كتابة حركات إلزامية باستخدام JavaScript. وقد تم إنشاؤه لتوفير أساس لتنفيذ كلّ من حركات CSS وعمليات النقل، ولتمكين تطوير التأثيرات المستقبلية، بالإضافة إلى إنشاء التأثيرات الحالية وتحديد وقتها.
على الرغم من أنّ Firefox وSafari قد نفّذا المجموعة الكاملة من ميزات المواصفات، يقدّم الإصدار 84 من Chromium مجموعة كبيرة من الميزات غير المتوافقة سابقًا في Chrome وEdge، ما يتيح التشغيل التفاعلي بين المتصفّحات.
الخطوات الأولى
في حال استخدام قواعد @keyframe
، من المفترض أن يكون إنشاء صورة متحركة باستخدام Web Animations API مألوفًا جدًا. عليك أولاً إنشاء عنصر لقطة رئيسية. قد يبدو ذلك على النحو التالي في CSS:
@keyframes openAnimation {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
ستظهر بالشكل التالي في JavaScript:
const openAnimation = [
{ transform: 'scale(0)' },
{ transform: 'scale(1)' },
];
حيث يمكنك ضبط مَعلمات للحركة في CSS:
.modal {
animation: openAnimation 1s 1 ease-in;
}
التي ستقوم بتعيينها في JS:
document.querySelector('.modal').animate(
openAnimation, {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: 'ease-in' // easing function
}
);
تكون كمية الرموز البرمجية متماثلة تقريبًا، ولكن باستخدام JavaScript، يمكنك الحصول على ميزتَين هامتين لا تتوفّر لك باستخدام CSS وحده. ويشمل ذلك إمكانية ترتيب التأثيرات والتحكّم بشكل أكبر في حالات تشغيلها.
أكثر من element.animate()
ومن خلال هذا التحديث، لن تقتصر واجهة برمجة التطبيقات Web Animations API على الصور المتحركة التي يتم إنشاؤها باستخدام "element.animate()
". يمكننا أيضًا التلاعب بالحركات وتأثيرات الانتقال في CSS.
getAnimations()
هي طريقة تعرض جميع الصور المتحركة في عنصر بغض النظر عمّا إذا تم إنشاؤها باستخدام element.animate()
أو باستخدام قواعد CSS (الحركة أو الانتقال في CSS). في ما يلي مثال على الشكل الذي قد يبدو عليه ذلك:
عليك أولاً "get"
لقطات الإطار الرئيسية للانتقال لتحديد المكان الذي ننتقل منه. بعد ذلك، تقوم بإنشاء رسمين متحركين جديدين للتعتيم، مما يتيح تأثير التلاشي المتقاطع. بعد اكتمال التلاشي المتقاطع، يمكنك حذف النسخة.
كيفية تنظيم الصور المتحركة مع تقديم الوعود
في Chromium 84، لديك الآن طريقتان يمكنك استخدامهما مع الوعود التالية: animation.ready
وanimation.finished
.
animation.ready
يتيح لك الانتظار إلى أن تسري التغييرات المعلّقة (أي التبديل بين طرق التحكّم في التشغيل، مثل التشغيل والإيقاف المؤقت).animation.finished
توفّر وسيلة لتنفيذ رمز JavaScript مخصّص عند اكتمال الحركة.
المتابعة للمثال الذي ذكرناه وإنشاء سلسلة منسَّقة للصور المتحركة باستخدام "animation.finished
" في ما يلي تحويل عمودي (scaleY
) يليه تحويل أفقي (scaleX
) يليه تغيير في الشفافية لعنصر ثانوي:
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});
لقد ربطنا هذه الرسوم المتحركة باستخدام animation.finished.then()
قبل تنفيذ مجموعة الرسوم المتحركة التالية في السلسلة. بهذه الطريقة، تظهر الصور المتحركة بالترتيب، ويمكنك أيضًا تطبيق تأثيرات على عناصر مستهدَفة مختلفة مع ضبط خيارات مختلفة (مثل السرعة والسهولة).
سيكون من الصعب إعادة إنشاء هذا التأثير في CSS، خاصةً عند تطبيق حركات فريدة ولكن متسلسلة على عناصر متعددة. وعليك استخدام @keyframe
، وترتيب النسب المئوية الصحيحة للتوقيت لوضع الصور المتحركة، واستخدام animation-delay
قبل تشغيل الصور المتحركة في التسلسل.
مثال: التشغيل والإيقاف المؤقت والعكس
ما يمكن أن يفتح، يجب أن يُغلق! لحسن الحظ، منذ إصدار Chromium 39، تمكّنت من خلال Web Animations API من تشغيل الرسوم المتحرّكة وإيقافها مؤقتًا وعكسها.
يمكنك استخدام الرسم المتحرك الذي تم عرضه سابقًا وتطبيق حركة عكسية سلسة عليه عند النقر على الزر مرة أخرى باستخدام .reverse()
. بهذه الطريقة، يمكنك إنشاء تفاعل أكثر سلاسة وسياقًا للنموذج.
ما يمكنك فعله هو إنشاء صورتَين متحركتَين في انتظار التشغيل (openModal
، وتحويل تعتيم مضمّن)، ثم إيقاف إحدى الصور المتحركة مؤقتًا، وتأخيرها حتى انتهاء الأخرى. يمكنك بعد ذلك استخدام الطلبات في انتظار اكتمال كل عملية قبل تشغيلها. أخيرًا، يمكنك التحقق لمعرفة ما إذا تم تعيين علامة أم لا، ثم عكس كل رسم متحرك.
مثال: التفاعلات الديناميكية مع اللقطات الرئيسية الجزئية
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
في هذا المثال، لا يتوفّر سوى إطار رئيسي واحد، ولا يتوفّر موضع بدء محدّد. هذا مثال على استخدام إطارات رئيسية جزئية. ينفّذ معالِج الماوس بعض الإجراءات هنا: يحدّد موقعًا نهائيًا جديدًا ويشغّل صورة متحركة جديدة. يتم استنتاج موضع البدء الجديد من الموضع الأساسي الحالي.
يمكن تشغيل انتقالات جديدة عندما تكون الانتقالات الحالية لا تزال قيد التشغيل. وهذا يعني أنّه يتم إيقاف عملية النقل الحالية وإنشاء عملية جديدة.
تحسينات الأداء باستخدام الصور المتحركة القابلة للاستبدال
عند إنشاء صور متحركة استنادًا إلى أحداث، مثل أحداث في 'mousemove'
، يتم إنشاء صورة متحركة جديدة في كل مرة، ما قد يؤدي إلى استهلاك الذاكرة بسرعة وخفض مستوى الأداء. لحلّ هذه المشكلة، تمّت إضافة صور متحركة قابلة للاستبدال في الإصدار 83 من Chromium، ما يتيح عملية تنظيف مبرمَجة يتم فيها وضع علامة على الصور المتحركة المكتملة كصور قابلة للاستبدال ويتمّ إزالتها تلقائيًا إذا تم استبدالها بصورة متحركة مكتملة أخرى. راجع المثال التالي:
elem.addEventListener('mousemove', evt => {
rectangle.animate(
{ transform: translate(${evt.clientX}px, ${evt.clientY}px) },
{ duration: 500, fill: 'forwards' }
);
});
في كل مرة يتم فيها تحريك الماوس، يعيد المتصفّح احتساب موضع كل كرة في مسار المذنب وينشئ صورة متحركة لهذه النقطة الجديدة. يعرف المتصفّح الآن كيفية إزالة الصور المتحركة القديمة (لتفعيل الاستبدال) في الحالات التالية:
- تنتهي الصورة المتحركة.
- هناك صورة متحركة واحدة أو أكثر في ترتيب مكوّن أعلى من الصورة المتحركة التي تم الانتهاء منها أيضًا.
- تعمل الصور المتحركة الجديدة على تحريك الخصائص نفسها.
يمكنك معرفة عدد الصور المتحركة التي يتم استبدالها بالضبط من خلال احتساب عدد الصور المتحركة التي تمّت إزالتها، وذلك باستخدام anim.onremove
لتشغيل المعداد.
هناك بعض الطرق الإضافية لتحسين التحكم في الصور المتحركة:
- يقدّم
animation.replaceState()
وسيلة لتتبُّع ما إذا كان المؤثر المتحرك نشطًا أو ثابتًا أو تمت إزالته. animation.commitStyles()
تُعدِّل نمط عنصر استنادًا إلى النمط الأساسي، بالإضافة إلى جميع الحركات على العنصر بالترتيب المركب.- يضع
animation.persist()
علامة على الصورة المتحركة بأنّه لا يمكن استبدالها.
صور متحركة أكثر سلاسة باستخدام أوضاع مركّبة
باستخدام Web Animations API، يمكنك الآن ضبط الوضع المركب للرسومات المتحركة، ما يعني أنّها يمكن أن تكون تراكبية أو تراكمية، بالإضافة إلى الوضع التلقائي "استبدال". تسمح الأوضاع المركبة للمطوّرين بكتابة صور متحركة مميّزة والتحكّم في كيفية دمج التأثيرات. هناك ثلاثة أوضاع مُركّبة متاحة الآن: 'replace'
(الوضع التلقائي) و'add'
و'accumulate'
.
عند إنشاء صور متحركة، يمكن للمطوّر إنشاء تأثيرات قصيرة ومميّزة وعرضها معًا. في المثال التالي، نطبِّق دورانًا وتغيير إطارها الرئيسي على كل مربّع، ويكون التعديل الوحيد هو الوضع المركّب، وتتم إضافته كخيار:
في الوضع التلقائي للمركب 'replace'
، تستبدل الصورة المتحركة النهائية خاصية التحويل وتنتهي في rotate(360deg) scale(1.4)
. بالنسبة إلى 'add'
، يضيف المركّب الدوران ويضرب المقياس، ما يؤدي إلى الحصول على حالة نهائية بقيمة rotate(720deg) scale(1.96)
. تجمع 'accumulate'
عمليات التحويل، ما يؤدي إلى rotate(720deg) scale(1.8)
. لمزيد من المعلومات عن التفاصيل الدقيقة لهذه الأوضاع المركبة، اطّلِع على تعدادات CompositeOperation وCompositeOperationOrAuto من مواصفات Web Animations.
اطّلِع على مثال عنصر واجهة المستخدم التالي:
في ما يلي صورتان متحركتان top
تم دمجهما. الأول هو صورة متحركة كبيرة، تنقل القائمة المنسدلة بالارتفاع الكامل للقوائم نفسها كتأثير للانزلاق من أعلى الصفحة، والثاني هو صورة متحركة صغيرة، تطبّق نطاطات صغيرة عند وصولها إلى أسفل الصفحة. يتيح استخدام الوضع المركّب 'add'
الانتقال بشكل أكثر سلاسة.
const dropDown = menu.animate(
[
{ top: `${-menuHeight}px`, easing: 'ease-in' },
{ top: 0 }
], { duration: 300, fill: 'forwards' });
dropDown.finished.then(() => {
const bounce = menu.animate(
[
{ top: '0px', easing: 'ease-in' },
{ top: '10px', easing: 'ease-out' },
{ ... }
], { duration: 300, composite: 'add' });
});
الخطوات التالية لواجهة برمجة التطبيقات Web Animations API
هذه كلها إضافات مثيرة لإمكانات الصور المتحرّكة في متصفّحات اليوم، وسنضيف المزيد من الإضافات في المستقبل. يمكنك الاطّلاع على هذه المواصفات المستقبلية للحصول على مزيد من المعلومات حول الميزات القادمة: