تنسيق الصور المتحركة مع الوعود، وتحسينات الأداء باستخدام الصور المتحركة القابلة للاستبدال، والصور المتحركة الأكثر سلاسة باستخدام الأوضاع المركبة، وغير ذلك
تاريخ النشر: 27 أيار (مايو) 2020
عند استخدامها بشكل صحيح، تُحسِّن الصور المتحركة من إدراك المستخدم وذاكرته لعلامتك التجارية، وترشد إجراءات المستخدم، وتساعد المستخدمين في التنقّل في تطبيقك، ما يقدّم سياقًا في المساحة الرقمية.
Web Animations API هي أداة تتيح للمطوّرين كتابة حركات إلزامية باستخدام JavaScript. وقد تم إنشاؤه لتوفير أساس لتنفيذ كلّ من الحركات والانتقالات في CSS، ولتمكين تطوير التأثيرات المستقبلية، بالإضافة إلى إنشاء التأثيرات الحالية وتحديد وقتها.
على الرغم من أنّ Firefox وSafari قد نفّذا المجموعة الكاملة من ميزات المواصفات، يقدّم الإصدار 84 من Chromium مجموعة كبيرة من الميزات غير المتوافقة سابقًا في Chrome وEdge، ما يتيح التشغيل التفاعلي بين المتصفّحات.
الخطوات الأولى
من المفترض أن يكون إنشاء صورة متحركة باستخدام Web Animations API مألوفًا جدًا إذا سبق لك استخدام قواعد @keyframe
. عليك أولاً إنشاء عنصر لقطة رئيسية. قد يبدو ذلك على النحو التالي في 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"
لقطات الإطار الرئيسية للانتقال لتحديد المكان الذي ننتقل منه. بعد ذلك، يمكنك إنشاء مؤثرَين جديدَين للّون الشفاف، ما يتيح تأثير التمويه. بعد اكتمال عملية التلاشي، يمكنك حذف النسخة.
كيفية تنسيق الرسوم المتحرّكة باستخدام الوعود
في الإصدار 84 من Chromium، تتوفّر لك الآن طريقتان يمكن استخدامهما مع الوعود: 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
هذه كلها إضافات مثيرة لإمكانات الصور المتحرّكة في متصفّحات اليوم، وسنضيف المزيد من الإضافات في المستقبل. يمكنك الاطّلاع على هذه المواصفات المستقبلية للحصول على مزيد من المعلومات حول الميزات القادمة: