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

تعرَّف على طريقة استخدام ميزة "التمرير الزمني" و"عرض المخططات الزمنية" لإنشاء صور متحركة تستند إلى الانتقال بشكل مرئي.

الصور المتحركة المستندة إلى التمرير

دعم المتصفح

  • Chrome: 115.
  • الحافة: 115.
  • متصفّح Firefox: خلف علم
  • Safari: غير متاح.

المصدر

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

مؤشر قراءة في أعلى المستند، من خلال الانتقال للأسفل أو للأعلى

نوع مشابه من الرسوم المتحركة القائمة على التمرير هو الرسوم المتحركة المرتبطة بموضع العنصر داخل حاوية التمرير الخاصة به. باستخدامها، على سبيل المثال، يمكن أن تتلاشى العناصر عندما تظهر.

تتلاشى الصور في هذه الصفحة عند ظهورها.

والطريقة الكلاسيكية لتنفيذ هذه الأنواع من التأثيرات هي الاستجابة لأحداث التمرير في سلسلة المحادثات الرئيسية، ما يؤدي إلى مشكلتَين رئيسيتَين:

  • تنفِّذ المتصفِّحات الحديثة عملية التمرير على عملية منفصلة، وبالتالي تعرض أحداث الانتقال بشكل غير متزامن.
  • تخضع الصور المتحركة لسلسلة المحادثات الرئيسية لميزة "إيقاف مؤقت".

وهذا يجعل إنشاء صور متحركة عالية الأداء تعتمد على التمرير ومتزامنة مع التمرير مستحيلاً أو صعبة للغاية.

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

تتكامل هذه المفاهيم الجديدة مع Web Animations API (WAAPI) وCSS Animations API الحاليتَين، ما يتيح له اكتساب الميزات التي توفّرها واجهات برمجة التطبيقات الحالية. يتضمن ذلك إمكانية تشغيل الرسوم المتحركة القائمة على التمرير خارج سلسلة التعليمات الرئيسية. نعم، اقرأ ذلك بشكل صحيح: يمكنك الآن الحصول على صور متحركة سلسة ومتسقة، تستند إلى التمرير، وتعمل خارج سلسلة التعليمات الرئيسية، مع إضافة بضعة أسطر من الرموز الإضافية. ما الذي لا يعجبك؟!

الصور المتحركة على الويب، ملخّص بسيط

الصور المتحركة على الويب باستخدام CSS

لإنشاء صورة متحركة في CSS، حدِّد مجموعة من الإطارات الرئيسية باستخدام قاعدة @keyframes. يمكنك ربط العنصر بعنصر باستخدام السمة animation-name مع ضبط animation-duration أيضًا لتحديد المدة التي يجب أن تستغرقها الحركة. يتوفّر المزيد من animation-* من المواقع الإلكترونية القديمة، مثل animation-easing-function وanimation-fill-mode، على سبيل المثال لا الحصر، ويمكن دمجها جميعًا في اختصار animation.

على سبيل المثال، إليك رسم متحرك يعمل على تصغير حجم عنصر على المحور س مع تغيير لون خلفيته أيضًا:

@keyframes scale-up {
  from {
    background-color: red;
    transform: scaleX(0);
  }
  to {
    background-color: darkred;
    transform: scaleX(1);
  }
}

#progressbar {
  animation: 2.5s linear forwards scale-up;
}
.

الصور المتحركة على الويب باستخدام JavaScript

في JavaScript، يمكن استخدام Web Animations API لتحقيق الشيء نفسه. يمكنك إجراء ذلك من خلال إنشاء مثيلَين Animation وKeyFrameEffect جديدَين، أو استخدام الطريقة الأقصر Element animate().

document.querySelector('#progressbar').animate(
  {
    backgroundColor: ['red', 'darkred'],
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    duration: 2500,
    fill: 'forwards',
    easing: 'linear',
   }
);

هذه النتيجة المرئية لمقتطف JavaScript أعلاه مماثلة لإصدار CSS السابق.

المخططات الزمنية للصور المتحركة

بشكل تلقائي، يتم تشغيل الصورة المتحركة المرفقة بأحد العناصر في المخطط الزمني للمستند. ويبدأ وقت المصدر من 0 عند تحميل الصفحة، ويبدأ في التقديم مع تقدم الوقت. هذا هو المخطط الزمني التلقائي للصور المتحركة، وكان حتى الآن هو المخطط الزمني الوحيد الذي يمكنك الوصول إليه.

تحدد مواصفات الحركات التي تعتمد على التمرير نوعين جديدين من المخططات الزمنية التي يمكنك استخدامهما:

  • المخطط الزمني لمستوى التقدُّم: مخطط زمني مرتبط بموضع التمرير في حاوية تمرير على محور معيّن.
  • عرض المخطط الزمني للتقدّم: مخطط زمني مرتبط بالموضع النسبي لعنصر معيّن ضمن حاوية التمرير.

الانتقال للأسفل أو للأعلى في المخطط الزمني

"المخطط الزمني لمستوى التقدُّم" في ميزة "التمرير" هو مخطط زمني للصور المتحركة مرتبط بالتقدّم في موضع التمرير لحاوية تمرير، ويُعرف أيضًا باسم شريط التمرير أو شريط التمرير، على محور معيّن. يحول موضعًا في نطاق تمرير إلى نسبة مئوية من التقدم.

ويمثل موضع التمرير عند البداية مستوى التقدم 0% ويمثل موضع التمرير في النهاية تقدمًا بنسبة 100%. في التصور التالي، يمكنك أن ترى أن التقدم يتم احتسابه من 0٪ إلى 100٪ أثناء تمرير أشرطة التمرير من أعلى إلى أسفل.

عرض مخطط زمني لتقدم التمرير وأثناء الانتقال إلى أسفل شريط التمرير، يتم احتساب قيمة مستوى التقدّم من% 0 إلى %100.

✨ جربها بنفسك

غالبًا ما يتم اختصار "المخطط الزمني لتقدم التمرير" ليصبح ببساطة "تمرير المخطط الزمني".

عرض المخطط الزمني لمستوى التقدُّم

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

يشبه ذلك إلى حدٍ ما طريقة عمل IntersectionObserver التي يمكنها تتبُّع مقدار ما يظهر فيه عنصر في شريط التمرير. إذا لم يكن العنصر مرئيًا في شريط التمرير، فهذا يعني أنه غير متقاطع. إذا كان مرئيًا داخل شريط التمرير - حتى بالنسبة لأصغر جزء - فسيكون متقاطعًا.

يبدأ عرض المخطط الزمني لمستوى التقدّم من اللحظة التي يبدأ فيها العنصر بالتقاطع مع شريط التمرير وينتهي عندما يتوقف الموضوع عن تقاطع شريط التمرير. في التصور التالي، يمكنك أن ترى أن التقدم يبدأ في العد من 0٪ عندما يدخل الموضوع في حاوية التمرير ويصل إلى 100٪ في اللحظة التي غادر فيها الموضوع حاوية التمرير.

عرض مخطط زمني لمستوى التقدّم يصل مستوى التقدّم من% 0 إلى% 100 عندما يتجاوز الهدف (المربّع الأخضر) شريط التمرير.

✨ جربها بنفسك

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

الاستفادة عمليًا من ميزة "المخطط الزمني لتقدم التمرير"

إنشاء مخطط زمني مجهول لتقدم التمرير في CSS

إنّ أسهل طريقة لإنشاء "مخطط زمني للتمرير" في CSS هي استخدام الدالة scroll(). يؤدي ذلك إلى إنشاء "المخطط الزمني للتمرير" بدون الكشف عن هويتك، ويمكنك ضبطه كقيمة للسمة animation-timeline الجديدة.

مثال:

@keyframes animate-it {  }

.subject {
  animation: animate-it linear;
  animation-timeline: scroll(root block);
}

تقبل الدالة scroll() الوسيطة <scroller> والوسيطة <axis>.

في ما يلي القيم المقبولة للوسيطة <scroller>:

  • nearest: يستخدم أقرب حاوية تمرير للكيان الأصل (الإعداد التلقائي).
  • root: تستخدم إطار عرض المستند كحاوية تمرير.
  • self: تستخدم العنصر نفسه كحاوية تمرير.

في ما يلي القيم المقبولة للوسيطة <axis>:

  • block: تُستخدَم هذه السمة قياس مدى التقدّم على محور القالب لحاوية التمرير (الإعداد التلقائي).
  • inline: تستخدم مقياس التقدم على طول المحور المضمَّن لحاوية التمرير.
  • y: تستخدم مقياس التقدم على طول المحور ص لحاوية التمرير.
  • x: تستخدم مقياس التقدم على طول المحور x لحاوية التمرير.

على سبيل المثال، لربط صورة متحركة بشريط التمرير الجذري على محور القالب، تكون القيم التي سيتم تمريرها إلى scroll() هي root وblock. بتجميع، القيمة هي scroll(root block).

عرض توضيحي: مؤشر تقدّم القراءة

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

العرض التوضيحي: مؤشر مستوى التقدّم في القراءة.

✨ جربها لنفسك

يظهر مؤشر تقدّم القراءة في أعلى الصفحة باستخدام الموضع الثابت. للاستفادة من الصور المتحركة المركّبة، لا يتم استخدام المؤثرات الحركية في width، ولكن تم تصغير العنصر على المحور x باستخدام transform.

<body>
  <div id="progress"></div>
  …
</body>
@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

#progress {
  position: fixed;
  left: 0; top: 0;
  width: 100%; height: 1em;
  background: red;

  transform-origin: 0 50%;
  animation: grow-progress auto linear;
  animation-timeline: scroll();
}

تم ضبط المخطط الزمني للصورة المتحركة grow-progress في العنصر #progress على مخطط زمني مجهول الهوية يتم إنشاؤه باستخدام scroll(). لم يتم توفير أي وسيطات للدالة scroll()، لذلك سيتم الرجوع إلى القيم التلقائية.

شريط التمرير التلقائي الذي يجب تتبُّعه هو nearest والمحور التلقائي هو block. يؤدي هذا الإجراء إلى استهداف شريط التمرير الجذري بفعالية أكبر، لأنّ هذا هو أقرب شريط تمرير للعنصر #progress، وذلك أثناء تتبُّع اتجاه حظر العنصر.

جارٍ إنشاء "المخطط الزمني لمستوى التقدُّم" باسم Scroll في خدمة مقارنة الأسعار (CSS).

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

لإنشاء "المخطط الزمني لمستوى تقدم التمرير" على أحد العناصر، اضبط سمة CSS scroll-timeline-name في حاوية التمرير على معرّف حسب رغبتك. يجب أن تبدأ القيمة بـ --.

لتعديل المحور الذي يجب تتبّعه، يجب أيضًا تعريف السمة scroll-timeline-axis. القيم المسموح بها هي نفس وسيطة <axis> لـ scroll().

أخيرًا، لربط الصورة المتحركة بالمخطط الزمني لمستوى تقدُّم الانتقال، اضبط السمة animation-timeline على العنصر الذي يجب تحريكه بالقيمة نفسها المُستخدَمة في المعرِّف المستخدَم في scroll-timeline-name.

مثال على الرمز البرمجي:

@keyframes animate-it {  }

.scroller {
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: inline;
}

.scroller .subject {
  animation: animate-it linear;
  animation-timeline: --my-scroller;
}

إذا أردت، يمكنك الجمع بين scroll-timeline-name وscroll-timeline-axis من خلال الاختصار scroll-timeline. على سبيل المثال:

scroll-timeline: --my-scroller inline;

يعرض هذا العرض التوضيحي مؤشر خطوات يظهر فوق كل لوحة عرض دوّارة للصور. عندما تحتوي لوحة العرض الدوّارة على ثلاث صور، يبدأ شريط المؤشر بعرض 33% للإشارة إلى أنك تنظر حاليًا إلى الصورة الأولى من ثلاث. عندما تكون الصورة الأخيرة في العرض - يحددها شريط التمرير بعد الانتقال إلى النهاية - يشغل المؤشر العرض الكامل لشريط التمرير. يتم استخدام مخطط "التقدم الزمني" المُسمّى لتحريك الصورة المتحركة.

العرض التوضيحي: مؤشر خطوات للوحة عرض دوّارة أفقية.

✨ جربها لنفسك

يكون الترميز الأساسي للمعرض هو:

<div class="gallery" style="--num-images: 2;">
  <div class="gallery__scrollcontainer">
    <div class="gallery__progress"></div>
    <div class="gallery__entry">…</div>
    <div class="gallery__entry">…</div>
  </div>
</div>

يتم تحديد موضع العنصر .gallery__progress بشكل كامل داخل عنصر تضمين .gallery. تحدِّد السمة المخصّصة --num-images حجمها الأولي.

.gallery {
  position: relative;
}


.gallery__progress {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 1em;
  transform: scaleX(calc(1 / var(--num-images)));
}

ينظّم .gallery__scrollcontainer عناصر .gallery__entry المضمّنة أفقيًا وهو العنصر الذي يمكن الانتقال إليه. ومن خلال تتبُّع موضع الانتقال، تظهر صورة متحركة على .gallery__progress. ويتم ذلك من خلال الرجوع إلى "المخطط الزمني لمستوى تقدّم التمرير" --gallery__scrollcontainer.

@keyframes grow-progress {
  to { transform: scaleX(1); }
}

.gallery__scrollcontainer {
  overflow-x: scroll;
  scroll-timeline: --gallery__scrollcontainer inline;
}
.gallery__progress {
  animation: auto grow-progress linear forwards;
  animation-timeline: --gallery__scrollcontainer;
}

إنشاء مخطط زمني لتقدم التمرير باستخدام JavaScript

لإنشاء مخطط زمني للتمرير في JavaScript، أنشِئ مثيلاً جديدًا للفئة ScrollTimeline. الدخول في حقيبة عقارية تحتوي على source وaxis المطلوب تتبُّعهما.

  • source: مرجع للعنصر الذي تريد تتبُّع شريط التمرير الخاص به استخدِم document.documentElement لاستهداف شريط التمرير الجذر.
  • axis: لتحديد المحور الذي يجب تتبّعه. على غرار صيغة CSS، القيم المقبولة هي block وinline وx وy.
const tl = new ScrollTimeline({
  source: document.documentElement,
});

لإرفاقها بإحدى الصور المتحركة على الويب، مرِّرها كسمة timeline واحذف أي duration في حال توفّر أي منها.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
});

عرض توضيحي: تمت إعادة النظر في مؤشر مستوى التقدّم في القراءة

لإعادة إنشاء مؤشر تقدّم القراءة باستخدام JavaScript مع استخدام الترميز نفسه، استخدِم رمز JavaScript التالي:

const $progressbar = document.querySelector('#progress');

$progressbar.style.transformOrigin = '0% 50%';
$progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

والنتيجة المرئية مماثلة في إصدار CSS: يتتبّع timeline الذي تم إنشاؤه شريط التمرير الجذري ويغيّر #progress على المحور x من 0% إلى 100% أثناء تمرير الصفحة.

✨ جربها لنفسك

تنفيذ الخطوات العملية باستخدام عرض المخطط الزمني لمستوى التقدّم

إنشاء مخطط زمني مجهول لمستوى التقدُّم في خدمة مقارنة الأسعار (CSS)

لإنشاء "عرض مخطط زمني" لمستوى التقدّم، استخدِم الدالة "view()". الوسيطات المقبولة هي <axis> و<view-timeline-inset>.

  • يتطابق <axis> مع المخطط الزمني لتقدم التمرير ويحدد المحور الذي يجب تتبعه. القيمة التلقائية هي block.
  • باستخدام <view-timeline-inset>، يمكنك تحديد إزاحة (موجبة أو سالبة) لضبط الحدود عندما يكون العنصر مرئيًا أو لا. يجب أن تكون القيمة نسبة مئوية أو auto، وتكون auto هي القيمة التلقائية.

على سبيل المثال، لربط صورة متحركة بعنصر يتقاطع مع شريط التمرير على محور القطعة، استخدِم view(block). على غرار scroll()، يجب ضبط هذه القيمة كقيمة للسمة animation-timeline، ولا تنسَ ضبط animation-duration على auto.

باستخدام الرمز التالي، سيتلاشى كل img عند عبوره إطار العرض أثناء التمرير.

@keyframes reveal {
  from { opacity: 0; }
  to { opacity: 1; }
}

img {
  animation: reveal linear;
  animation-timeline: view();
}

Intermezzo: عرض نطاقات المخطط الزمني

بشكل تلقائي، يتم إرفاق الصورة المتحركة المرتبطة بـ "عرض المخطط الزمني" بنطاق المخطط الزمني بالكامل. يبدأ هذا من اللحظة التي يوشك فيها الشخص على الدخول إلى شريط التمرير وينتهي عندما يترك الشخص منفذ التمرير بالكامل.

من الممكن أيضًا ربطه بجزء معيّن من "عرض المخطط الزمني" من خلال تحديد النطاق الذي يجب أن يتم إرفاقه به. ولا يمكن أن يحدث ذلك، على سبيل المثال، إلا عندما يدخل الموضوع إلى شريط التمرير. في التصور التالي، يبدأ التقدم في العد من 0٪ عندما يدخل الموضوع في حاوية التمرير ولكنه يصل بالفعل إلى 100٪ من لحظة تقاطعه تمامًا.

تم ضبط مخطط زمني لعرض الفيديو على تتبُّع النطاق الزمني للموضوع. ولا يتم تشغيل الصورة المتحركة إلا عندما يدخل الشخص إلى شريط التمرير.

في ما يلي نطاقات "عرض المخطط الزمني" المحتملة التي يمكنك استهدافها:

  • cover: يمثل هذا الخيار النطاق الكامل للمخطط الزمني لتقدم المشاهدة.
  • entry: يمثل النطاق الذي يدخل خلاله المربع الأساسي نطاق مستوى رؤية تقدم العرض.
  • exit: يمثل النطاق الذي يخرج خلاله المربع الأساسي من نطاق مستوى رؤية تقدم العرض.
  • entry-crossing: يمثل النطاق الذي يتخطى فيه المربع الرئيسي حافة حدود النهاية.
  • exit-crossing: يمثل النطاق الذي يتخطى فيه المربع الرئيسي حافة حد البداية.
  • contain: يمثل النطاق الذي يتم خلاله تضمين المربع الرئيسي بالكامل أو تغطيته بالكامل نطاق مستوى رؤية تقدم العرض ضمن شريط التمرير. ويعتمد ذلك على ما إذا كان العنصر أطول أو أقصر من شريط التمرير.

لتحديد نطاق، يجب تعيين قيمة بداية نطاق ونهاية نطاق. يتكون كل منها من اسم النطاق (انظر القائمة أعلاه) وإزاحة نطاق لتحديد الموضع ضمن اسم النطاق هذا. ويتراوح عادةً النطاق بين 0% و100%، ولكن يمكنك أيضًا تحديد طول ثابت، مثل 20em.

على سبيل المثال، إذا أردت تشغيل رسم متحرك من لحظة دخول الموضوع، اختَر entry 0% كبداية النطاق. ولإكماله بحلول الوقت الذي أدخل فيه الموضوع، اختَر entry 100% كقيمة لنهاية النطاق.

في CSS، يمكنك ضبط هذا الإعداد باستخدام السمة animation-range. مثال:

animation-range: entry 0% entry 100%;

في JavaScript، استخدِم السمتَين rangeStart وrangeEnd.

$el.animate(
  keyframes,
  {
    timeline: tl,
    rangeStart: 'entry 0%',
    rangeEnd: 'entry 100%',
  }
);

استخدم الأداة المضمنة أدناه لمعرفة ما يمثله كل اسم نطاق وكيف تؤثر النسب المئوية على موضعي البداية والنهاية. جرِّب ضبط قيمة البداية للنطاق على entry 0% ونهاية النطاق على cover 50%، ثم اسحب شريط التمرير لرؤية نتيجة الحركة.

أداة عرض نطاقات المخطط الزمني، متوفّرة على https://goo.gle/view-timeline-range-tool

مشاهدة تسجيل

كما قد تلاحظ أثناء تجربة أدوات "عرض نطاقات المخطط الزمني"، يمكن استهداف بعض النطاقات من خلال تركيبتين مختلفتين لاسم النطاق + إزاحة النطاق. على سبيل المثال، تستهدف entry 0% وentry-crossing 0% وcover 0% المنطقة نفسها.

عندما يستهدف كل من بداية النطاق ونهاية النطاق اسم النطاق نفسه ويمتد النطاق بالكامل من 0% إلى 100%، يمكنك اختصار القيمة لتتضمن اسم النطاق فقط. على سبيل المثال، يمكن إعادة كتابة animation-range: entry 0% entry 100%; إلى animation-range: entry الأقصر بكثير.

عرض توضيحي: عرض صورة

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

العرض التوضيحي: عرض الصور

✨ جربها بنفسك

يتم تحقيق تأثير التوسيع باستخدام مسار مقطع متحرك. CSS المستخدمة لهذا التأثير هي كما يلي:

@keyframes reveal {
  from { opacity: 0; clip-path: inset(0% 60% 0% 50%); }
  to { opacity: 1; clip-path: inset(0% 0% 0% 0%); }
}

.revealing-image {
  animation: auto linear reveal both;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

جارٍ إنشاء "عرض المخطط الزمني لمستوى التقدّم" في خدمة مقارنة الأسعار (CSS).

على غرار الطريقة التي تحتوي بها "المخططات الزمنية للتمرير" على نُسخ مُسَمّاة، يمكنك أيضًا إنشاء اسم "عرض المخططات الزمنية". بدلاً من السمتَين scroll-timeline-*، يمكنك استخدام خيارات تستخدم البادئة view-timeline-، وهي view-timeline-name وview-timeline-axis.

ينطبق نفس نوع القيم، وتنطبق القواعد نفسها للبحث عن مخطط زمني محدَّد.

عرض توضيحي: الكشف عن الصورة، تمت إعادة النظر

تؤدي إعادة صياغة الصورة إلى الكشف عن عرض توضيحي من وقت سابق، يبدو التعليمة البرمجية التي تمت مراجعتها على النحو التالي:

.revealing-image {
  view-timeline-name: --revealing-image;
  view-timeline-axis: block;

  animation: auto linear reveal both;
  animation-timeline: --revealing-image;
  animation-range: entry 25% cover 50%;
}

وباستخدام view-timeline-name: revealing-image، سيتم تتبُّع العنصر ضمن أقرب شريط تمرير له. ويتم بعد ذلك استخدام القيمة نفسها كقيمة للسمة animation-timeline. الناتج المرئي هو نفس الشيء تمامًا كما كان من قبل.

✨ جربها بنفسك

إنشاء مخطط زمني لمستوى التقدّم في JavaScript

لإنشاء "عرض مخطط زمني" في JavaScript، يجب إنشاء مثيل جديد لفئة ViewTimeline. المرور في حقيبة عقارية تتضمن subject الذي تريد تتبُّعه وaxis وinset

  • subject: مرجع إلى العنصر الذي تريد تتبُّعه في شريط التمرير الخاص به
  • axis: المحور المطلوب التتبّع على غرار صيغة CSS، القيم المقبولة هي block وinline وx وy.
  • inset: تعديل داخلي (موجب) أو خارجي (سلبي) لإطار التمرير عند تحديد ما إذا كان المربّع معروضًا.
const tl = new ViewTimeline({
  subject: document.getElementById('subject'),
});

لإرفاقها بإحدى الصور المتحركة على الويب، مرِّرها كسمة timeline واحذف أي duration في حال توفّر أي منها. يمكنك اختياريًا تمرير معلومات النطاق باستخدام السمتَين rangeStart وrangeEnd.

$el.animate({
  opacity: [0, 1],
}, {
  timeline: tl,
  rangeStart: 'entry 25%',
  rangeEnd: 'cover 50%',
});

✨ جربها بنفسك

مزايا إضافية يمكن تجربتها

الإرفاق بالعديد من نطاقات "عرض المخطط الزمني" باستخدام مجموعة واحدة من الإطارات الرئيسية

لنلقِ نظرة على هذا العرض التوضيحي لقائمة جهات الاتصال حيث تكون إدخالات القائمة متحركة. عندما يدخل إدخال قائمة إلى منفذ التمرير من الأسفل، ينزلق+يتلاشى للداخل، وعندما يخرج من منفذ التمرير في الأعلى، ينزلق+يتلاشى.

العرض التوضيحي: قائمة جهات الاتصال

✨ جربها لنفسك

بالنسبة لهذا العرض التوضيحي، يتم تزيين كل عنصر بعرض مخطط زمني واحد يتعقب العنصر أثناء عبوره لمنفذ التمرير الخاص به، إلا أنه يتم إرفاق رسمين متحركين قائمين على التمرير. يتم إرفاق الحركة animate-in بنطاق entry من المخطط الزمني، والحركة animate-out إلى نطاق exit من المخطط الزمني.

@keyframes animate-in {
  0% { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-100%); }
}

#list-view li {
  animation: animate-in linear forwards,
             animate-out linear forwards;
  animation-timeline: view();
  animation-range: entry, exit;
}

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

@keyframes animate-in-and-out {
  entry 0%  {
    opacity: 0; transform: translateY(100%);
  }
  entry 100%  {
    opacity: 1; transform: translateY(0);
  }
  exit 0% {
    opacity: 1; transform: translateY(0);
  }
  exit 100% {
    opacity: 0; transform: translateY(-100%);
  }
}

#list-view li {
  animation: linear animate-in-and-out;
  animation-timeline: view();
}

ولا تحتاج إلى تحديد animation-range لأنّ الإطارات الرئيسية تحتوي على معلومات النطاق. والنتيجة هي نفسها التي كانت عليه من قبل.

✨ جربها لنفسك

الإرفاق بالمخطط الزمني للتمرير الذي لا ينتمي إلى كيان أصل

تقتصر آلية البحث في "التمرير الزمني" الذي يحمل الاسم و"عرض المخططات الزمنية" على تمرير العناصر الأساسية فقط. ومع ذلك، في كثير من الأحيان، لا يكون العنصر الذي يحتاج إلى رسم متحرك عنصرًا فرعيًا لشريط التمرير يجب تتبعه.

لتنفيذ هذا الإجراء، يتم استخدام السمة timeline-scope. يمكنك استخدام هذه السمة للإشارة إلى مخطط زمني بهذا الاسم بدون إنشائه. هذا يعطي الجدول الزمني بهذا الاسم نطاقًا أوسع. من الناحية العملية، يمكنك استخدام السمة timeline-scope في عنصر رئيسي مشترَك لكي يتم إرفاق المخطط الزمني لشريط التمرير الفرعي فيه.

على سبيل المثال:

.parent {
  timeline-scope: --tl;
}
.parent .scroller {
  scroll-timeline: --tl;
}
.parent .scroller ~ .subject {
  animation: animate linear;
  animation-timeline: --tl;
}

في هذا المقتطف:

  • يعرّف العنصر .parent عن مخطط زمني باسم --tl. ويمكن لأي عنصر ثانوي العثور عليها واستخدامها كقيمة للسمة animation-timeline.
  • يحدد العنصر .scroller بالفعل مخططًا زمنيًا للتمرير باسم --tl. وستظهر تلقائيًا العناصر الفرعية منها فقط، ولكن بما أنّ السمة .parent قد تم ضبطها كـ scroll-timeline-root، سيتم إرفاقها بها.
  • يستخدم العنصر .subject المخطط الزمني --tl. يسير على شجرة أصلها ويجد --tl في .parent. عندما يشير --tl على .parent إلى --tl من .scroller، سيتتبّع .subject بشكل أساسي "المخطط الزمني لمستوى تقدُّم الانتقال" في .scroller.

بعبارة أخرى، يمكنك استخدام timeline-root لنقل مخطط زمني إلى أحد السلف (أي الرافع)، حتى يتمكن جميع عناصر الأصل من الوصول إليه.

يمكن استخدام السمة timeline-scope مع كل من "المخطط الزمني" و"عرض المخططات الزمنية".

المزيد من العروض التوضيحية والموارد

تشمل هذه المقالة جميع العروض التوضيحية التي تتناولها على موقع scroll-id-animations.style المصغّر. يتضمن الموقع العديد من العروض التوضيحية لإبراز ما هو ممكن مع الرسوم المتحركة القائمة على التمرير.

أحد العروض التوضيحية الإضافية هي قائمة أغلفة الألبومات. يمكن تدوير كل غلاف ثلاثي الأبعاد لتسليط الضوء عليه في الوسط.

العرض التوضيحي: مسار الغلاف

✨ جربها لنفسك

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

العرض التوضيحي: تجميع البطاقات.

✨ جربها لنفسك

ويظهر أيضًا المحتوى الذي تم ذكره في السابق في هذه المشاركة على scroll-based-animations.style، وتتضمّن مجموعة من الأدوات، مثل العرض المرئي لمستوى تقدُّم مدى التقدُّم في المخطط الزمني.

ويمكنك أيضًا الاطّلاع على الصور المتحركة المستندة إلى التمرير في مقالة الميزات الجديدة في Web Animations في مؤتمر Google I/O لعام 2023.