1. قبل از شروع
انیمیشنهای اسکرولمدار به شما این امکان را میدهند که پخش یک انیمیشن را بر اساس موقعیت اسکرول ظرف اسکرول کنترل کنید. این به این معنی است که با اسکرول کردن به سمت بالا یا پایین، انیمیشن به جلو یا عقب می رود. علاوه بر این، با انیمیشنهای پیمایشی، میتوانید انیمیشن را بر اساس موقعیت یک عنصر در ظرف اسکرول آن کنترل کنید. این به شما امکان میدهد جلوههای جالبی مانند تصویر پسزمینه اختلاف منظر، نوارهای پیشرفت اسکرول و تصاویری ایجاد کنید که در هنگام مشاهده، خود را نشان میدهند.
جدید در کروم 115 پشتیبانی از مجموعهای از کلاسهای جاوا اسکریپت و ویژگیهای CSS است که به شما امکان میدهد به راحتی انیمیشنهای پیمایش محور را ایجاد کنید. این APIهای جدید در ارتباط با Web Animations و CSS Animations APIهای موجود کار می کنند.
این کد لبه به شما یاد می دهد که چگونه با استفاده از CSS انیمیشن های اسکرول را ایجاد کنید. با تکمیل این کد لبه، با بسیاری از ویژگیهای جدید CSS که توسط این ویژگی هیجانانگیز معرفی شدهاند، آشنا میشوید، مانند scroll-timeline
، view-timeline
، animation-timeline
و animation-range
.
چیزی که یاد خواهید گرفت
- نحوه ایجاد افکت پسزمینه اختلاف منظر با Scroll Timeline در CSS.
- نحوه ایجاد نوار پیشرفت با Scroll Timeline در CSS.
- نحوه ایجاد افکت آشکارسازی تصویر با View Timeline در CSS.
- نحوه هدفگیری انواع مختلف محدودههای View Timeline در CSS.
آنچه شما نیاز دارید
یکی از ترکیب دستگاه های زیر:
- نسخه اخیر Chrome (115 یا بالاتر) در ChromeOS، macOS، یا Windows با پرچم «ویژگیهای پلتفرم وب آزمایشی» روی فعال تنظیم شده است.
- درک اولیه HTML
- درک اساسی از CSS، به ویژه انیمیشن ها در CSS
2. راه اندازی شوید
هر آنچه برای این پروژه نیاز دارید در مخزن GitHub موجود است. برای شروع، کد را شبیه سازی کنید و آن را در محیط برنامه نویس مورد علاقه خود باز کنید.
- یک برگه مرورگر جدید باز کنید و به https://github.com/googlechromelabs/io23-scroll-driven-animations-codelab بروید.
- مخزن را شبیه سازی کنید.
- کد را در IDE دلخواه خود باز کنید.
-
npm install
برای نصب وابستگی ها اجرا کنید. -
npm start
اجرا کنید و به http://localhost:3000/ مراجعه کنید. - از طرف دیگر، اگر npm را نصب نکردهاید، فایل
src/index.html
را در کروم باز کنید.
3. در مورد جدول زمانی انیمیشن بیاموزید
به طور پیش فرض، یک انیمیشن متصل به یک عنصر در خط زمانی سند اجرا می شود. این بدان معنی است که وقتی صفحه بارگذاری می شود، انیمیشن با گذشت زمان به جلو حرکت می کند. این جدول زمانی پیشفرض انیمیشن است و تاکنون تنها خط زمانی انیمیشنی بود که به آن دسترسی داشتید.
با انیمیشن های پیمایشی، به دو نوع جدید از جدول زمانی دسترسی پیدا می کنید:
- جدول زمانی پیشرفت را پیمایش کنید
- مشاهده جدول زمانی پیشرفت
در CSS، این خطوط زمانی را می توان با استفاده از ویژگی animation-timeline
به یک انیمیشن متصل کرد. به معنای این خطوط زمانی جدید و تفاوت آنها با یکدیگر نگاه کنید.
جدول زمانی پیشرفت را پیمایش کنید
جدول زمانی پیشرفت پیمایش یک جدول زمانی انیمیشن است که به پیشرفت در موقعیت اسکرول محفظه اسکرول - همچنین به نام اسکرولپورت یا اسکرولر - در امتداد یک محور خاص مرتبط است. این یک موقعیت در محدوده پیمایش را به درصد پیشرفت در طول یک جدول زمانی تبدیل می کند.
موقعیت اسکرول شروع نشان دهنده 0٪ پیشرفت و موقعیت اسکرول پایانی نشان دهنده 100٪ پیشرفت است. در تجسم زیر، توجه داشته باشید که با اسکرول کردن به پایین، پیشرفت از 0٪ تا 100٪ افزایش می یابد.
مشاهده جدول زمانی پیشرفت
این نوع جدول زمانی به پیشرفت نسبی یک عنصر خاص در یک ظرف اسکرول مرتبط است. درست مانند جدول زمانی پیشرفت اسکرول، افست اسکرول پیمایش ردیابی می شود. برخلاف جدول زمانی پیشرفت پیمایش، موقعیت نسبی سوژه در آن پیشگرد است که پیشرفت را تعیین میکند. این قابل مقایسه با IntersectionObserver
است که میزان قابل مشاهده بودن یک عنصر در اسکرول را ردیابی می کند. اگر عنصر در اسکرول قابل مشاهده نباشد، متقاطع نیست. اگر در داخل اسکرول قابل مشاهده باشد – حتی برای کوچکترین قسمت – متقاطع است.
جدول زمانی نمایش پیشرفت از لحظه ای شروع می شود که سوژه شروع به تقاطع با پیمایش می کند و زمانی پایان می یابد که موضوع از تقاطع آن با پیمایش متوقف شود. در تصویرسازی زیر، توجه داشته باشید که زمانی که سوژه وارد محفظه اسکرول میشود، پیشرفت از 0 درصد شروع به شمارش میکند و تا زمانی که از ظرف اسکرول خارج میشود به 100 درصد میرسد.
بهطور پیشفرض، یک انیمیشن مرتبط با جدول زمانی View Progress به کل محدوده آن متصل میشود. این از لحظه ای که سوژه وارد اسکرولپورت می شود شروع می شود و با خروج سوژه از اسکرولپورت به پایان می رسد.
همچنین می توان با تعیین محدوده ای که باید به آن متصل شود، آن را به بخش خاصی از جدول زمانی نمایش پیشرفت پیوند داد. این می تواند، برای مثال، تنها زمانی باشد که سوژه در حال ورود به اسکرولر باشد. در تصویرسازی زیر، زمانی که سوژه وارد محفظه اسکرول میشود، پیشرفت از 0 درصد شروع به شمارش میکند، اما از لحظهای که کاملاً قطع میشود به 100 درصد میرسد.
محدودههای ممکن View Timeline که میتوانید هدف قرار دهید عبارتند از: cover
، contain
، entry
، exit
، entry-crossing
، و exit-crossing
. این محدودهها بعداً در این آزمایشگاه کد توضیح داده شدهاند، اما اگر نمیتوانید منتظر بمانید تا بدانید، از ابزار واقع در https://goo.gle/view-timeline-range-tool استفاده کنید تا ببینید هر محدوده چه چیزی را نشان میدهد.
4. یک افکت پس زمینه اختلاف منظر ایجاد کنید
اولین افکتی که به صفحه اضافه می شود افکت پس زمینه اختلاف منظر روی تصویر پس زمینه اصلی است. همانطور که صفحه را به پایین اسکرول می کنید، تصویر پس زمینه باید حرکت کند، هرچند با سرعت متفاوت. برای این کار، به یک جدول زمانی پیشرفت پیمایش تکیه می کنید.
برای اجرای این امر دو مرحله وجود دارد:
- انیمیشنی ایجاد کنید که موقعیت تصویر پس زمینه را جابجا کند.
- انیمیشن را به پیشرفت پیمایش سند پیوند دهید.
انیمیشن را ایجاد کنید
- برای ایجاد انیمیشن، از مجموعهای از فریمهای کلیدی معمولی استفاده کنید. در آن، موقعیت پس زمینه را از 0% به صورت عمودی به 100% منتقل کنید:
src/styles.css
@keyframes move-background {
from {
background-position: 50% 0%;
}
to {
background-position: 50% 100%;
}
}
- اکنون این فریم های کلیدی را به عنصر بدنه وصل کنید:
src/styles.css
body {
animation: 1s linear move-background;
}
با این کد انیمیشن move-background
به عنصر بدنه اضافه می شود. ویژگی animation-duration
آن روی یک ثانیه تنظیم شده است و از یک کاهش linear
استفاده می کند.
با استفاده از جدول زمانی پیشرفت اسکرول ناشناس، انیمیشن را به پیشرفت پیمایش ریشه پیوند دهید
ساده ترین راه برای ایجاد جدول زمانی Scroll Progress استفاده از تابع scroll()
است. این یک جدول زمانی پیشرفت پیمایش ناشناس ایجاد می کند که می توانید آن را به عنوان مقدار ویژگی animation-timeline
تنظیم کنید.
تابع scroll()
یک آرگومان <scroller>
و <axis>
را می پذیرد.
مقادیر پذیرفته شده برای آرگومان <scroller>
به شرح زیر است:
-
nearest
. از نزدیکترین محفظه اسکرول اجداد (پیشفرض) استفاده میکند. -
root
. از نمای سند به عنوان محفظه اسکرول استفاده می کند. -
self
. از خود عنصر به عنوان محفظه اسکرول استفاده می کند.
مقادیر پذیرفته شده برای آرگومان <axis>
به شرح زیر است:
-
block
. از اندازه گیری پیشرفت در امتداد محور بلوک ظرف اسکرول (پیش فرض) استفاده می کند. -
inline
. از اندازه گیری پیشرفت در امتداد محور درونی ظرف اسکرول استفاده می کند. -
y
از اندازه گیری پیشرفت در امتداد محور y ظرف اسکرول استفاده می کند. -
x
از اندازه گیری پیشرفت در امتداد محور x ظرف اسکرول استفاده می کند.
برای پیوند دادن انیمیشن به پیمایش ریشه در محور بلوک، مقادیری که باید به scroll()
منتقل شوند root
و block
هستند. با هم، مقدار scroll(root block)
است.
-
scroll(root block)
را به عنوان مقدار خاصیتanimation-timeline
روی بدنه تنظیم کنید. - علاوه بر این، از آنجایی که
animation-duration
بیان شده در ثانیه معنی ندارد، مدت زمان را رویauto
تنظیم کنید. اگرanimation-duration
مشخص نکنید، به طور پیشفرض رویauto
خواهد بود.
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(root block);
}
از آنجایی که پیمایش ریشه نزدیکترین پیمایش والد عنصر بدنه است، میتوانید از مقدار nearest
نیز استفاده کنید:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll(nearest block);
}
از آنجا که nearest
و block
مقادیر پیشفرض هستند، حتی میتوانید آنها را حذف کنید. در این صورت، کد را می توان به این شکل ساده کرد:
src/styles.css
body {
animation: linear move-background;
animation-duration: auto;
animation-timeline: scroll();
}
تغییرات خود را تأیید کنید
اگر همه چیز خوب پیش رفت، اکنون باید این را داشته باشید:
در غیر این صورت، به بخش solution-step-1
کد مراجعه کنید.
5. یک نوار پیشرفت برای گالری تصاویر ایجاد کنید
در صفحه یک چرخ فلک افقی وجود دارد که به نوار پیشرفت نیاز دارد تا نشان دهد در حال حاضر کدام عکس را مشاهده می کنید.
نشانه گذاری برای چرخ فلک به صورت زیر است:
src/index.html
<div class="gallery">
<div class="gallery__scrollcontainer" style="--num-images: 3;">
<div class="gallery__progress"></div>
<div class="gallery__entry">
...
</div>
<div class="gallery__entry">
...
</div>
<div class="gallery__entry">
...
</div>
</div>
</div>
فریم های کلیدی برای نوار پیشرفت در حال حاضر در محل قرار دارند و به شکل زیر هستند:
src/styles.css
@keyframes adjust-progress {
from {
transform: scaleX(calc(1 / var(--num-images)));
}
to {
transform: scaleX(1);
}
}
این انیمیشن باید به ضمیمه شود. عنصر gallery__progress
با جدول زمانی پیشرفت پیمایش. همانطور که در مرحله قبل نشان داده شد، می توانید با ایجاد یک جدول زمانی پیشرفت اسکرول ناشناس با تابع scroll()
به این مهم دست یابید:
src/styles.css
.gallery__progress {
animation: linear adjust-progress;
animation-duration: auto;
animation-timeline: scroll(nearest inline);
}
در حالی که این قطعه کد ممکن است به نظر کار میآید، اما به دلیل نحوه جستجوی خودکار ظرف اسکرول با استفاده از nearest
کار نیست. هنگام جستجوی نزدیکترین اسکرول، عنصر فقط عناصری را در نظر می گیرد که می توانند بر موقعیت آن تأثیر بگذارند. از آنجایی که .gallery__progress
کاملاً در موقعیت قرار دارد، اولین عنصر والد که موقعیت آن را تعیین می کند، عنصر .gallery
است زیرا position: relative
اعمال شده دارد. این بدان معنی است که عنصر .gallery__scrollcontainer
– که پیمایشی است که باید مورد هدف قرار گیرد – در طول این جستجوی خودکار اصلا در نظر گرفته نمی شود.
برای حل این مشکل، در عنصر .gallery__scrollcontainer
یک Scroll Progress Timeline با نام Scroll Progress ایجاد کنید و .gallery__progress
را با استفاده از آن نام به آن پیوند دهید.
یک جدول زمانی پیشرفت پیمایش با نام ایجاد و پیوند دهید
برای ایجاد یک جدول زمانی پیشرفت اسکرول با نام روی یک عنصر، ویژگی scroll-timeline-name
CSS را در ظرف اسکرول روی مقدار دلخواه خود تنظیم کنید. مقدار باید با --
شروع شود.
از آنجایی که گالری به صورت افقی اسکرول می شود، باید ویژگی scroll-timeline-axis
نیز تنظیم کنید. مقادیر مجاز همان آرگومان <axis>
scroll()
است.
در نهایت، برای پیوند دادن انیمیشن به جدول زمانی Scroll Progress، ویژگی animation-timeline
را روی عنصری که باید متحرک شود، با همان مقدار شناسه استفاده شده برای scroll-timeline-name
تنظیم کنید.
- فایل
styles.css
را با موارد زیر تغییر دهید:
src/styles.css
.gallery__scrollcontainer {
/* Create the gallery-is-scrolling timeline */
scroll-timeline-name: --gallery-is-scrolling;
scroll-timeline-axis: inline;
}
.gallery__progress {
animation: linear adjust-progress;
animation-duration: auto;
/* Set gallery-is-scrolling as the timeline */
animation-timeline: --gallery-is-scrolling;
}
تغییرات خود را تأیید کنید
اگر همه چیز خوب پیش رفت، اکنون باید این را داشته باشید:
در غیر این صورت، به بخش solution-step-2
کد مراجعه کنید.
6. تصاویر گالری را هنگام ورود و خروج از اسکرولپورت متحرک کنید
محو شدن در تصاویر گالری
یک جدول زمانی نمایش پیشرفت ناشناس تنظیم کنید
یک جلوه خوب برای افزودن این است که در هنگام مشاهده تصاویر در گالری محو شوند. برای این کار، می توانید از جدول زمانی نمایش پیشرفت استفاده کنید.
برای ایجاد جدول زمانی View Progress، می توانید از تابع view()
استفاده کنید. آرگومان های پذیرفته شده آن <axis>
و <view-timeline-inset>
هستند.
-
<axis>
مانند جدول زمانی پیشرفت پیمایش است و مشخص می کند که کدام محور را ردیابی کند. - با
<view-timeline-inset>
، میتوانید یک افست (مثبت یا منفی) را برای تنظیم کرانها در زمانی که عنصری در نظر گرفته میشود در نظر گرفته میشود مشخص کنید.
- فریم های کلیدی از قبل در جای خود قرار دارند، بنابراین فقط باید آنها را وصل کنید. برای انجام این کار، روی هر عنصر
.gallery__entry
یک جدول زمانی مشاهده پیشرفت ایجاد کنید.
src/styles.css
@keyframes animate-in {
from {
opacity: 0;
clip-path: inset(50% 0% 50% 0%);
}
to {
opacity: 1;
clip-path: inset(0% 0% 0% 0%);
}
}
.gallery__entry {
animation: linear animate-in;
animation-duration: auto;
animation-timeline: view(inline);
}
محدوده زمانی نمایش پیشرفت را محدود کنید
اگر CSS را ذخیره کنید و صفحه را بارگذاری کنید، می بینید که عناصر محو می شوند، اما چیزی به نظر می رسد. زمانی که کاملاً خارج از دید هستند با کدورت 0
شروع میشوند و زمانی که کاملاً خارج شدهاند به کدورت 1
ختم میشوند.
این به این دلیل است که محدوده پیشفرض برای یک جدول زمانی نمایش پیشرفت، محدوده کامل است. این به عنوان محدوده cover
شناخته می شود.
- برای هدف قرار دادن فقط محدوده
entry
موضوع، از ویژگی CSSanimation-range
استفاده کنید تا زمان اجرای انیمیشن را محدود کنید.
src/styles.css
.gallery__entry {
animation: linear fade-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry 0% entry 100%;
}
انیمیشن اکنون از entry 0%
(سوژه در شرف ورود به اسکرولر) تا entry 100%
اجرا می شود (موضوع به طور کامل وارد پیمایش شده است).
محدودههای نمایش زمانی ممکن به شرح زیر است:
-
cover
. محدوده کامل جدول زمانی پیشرفت نمایش را نشان می دهد. -
entry
. نشان دهنده محدوده ای است که در طی آن کادر اصلی وارد محدوده دید پیشرفت نما می شود. -
exit
. محدوده ای را نشان می دهد که در طی آن کادر اصلی از محدوده دید پیشرفت نما خارج می شود. -
entry-crossing
. محدوده ای را نشان می دهد که در طی آن جعبه اصلی از لبه مرزی انتهایی عبور می کند. -
exit-crossing
. نشان دهنده محدوده ای است که در طی آن جعبه اصلی از لبه مرز شروع عبور می کند. -
contain
. محدودهای را نشان میدهد که در طی آن کادر اصلی یا بهطور کامل توسط محدوده دید پیشرفت نمای آن در اسکرولپورت قرار میگیرد یا کاملاً پوشش میدهد. این بستگی به این دارد که آیا سوژه بلندتر یا کوتاهتر از اسکرولر باشد.
از ابزار واقع در https://goo.gle/view-timeline-range-tool استفاده کنید تا ببینید هر محدوده نشان دهنده چیست و چگونه درصدها بر موقعیت های شروع و پایان تأثیر می گذارد.
- از آنجا که محدوده شروع و پایان در اینجا یکسان است و از افست های پیش فرض استفاده می شود،
animation-range
به یک نام محدوده انیمیشن ساده کنید:
src/styles.css
.gallery__entry {
animation: linear animate-in;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry;
}
محو کردن تصاویر گالری
- برای محو کردن تصاویر در هنگام خروج از اسکرول، میتوانید مانند انیمیشن انیمهای انجام دهید، اما محدوده متفاوتی را هدف قرار دهید.
src/styles.css
@keyframes animate-out {
from {
opacity: 1;
clip-path: inset(0% 0% 0% 0%);
}
to {
opacity: 0;
clip-path: inset(50% 0% 50% 0%);
}
}
.gallery__entry {
animation: linear animate-in, linear animate-out;
animation-duration: auto;
animation-timeline: view(inline);
animation-range: entry, exit;
}
فریمهای کلیدی animate-in
محدوده entry
و فریمهای کلیدی animate-out
در محدوده exit
اعمال خواهند شد.
تغییرات خود را تأیید کنید
اگر همه چیز خوب پیش رفت، اکنون باید این را داشته باشید:
در غیر این صورت، بخش solution-step-3
کد را بررسی کنید.
7. تصاویر گالری را هنگام ورود و خروج از اسکرولپورت با استفاده از یک مجموعه از فریم های کلیدی متحرک کنید.
مورد برای یک مجموعه از فریم های کلیدی
به جای اتصال دو انیمیشن به محدوده های مختلف، می توان یک مجموعه از فریم های کلیدی ایجاد کرد که از قبل حاوی اطلاعات محدوده باشد.
شکل فریم های کلیدی به این صورت است:
@keyframes keyframes-name {
range-name range-offset {
...
}
range-name range-offset {
...
}
}
- فریم های کلیدی fade-in و fade-out را به این صورت ترکیب کنید:
src/styles.css
@keyframes animate-in-and-out {
entry 0% {
opacity: 0;
clip-path: inset(50% 0% 50% 0%);
}
entry 90% {
opacity: 1;
clip-path: inset(0% 0% 0% 0%);
}
exit 10% {
opacity: 1;
clip-path: inset(0% 0% 0% 0%);
}
exit 100% {
opacity: 0;
clip-path: inset(50% 0% 50% 0%);
}
}
- وقتی اطلاعات محدوده در فریمهای کلیدی وجود دارد، دیگر نیازی نیست که
animation-range
جداگانه مشخص کنید. فریم های کلیدی را به عنوان ویژگیanimation
ضمیمه کنید.
src/styles.css
.gallery__entry {
animation: linear animate-in-and-out both;
animation-duration: auto;
animation-timeline: view(inline);
}
تغییرات خود را تأیید کنید
اگر همه چیز خوب پیش رفت، باید همان نتیجه مرحله قبل را داشته باشید. در غیر این صورت، به بخش solution-step-4
کد مراجعه کنید.
8. تبریک می گویم!
شما این کد را به پایان رساندید و اکنون می دانید که چگونه جدول زمانی پیشرفت اسکرول را ایجاد کنید و خطوط زمانی پیشرفت را در CSS مشاهده کنید!
بیشتر بدانید
منابع: