تعرَّف على طريقة استخدام ميزة "التمرير الزمني" و"عرض المخططات الزمنية" لإنشاء صور متحركة تستند إلى الانتقال بشكل مرئي.
الصور المتحركة المستندة إلى التمرير
الرسوم المتحركة التي تعتمد على التمرير هي نمط تجربة مستخدم شائع على الويب. ترتبط الرسوم المتحركة المستندة إلى التمرير بموضع التمرير في حاوية تمرير. هذا يعني أنه أثناء التمرير لأعلى أو لأسفل، تظهر الرسوم المتحركة المرتبطة للأمام أو للخلف في استجابة مباشرة. ومن الأمثلة على ذلك التأثيرات، مثل صور الخلفية المتباينة أو مؤشرات القراءة التي تتحرك أثناء التنقّل.
نوع مشابه من الرسوم المتحركة القائمة على التمرير هو الرسوم المتحركة المرتبطة بموضع العنصر داخل حاوية التمرير الخاصة به. باستخدامها، على سبيل المثال، يمكن أن تتلاشى العناصر عندما تظهر.
والطريقة الكلاسيكية لتنفيذ هذه الأنواع من التأثيرات هي الاستجابة لأحداث التمرير في سلسلة المحادثات الرئيسية، ما يؤدي إلى مشكلتَين رئيسيتَين:
- تنفِّذ المتصفِّحات الحديثة عملية التمرير على عملية منفصلة، وبالتالي تعرض أحداث الانتقال بشكل غير متزامن.
- تخضع الصور المتحركة لسلسلة المحادثات الرئيسية لميزة "إيقاف مؤقت".
وهذا يجعل إنشاء صور متحركة عالية الأداء تعتمد على التمرير ومتزامنة مع التمرير مستحيلاً أو صعبة للغاية.
بدءًا من الإصدار 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٪ أثناء تمرير أشرطة التمرير من أعلى إلى أسفل.
✨ جربها بنفسك
غالبًا ما يتم اختصار "المخطط الزمني لتقدم التمرير" ليصبح ببساطة "تمرير المخطط الزمني".
عرض المخطط الزمني لمستوى التقدُّم
يرتبط هذا النوع من المخطط الزمني بالتقدم النسبي لعنصر معين داخل حاوية تمرير. تمامًا مثل "المخطط الزمني لتقدم التمرير"، يتم تتبُّع إزاحة التمرير في شريط التمرير. على عكس المخطط الزمني لتقدم التمرير، يحدد الموضع النسبي للموضوع داخل شريط التمرير التقدم.
يشبه ذلك إلى حدٍ ما طريقة عمل IntersectionObserver
التي يمكنها تتبُّع مقدار ما يظهر فيه عنصر في شريط التمرير. إذا لم يكن العنصر مرئيًا في شريط التمرير، فهذا يعني أنه غير متقاطع. إذا كان مرئيًا داخل شريط التمرير - حتى بالنسبة لأصغر جزء - فسيكون متقاطعًا.
يبدأ عرض المخطط الزمني لمستوى التقدّم من اللحظة التي يبدأ فيها العنصر بالتقاطع مع شريط التمرير وينتهي عندما يتوقف الموضوع عن تقاطع شريط التمرير. في التصور التالي، يمكنك أن ترى أن التقدم يبدأ في العد من 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%
، ثم اسحب شريط التمرير لرؤية نتيجة الحركة.
مشاهدة تسجيل
كما قد تلاحظ أثناء تجربة أدوات "عرض نطاقات المخطط الزمني"، يمكن استهداف بعض النطاقات من خلال تركيبتين مختلفتين لاسم النطاق + إزاحة النطاق. على سبيل المثال، تستهدف 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.