با انیمیشن های اسکرول محور عناصر را روی اسکرول متحرک کنید

یاد بگیرید که چگونه با Scroll Timelines و View Timelines کار کنید تا انیمیشن‌های اسکرول-محور را به روشی اعلانی ایجاد کنید.

منتشر شده: ۵ مه ۲۰۲۳

انیمیشن‌های اسکرول‌محور

Browser Support

  • کروم: ۱۱۵.
  • لبه: ۱۱۵.
  • فایرفاکس: پشت یک پرچم.
  • سافاری: ۲۶.

Source

انیمیشن‌های اسکرول‌محور یک الگوی رایج تجربه کاربری در وب هستند. یک انیمیشن اسکرول‌محور به موقعیت اسکرول یک کانتینر اسکرول لینک می‌شود. این بدان معناست که وقتی شما به بالا یا پایین اسکرول می‌کنید، انیمیشن لینک‌شده در پاسخ مستقیم به جلو یا عقب می‌رود. نمونه‌هایی از این موارد، جلوه‌هایی مانند تصاویر پس‌زمینه پارالاکس یا نشانگرهای خواندن هستند که با اسکرول شما حرکت می‌کنند.

یک نشانگر خواندن بالای سند، که با اسکرول کردن هدایت می‌شود.

نوع مشابهی از انیمیشن اسکرول-محور، انیمیشنی است که به موقعیت یک عنصر در محفظه اسکرول آن لینک می‌شود. برای مثال، با آن، عناصر می‌توانند هنگام نمایش، محو شوند.

تصاویر این صفحه با شروع نمایش، کم‌رنگ می‌شوند.

روش کلاسیک برای دستیابی به این نوع اثرات، پاسخ دادن به رویدادهای اسکرول در نخ اصلی است که منجر به دو مشکل اصلی می‌شود:

  • مرورگرهای مدرن اسکرول کردن را در یک فرآیند جداگانه انجام می‌دهند و بنابراین رویدادهای اسکرول را به صورت غیرهمزمان ارائه می‌دهند.
  • انیمیشن‌های نخ اصلی در معرض jank هستند.

این امر ایجاد انیمیشن‌های اسکرول-محور کارآمد که با اسکرول کردن هماهنگ باشند را غیرممکن یا بسیار دشوار می‌کند.

از نسخه ۱۱۵ کروم، مجموعه‌ای جدید از APIها و مفاهیم وجود دارد که می‌توانید برای فعال کردن انیمیشن‌های اسکرول-محور اعلانی از آنها استفاده کنید: Scroll Timelines و View Timelines.

این مفاهیم جدید با API انیمیشن‌های وب (WAAPI) و API انیمیشن‌های CSS موجود ادغام می‌شوند و به آنها اجازه می‌دهند مزایایی را که این APIهای موجود به ارمغان می‌آورند، به ارث ببرند. این شامل قابلیت اجرای انیمیشن‌های اسکرول-محور از نخ اصلی می‌شود. بله، درست خواندید: اکنون می‌توانید انیمیشن‌های روان و ابریشمی داشته باشید که توسط اسکرول هدایت می‌شوند و از نخ اصلی، تنها با چند خط کد اضافی، اجرا می‌شوند. چه چیزی دوست داشتنی نیست؟!

انیمیشن‌ها در وب، خلاصه‌ای کوتاه

انیمیشن‌های وب با CSS

برای ایجاد یک انیمیشن در CSS، مجموعه‌ای از فریم‌های کلیدی را با استفاده از @keyframes at-rule تعریف کنید. آن را با استفاده از ویژگی 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;
}

انیمیشن‌های وب با جاوا اسکریپت

در جاوا اسکریپت، می‌توان از API انیمیشن‌های وب برای دستیابی به همین هدف استفاده کرد. می‌توانید این کار را با ایجاد نمونه‌های جدید Animation و KeyFrameEffect یا استفاده از متد بسیار کوتاه‌تر Element animate() انجام دهید.

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

این نتیجه بصری از قطعه کد جاوا اسکریپت بالا با نسخه قبلی CSS یکسان است.

جدول زمانی انیمیشن

به طور پیش‌فرض، یک انیمیشن متصل به یک عنصر در جدول زمانی سند اجرا می‌شود. زمان مبدا آن هنگام بارگذاری صفحه از ۰ شروع می‌شود و با گذشت زمان، به جلو حرکت می‌کند. این جدول زمانی پیش‌فرض انیمیشن است و تاکنون، تنها جدول زمانی انیمیشنی بود که به آن دسترسی داشتید.

مشخصات انیمیشن‌های اسکرول-محور، دو نوع جدید از جدول زمانی را که می‌توانید استفاده کنید، تعریف می‌کند:

  • جدول زمانی پیشرفت اسکرول : یک جدول زمانی که به موقعیت اسکرول یک ظرف اسکرول در امتداد یک محور خاص مرتبط است.
  • نمایش جدول زمانی پیشرفت : یک جدول زمانی که به موقعیت نسبی یک عنصر خاص در ظرف اسکرول آن پیوند دارد.

جدول زمانی پیشرفت پیمایش

یک جدول زمانی پیشرفت اسکرول، یک جدول زمانی انیمیشن است که به پیشرفت در موقعیت اسکرول یک محفظه اسکرول - که به آن اسکرول پورت یا اسکرولر نیز گفته می‌شود - در امتداد یک محور خاص مرتبط است. این جدول زمانی، موقعیت را در یک محدوده اسکرول به درصد پیشرفت تبدیل می‌کند.

موقعیت شروع اسکرول نشان دهنده پیشرفت ۰٪ و موقعیت پایان اسکرول نشان دهنده پیشرفت ۱۰۰٪ است. در تصویرسازی زیر، می‌توانید ببینید که با اسکرول کردن اسکرول از بالا به پایین، پیشرفت از ۰٪ تا ۱۰۰٪ شمارش می‌شود.

تجسم جدول زمانی پیشرفت اسکرول. همانطور که به پایین اسکرول کننده اسکرول می‌کنید، مقدار پیشرفت از ۰٪ تا ۱۰۰٪ به صورت صعودی شمارش می‌شود.

✨ خودتان امتحان کنید

یک جدول زمانی پیشرفت اسکرول اغلب به اختصار «جدول زمانی اسکرول» نامیده می‌شود.

مشاهده جدول زمانی پیشرفت

این نوع جدول زمانی به پیشرفت نسبی یک عنصر خاص در یک ظرف اسکرول مرتبط است. درست مانند یک جدول زمانی پیشرفت اسکرول، جابجایی اسکرول یک اسکرول کننده ردیابی می‌شود. برخلاف یک جدول زمانی پیشرفت اسکرول، موقعیت نسبی یک موضوع در آن اسکرول کننده است که پیشرفت را تعیین می‌کند.

این تا حدودی با نحوه کار IntersectionObserver قابل مقایسه است، که می‌تواند میزان قابل مشاهده بودن یک عنصر در پیمایشگر را ردیابی کند. اگر عنصر در پیمایشگر قابل مشاهده نباشد، متقاطع نیست. اگر در داخل پیمایشگر قابل مشاهده باشد - حتی برای کوچکترین قسمت - متقاطع است.

یک جدول زمانی پیشرفت نمایش از لحظه‌ای که یک شیء شروع به تقاطع با اسکرول می‌کند شروع می‌شود و زمانی که تقاطع شیء با اسکرول متوقف می‌شود، پایان می‌یابد. در تصویرسازی زیر، می‌توانید ببینید که پیشرفت از ۰٪ شروع می‌شود، زمانی که شیء وارد محفظه اسکرول می‌شود و در همان لحظه‌ای که شیء محفظه اسکرول را ترک می‌کند، به ۱۰۰٪ می‌رسد.

تجسم جدول زمانی پیشرفت نمایش. با عبور موضوع (کادر سبز) از اسکرول، پیشرفت از ۰٪ تا ۱۰۰٪ شمارش می‌شود.

✨ خودتان امتحان کنید

یک جدول زمانی مشاهده پیشرفت اغلب به اختصار «مشاهده جدول زمانی» نامیده می‌شود. می‌توان بخش‌های خاصی از یک جدول زمانی مشاهده را بر اساس اندازه موضوع هدف قرار داد، اما بعداً بیشتر در مورد آن صحبت خواهیم کرد.

کار با جدول زمانی پیشرفت اسکرول (Scroll Progress Timelines)

ایجاد یک جدول زمانی پیشرفت پیمایش ناشناس در CSS

ساده‌ترین راه برای ایجاد یک جدول زمانی پیمایش (Scroll Timeline) در CSS استفاده از تابع scroll() است. این تابع یک جدول زمانی پیمایش ناشناس (anonymous Scroll Timeline) ایجاد می‌کند که می‌توانید آن را به عنوان مقدار برای ویژگی جدید 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 : از معیار پیشرفت در امتداد محور y ظرف اسکرول استفاده می‌کند.
  • x : از معیار پیشرفت در امتداد محور x ظرف اسکرول استفاده می‌کند.

برای مثال، برای اتصال یک انیمیشن به اسکرول کننده ریشه در محور بلوک، مقادیری که باید به scroll() ارسال شوند، root و block هستند. در مجموع، مقدار scroll(root block) می‌شود.

نسخه آزمایشی: نشانگر پیشرفت خواندن

این نسخه آزمایشی یک نشانگر پیشرفت خواندن دارد که در بالای صفحه نمایش ثابت شده است. با اسکرول کردن به پایین صفحه، نوار پیشرفت بزرگ می‌شود تا زمانی که با رسیدن به انتهای سند، کل عرض صفحه نمایش را اشغال کند. یک جدول زمانی ناشناس برای پیشرفت اسکرول کردن، برای هدایت انیمیشن استفاده می‌شود.

نسخه آزمایشی: نشانگر پیشرفت خواندن .

✨ خودتان امتحان کنید

نشانگر پیشرفت خواندن با استفاده از position fixed در بالای صفحه قرار می‌گیرد. برای استفاده از انیمیشن‌های ترکیبی، width متحرک نمی‌شود، بلکه عنصر با استفاده از transform روی محور x کوچک می‌شود.

<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

یک روش جایگزین برای تعریف جدول زمانی پیشرفت اسکرول، استفاده از یک جدول زمانی با نام است. این روش کمی طولانی‌تر است، اما وقتی اسکرول والد یا اسکرول ریشه را هدف قرار نمی‌دهید، یا وقتی صفحه از چندین جدول زمانی استفاده می‌کند یا وقتی جستجوی خودکار کار نمی‌کند، می‌تواند مفید باشد. به این ترتیب، می‌توانید یک جدول زمانی پیشرفت اسکرول را با نامی که به آن می‌دهید، شناسایی کنید.

برای ایجاد یک جدول زمانی پیشرفت پیمایش نامگذاری شده روی یک عنصر، ویژگی 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;

این نسخه آزمایشی دارای یک نشانگر مرحله است که بالای هر چرخ فلک تصویر نشان داده می‌شود. وقتی یک چرخ فلک شامل سه تصویر باشد، نوار نشانگر از عرض ۳۳٪ شروع می‌شود تا نشان دهد که شما در حال حاضر به تصویر یکی از سه تصویر نگاه می‌کنید. وقتی آخرین تصویر در حال مشاهده است - که با پیمایش اسکرول تا انتها تعیین می‌شود - نشانگر تمام عرض اسکرول را اشغال می‌کند. یک جدول زمانی پیشرفت پیمایش با نام برای هدایت انیمیشن استفاده می‌شود.

نسخه آزمایشی: نشانگر گام چرخ فلک افقی .

✨ خودتان امتحان کنید

نشانه‌گذاری پایه برای یک گالری به این صورت است:

<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 به طور مطلق درون عنصر wrapper .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 ‎ متحرک می‌شود. این کار با ارجاع به ‎Scroll Progress Timeline --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;
}

ایجاد جدول زمانی پیشرفت اسکرول با جاوا اسکریپت

برای ایجاد یک جدول زمانی پیمایشی (Scroll Timeline) در جاوا اسکریپت، یک نمونه جدید از کلاس ScrollTimeline ایجاد کنید. یک ویژگی (property bag) شامل 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,
});

نسخه آزمایشی: نشانگر پیشرفت مطالعه، بازبینی شده

برای ایجاد مجدد نشانگر پیشرفت خواندن با جاوا اسکریپت، ضمن استفاده از همان نشانه‌گذاری، از کد جاوا اسکریپت زیر استفاده کنید:

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();
}

میان‌پرده: مشاهده محدوده‌های جدول زمانی

به طور پیش‌فرض، یک انیمیشن که به View Timeline متصل است، به کل محدوده‌ی Timeline متصل می‌شود. این از لحظه‌ای که سوژه در شرف ورود به scrollport است شروع می‌شود و زمانی که سوژه به طور کامل scrollport را ترک کرده است، پایان می‌یابد.

همچنین می‌توان با مشخص کردن محدوده‌ای که باید به آن متصل شود، آن را به بخش خاصی از جدول زمانی نمایش (View Timeline) پیوند داد. این می‌تواند، به عنوان مثال، فقط زمانی باشد که سوژه وارد اسکرول می‌شود. در تجسم زیر، پیشرفت از زمانی که سوژه وارد ظرف اسکرول می‌شود، از ۰٪ شروع به شمارش می‌کند، اما از لحظه‌ای که کاملاً متقاطع می‌شود، به ۱۰۰٪ می‌رسد.

یک جدول زمانی نمایش که برای ردیابی محدوده ورود سوژه تنظیم شده است. انیمیشن فقط زمانی اجرا می‌شود که سوژه وارد اسکرول‌پورت می‌شود.

محدوده‌های نمایش جدول زمانی که می‌توانید هدف قرار دهید عبارتند از:

  • cover : نشان‌دهنده‌ی طیف کامل جدول زمانی پیشرفت نمایش است.
  • entry : نشان‌دهنده‌ی بازه زمانی است که کادر اصلی وارد محدوده‌ی پیشرفت نمایش می‌شود.
  • exit : نشان‌دهنده‌ی بازه زمانی است که کادر اصلی از محدوده‌ی دید پیشرفت نما خارج می‌شود.
  • entry-crossing : نشان‌دهنده محدوده‌ای است که در طی آن کادر اصلی از لبه مرزی انتهایی عبور می‌کند.
  • exit-crossing : نشان‌دهنده‌ی بازه زمانی است که کادر اصلی از لبه‌ی مرزی شروع عبور می‌کند.
  • contain : نشان‌دهنده‌ی بازه زمانی است که کادر اصلی یا به‌طور کامل توسط آن احاطه شده یا به‌طور کامل، بازه دید پیشرفت نمای خود را در داخل اسکرول‌پورت پوشش می‌دهد. این بستگی به این دارد که سوژه از اسکرول‌ور بلندتر یا کوتاه‌تر باشد.

برای تعریف یک محدوده، باید یک محدوده شروع و پایان تعیین کنید. هر کدام شامل نام محدوده (به لیست بالا مراجعه کنید) و یک فاصله محدوده برای تعیین موقعیت در آن نام محدوده است. فاصله محدوده معمولاً درصدی از 0% تا 100% است، اما می‌توانید یک طول ثابت مانند 20em نیز تعیین کنید.

برای مثال، اگر می‌خواهید یک انیمیشن از لحظه ورود یک سوژه اجرا شود، entry 0% به عنوان شروع محدوده انتخاب کنید. برای اینکه انیمیشن تا زمان ورود سوژه تمام شود، entry 100% به عنوان مقداری برای پایان محدوده انتخاب کنید.

در CSS، این مورد را با استفاده از ویژگی animation-range تنظیم می‌کنید. مثال:

animation-range: entry 0% entry 100%;

در جاوا اسکریپت، از ویژگی‌های rangeStart و rangeEnd استفاده کنید.

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

از ابزاری که در زیر تعبیه شده است استفاده کنید تا ببینید هر نام محدوده چه چیزی را نشان می‌دهد و درصدها چگونه بر موقعیت‌های شروع و پایان تأثیر می‌گذارند. سعی کنید شروع محدوده را روی entry 0% و پایان محدوده را روی cover 50% تنظیم کنید و سپس نوار پیمایش را بکشید تا نتیجه انیمیشن را ببینید.

ابزار نمایش محدوده‌های خط زمانی، قابل دسترسی در https://goo.gle/view-timeline-range-tool

تماشای یک ضبط

همانطور که ممکن است هنگام کار با ابزارهای View Timeline Ranges متوجه شده باشید، برخی از محدوده‌ها را می‌توان با دو ترکیب مختلف range-name + range-offset هدف‌گیری کرد. برای مثال، entry 0% ، entry-crossing 0% و cover 0% همگی یک منطقه را هدف قرار می‌دهند.

وقتی مقادیر range-start و range-end نام محدوده یکسانی را هدف قرار می‌دهند و کل محدوده - از 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 Timelines، می‌توانید View Timelines را نیز ایجاد کنید. به جای ویژگی‌های 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 ، عنصر در نزدیکترین scroller خود ردیابی می‌شود. سپس همان مقدار به عنوان مقدار ویژگی animation-timeline استفاده می‌شود. خروجی بصری دقیقاً مانند قبل است.

✨ خودتان امتحان کنید

ایجاد جدول زمانی پیشرفت نمایش در جاوا اسکریپت

برای ایجاد یک View Timeline در جاوا اسکریپت، یک نمونه جدید از کلاس ViewTimeline ایجاد کنید. یک property bag شامل subject مورد نظر برای ردیابی)، axis ) و inset به آن ارسال کنید.

  • subject : ارجاعی به عنصری که می‌خواهید درون اسکرول خودش ردیابی شود.
  • axis : محوری که باید ردیابی شود. مشابه نوع CSS، مقادیر پذیرفته شده block ، inline ، x و y هستند.
  • inset : تنظیم inset (مثبت) یا outset (منفی) درگاه اسکرول هنگام تعیین اینکه آیا کادر در دید است یا خیر.
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%',
});

✨ خودتان امتحان کنید

چیزهای بیشتری برای امتحان کردن

اتصال به چندین محدوده View Timeline با یک مجموعه از فریم‌های کلیدی

بیایید نگاهی به این دموی لیست تماس بیندازیم که در آن ورودی‌های لیست متحرک هستند. وقتی یک ورودی لیست از پایین وارد درگاه اسکرول می‌شود، به صورت کشویی + محو می‌شود و وقتی از درگاه اسکرول در بالا خارج می‌شود، به صورت کشویی + محو می‌شود.

نسخه آزمایشی: لیست مخاطبین

✨ خودتان امتحان کنید

برای این دمو، هر عنصر با یک جدول زمانی نمایش (View Timeline) تزئین شده است که عنصر را هنگام عبور از اسکرول‌پورت خود دنبال می‌کند، اما دو انیمیشن اسکرول‌محور به آن متصل شده‌اند. انیمیشن 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 ندارید. نتیجه دقیقاً مشابه قبل است.

✨ خودتان امتحان کنید

اتصال به یک جدول زمانی پیمایش غیر اجدادی

مکانیزم جستجو برای جدول‌های زمانی Scroll نامگذاری شده و جدول‌های زمانی View نامگذاری شده فقط به اجداد scroll محدود می‌شود. با این حال، اغلب اوقات، عنصری که باید متحرک‌سازی شود، فرزند scroller مورد نظر برای ردیابی نیست.

برای انجام این کار، ویژگی 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 برای انتقال یک جدول زمانی به یک جد (که به آن hoisting هم می‌گویند) استفاده کنید، به طوری که همه فرزندان جد بتوانند به آن دسترسی داشته باشند.

ویژگی timeline-scope را می‌توان هم با Scroll Timelines و هم با View Timelines استفاده کرد.

دموها و منابع بیشتر

تمام دموهای پوشش داده شده در این مقاله در مینی‌سایت scroll-driven-animations.style قرار دارند. این وب‌سایت شامل دموهای بسیار بیشتری است تا امکانات انیمیشن‌های Scroll-driven را برجسته کند.

یکی از دموهای اضافی، این لیست از جلدهای آلبوم است. هر جلد به صورت سه‌بعدی می‌چرخد و در مرکز توجه قرار می‌گیرد.

نسخه آزمایشی: جریان پوشش

✨ خودتان امتحان کنید

یا این نمایش کارت‌های روی هم چیده شده، آن position: sticky . با انباشته شدن کارت‌ها، کارت‌های از قبل چسبیده شده کوچک‌تر می‌شوند و یک جلوه عمق زیبا ایجاد می‌کنند. در نهایت، کل دسته به صورت گروهی از دید خارج می‌شوند.

نسخه آزمایشی: چیدن کارت‌ها .

✨ خودتان امتحان کنید

همچنین در scroll-driven-animations.style مجموعه‌ای از ابزارها مانند نمایش پیشرفت محدوده زمانی نمایش (View Timeline Range Progress) که قبلاً در این پست گنجانده شده بود، وجود دارد.

انیمیشن‌های اسکرول‌محور همچنین در بخش «چه چیزهایی در انیمیشن‌های وب در کنفرانس Google I/O 2023 جدید است» پوشش داده شده‌اند.