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