تحسينات على Web Animations API في Chromium 84

تنسيق الصور المتحركة مع الوعود، وتحسينات الأداء باستخدام صور متحركة قابلة للاستبدال، وصور متحركة أكثر سلاسة من خلال الأوضاع المركّبة، والمزيد

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

Web Animations API هي أداة تتيح للمطوّرين كتابة الصور المتحركة الضرورية باستخدام JavaScript. وقد تمت كتابته لدعم كل من الرسوم المتحركة في CSS وتنفيذ عمليات الانتقال والسماح بتطوير التأثيرات المستقبلية، بالإضافة إلى إنشاء التأثيرات الحالية وتحديد توقيتها.

على الرغم من أنّ Firefox وSafari قد نفّذا بالفعل المجموعة الكاملة من الميزات للمواصفات، يوفّر Chromium 84 عددًا كبيرًا من الميزات غير المتوافقة سابقًا إلى Chrome وEdge، ما يتيح إمكانية التشغيل التفاعلي على جميع المتصفحات.

ظهرت واجهة برمجة التطبيقات Web Animations API لأول مرة على Chromium في الإصدار 36 تموز (يوليو) 2014. ستكتمل الآن المواصفات في الإصدار 84 وستُتاح في تموز (يوليو) 2020.
السجلّ الطويل لواجهة Web Animations API في Chromium.

الخطوات الأولى

من المفترض أن يبدو إنشاء صورة متحركة عبر 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)، متبوعًا بتغيير تعتيم عنصر فرعي:

تطبيق التحويلات والتعتيم على عنصر نمطي افتتاحي. الاطّلاع على عرض توضيحي على Codepen
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(). بهذه الطريقة، يمكنك إنشاء تفاعل أكثر سلاسة وسياقًا لنموذجنا.

مثال على فتح مربّع وإغلاقه عند النقر على الزر الاطّلاع على عرض توضيحي لميزة Glitch

ما يمكنك فعله هو إنشاء صورتَين متحرّكتَين قيد التشغيل في انتظار التشغيل (openModal، وتحويل مضمّن لتعتيم الصورة)، ثم إيقاف إحداهما مؤقتًا مع تأخير عرضها حتى انتهاء الأخرى. ويمكنك بعد ذلك استخدام وعود بالانتظار حتى انتهاء كل منها قبل اللعب. أخيرًا، يمكنك التحقق لمعرفة ما إذا تم تعيين علامة، ثم عكس كل رسم متحرك.

مثال: التفاعلات الديناميكية مع الإطارات الرئيسية الجزئية

مثال على إعادة الاستهداف، حيث يتم من خلال النقر بالماوس على الصورة المتحركة لضبط موقع جديد. الاطّلاع على عرض توضيحي حول Glitch
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

في هذا المثال، يوجد إطار رئيسي واحد فقط، وليس هناك موضع بدء محدد. هذا مثال على استخدام الإطارات الرئيسية الجزئية. ينفّذ معالِج الماوس بعض الإجراءات في هذه الحالة: فهو يضبط موضع انتهاء جديد ويشغّل رسمًا متحركًا جديدًا. يتم استنتاج موضع البدء الجديد من الموضع الأساسي الحالي.

يمكن بدء عمليات نقل جديدة أثناء تشغيل عمليات النقل الحالية. وهذا يعني أنّه تتم مقاطعة الانتقال الحالي وإنشاء عملية انتقال جديدة.

تحسينات على الأداء باستخدام الصور المتحركة القابلة للاستبدال

عند إنشاء صور متحركة استنادًا إلى الأحداث، مثلاً في 'mousemove'، يتم إنشاء صورة متحركة جديدة في كل مرة، ما قد يؤدي إلى استهلاك الذاكرة بسرعة وتقليل الأداء. لحلّ هذه المشكلة، تم طرح الصور المتحركة القابلة للاستبدال في إصدار Chromium 83، ما أتاح إزالة الصور المتحركة آليًا، حيث يتم وضع علامة على الصور المتحركة المنتهية كعناصر قابلة للاستبدال وتتم إزالتها تلقائيًا في حال استبدالها بصور متحركة أخرى مكتملة. راجع المثال التالي:

يتحرك ممر المذنب عند تحرك الماوس. الاطّلاع على عرض توضيحي حول Glitch
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

وفي كل مرة يتحرك فيها الماوس، يعيد المتصفّح احتساب موضع كل كرة في مسار المذنب وينشئ رسومًا متحركة لهذه النقطة الجديدة. يعرف المتصفّح الآن إزالة الصور المتحركة القديمة (تفعيل الاستبدال) عند:

  1. انتهت الرسوم المتحركة.
  2. هناك صورة متحركة واحدة أو أكثر أعلى في الترتيب المركب والتي تم الانتهاء منها أيضًا.
  3. تحرّك الصور المتحركة الجديدة نفس الخصائص.

يمكنك أن ترى بالضبط عدد الصور المتحركة التي يتم استبدالها من خلال احتساب عدّاد مع كل صورة متحركة تمت إزالتها، باستخدام anim.onremove لتشغيل العدّاد.

تتوفر بعض الطرق الإضافية للتحكّم في الصور المتحركة بشكل أكبر:

  • توفّر animation.replaceState() وسيلة لتتبُّع ما إذا كانت الصورة المتحركة نشطة أو مستمرة أو تمت إزالتها.
  • animation.commitStyles() يحدّث نمط العنصر بناءً على النمط الأساسي إلى جانب جميع الرسوم المتحركة على العنصر بالترتيب المركّب.
  • يضع animation.persist() علامة على صورة متحركة بأنّها لا يمكن استبدالها.

صور متحركة أكثر سلاسة في الأوضاع المركّبة

باستخدام Web Animations API، يمكنك الآن ضبط الوضع المركّب للصور المتحركة، ما يعني أنّها يمكن أن تكون تراكمية أو تراكمية، بالإضافة إلى الوضع التلقائي "replace". تسمح الأوضاع المركّبة للمطوّرين بكتابة صور متحركة مختلفة والتحكّم في كيفية دمج التأثيرات. تتوفر الآن ثلاثة أوضاع مركّبة: 'replace' (الوضع التلقائي) و'add' و'accumulate'.

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

عرض توضيحي يعرض الأوضاع التلقائية والإضافة وتجميع الأوضاع المركّبة. الاطّلاع على عرض توضيحي لميزة Glitch

في الوضع المركّب التلقائي 'replace'، تحلّ الصورة المتحركة النهائية محلّ خاصية التحويل وتنتهي عند rotate(360deg) scale(1.4). بالنسبة إلى 'add'، يضيف المركب التدوير ويضرب المقياس، ما يؤدي إلى الحصول على الحالة النهائية لـ rotate(720deg) scale(1.96). يدمج 'accumulate' عمليات التحويل، ما يؤدي إلى rotate(720deg) scale(1.8). لمزيد من المعلومات عن تعقيدات هذه الأوضاع المركّبة، راجع The CompositeOperation وCompositeOperationOrAuto enumerations من مواصفات Web Animations.

لنلقِ نظرة على مثال على عنصر في واجهة المستخدم:

قائمة منسدلة مرتدّة تتضمّن صورتَين متحرّكتين مركّبة تم تطبيقهما عليها. الاطّلاع على عرض توضيحي لميزة Glitch

في هذا المثال، يتم إنشاء صور متحركة من نوع 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

هذه كلها إضافات مثيرة للاهتمام بإمكانات الصور المتحركة في متصفحات اليوم، وهناك المزيد من الإضافات في المستقبل. يُرجى الاطّلاع على هذه المواصفات المستقبلية لمزيد من المعلومات عن الميزات القادمة: