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

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

الصور المتحركة التي يتم تشغيلها من خلال الانتقال للأعلى أو للأسفل

دعم المتصفح

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

المصدر

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

مؤشر القراءة أعلى المستند، يتم تشغيله من خلال التمرير.

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

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

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

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

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

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

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

ملخّص صغير عن الصور المتحركة على الويب

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

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

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

@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 عند تحميل الصفحة، ويبدأ في التقديم مع تقدم الوقت. هذا هو المخطط الزمني التلقائي للحركة، وكان حتى الآن المخطط الزمني الوحيد للحركة الذي يمكنك الوصول إليه.

تحدِّد مواصفات الرسوم المتحرّكة المستندة إلى الانتقال للأعلى أو للأسفل نوعَين جديدَين من المخططات الزمنية يمكنك استخدامهما:

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

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

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

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

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

✨ جرِّب هذه الميزة بنفسك

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

عرض المخطط الزمني للتقدّم

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

يشبه ذلك إلى حدٍ ما طريقة عمل 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، مع تتبُّع اتجاه الحظر.

إنشاء مخطط زمني مُعنوَن لتقدّم الانتقال في CSS

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

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

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

أداة Visualizer لعرض نطاقات المخطط الزمني، المتوفّرة على الرابط 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-based-animations.style mini-site. يتضمن الموقع العديد من العروض التوضيحية لإبراز ما هو ممكن مع الرسوم المتحركة القائمة على التمرير.

من بين العروض التوضيحية الإضافية هذه القائمة التي تتضمّن أغلفة الألبومات. يتم تدوير كل غلاف بشكل ثلاثي الأبعاد عندما يكون في مركز العرض.

عرض توضيحي: Cover Flow

✨ جرِّبها بنفسك

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

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

✨ جرِّب هذه الميزة بنفسك

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

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