ساختن جلوه‌های اسلاید گردونه‌ای

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

نحوه پیاده‌سازی

در اینجا نحوه ایجاد جلوه‌های اسلاید گردونه‌ای را مشاهده می‌کنید:

  1. ایجاد پیمایشگر: این عنصر به‌عنوان ظرفی برای اسلایدهای گردونه شما عمل خواهد کرد. در این مثال، از overflow-x: scroll برای مجاز کردن پیمایش افقی استفاده می‌کند.

    <ul class="scroller">
      <li class="entry">1</li>
      <li class="entry">2</li>
      <li class="entry">3</li>
      …
    </ul>
    
    .scroller {
      overflow-x: scroll;
    }
    
  2. پویانمایی را تعریف کنید: پویانمایی CSS ایجاد کنید که حالت‌های مختلف اسلایدها را هنگام عبور از درگاه پیمایش تعریف کند. می‌توانید برای هر بخشی از پویانمایی قاب‌های کلیدی تعریف کنید. برای مثال، می‌توانید با گنجاندن فریم کلیدی 50%، حالتی را برای زمانی که اسلایدها در مرکز درگاه پیمایش قرار دارند تعریف کنید. در این مثال، ویژگی scale باعث می‌شود اسلایدها با نزدیک شدن به مرکز بزرگ‌تر و با دور شدن از آن کوچک‌تر شوند.

    @keyframes animate {
      0% {
        scale: 0.5;
      }
      50% {
        scale: 1;
      }
      100% {
        scale: 0.5;
      }
    }
    
  3. اعمال پویانمایی و view-timeline: پویانمایی را به اسلایدهای گردونه پیوست کنید و آن را به view-timeline پیوند دهید که عنصر را هنگام پیمایش در ظرف ردیابی می‌کند.

    .scroller > * {
      animation: animate auto linear both;
      animation-timeline: view(inline);
    }
    

    به‌طور پیش‌فرض، view() عنصر را در محور block ردیابی می‌کند. اگر لازم است آن را در محور inline ردیابی کنید، می‌توانید از view(inline) استفاده کنید.

کد نمونه

این کد بااستفاده از view-timeline ناشناس، موارد گردونه پیمایشگر افقی را هنگام پیمایش متحرک می‌کند:

@keyframes animate {
  0% {
    scale: 0.5;
  }

  50% {
    scale: 1;
  }

  100% {
    scale: 0.5;
  }
}

.scroller > * {
  /* Applies the animation using an `auto` duration */
  animation: animate auto linear both;
  /* Sets the animation timeline to use an anonymous view progress timeline, tracking the element's progress through the scroller on the inline axis */
  animation-timeline: view(inline);
}

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

@keyframes animate {
  0% {
    scale: 0.5;
  }

  50% {
    scale: 1;
  }

  100% {
    scale: 0.5;
  }
}

/* This creates a named view-timeline on each carousel item. The timeline is used to drive the animation that is applied on the same element. */
.scroller > * {
  /* Applies the animation using an `auto` duration */
  animation: animate auto linear both;
  /* Defines a named view progress timeline, tracking the element's progress through the scroller on the inline axis */
  view-timeline: --item inline;
  /* Sets the animation timeline to use the named view progress timeline defined above */
  animation-timeline: --item;
}

روال‌های مطلوب

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

  • باید تشخیص ویژگی را اضافه کنید: همه مرورگرها از پویانمایی‌های پیمایش‌محور پشتیبانی نمی‌کنند. از @supports ((animation-timeline: view()) and (animation-range: entry)) برای بررسی پشتیبانی و ارائه بازگشت به روش پیش‌فرض برای مرورگرهایی که از آن پشتیبانی نمی‌کنند استفاده کنید.
    • بررسی (animation-range: entry) باید در اینجا گنجانده شود تا مرورگرهایی که فقط پشتیبانی جزئی دارند فیلتر شوند.
    • از بسته scroll-timeline-polyfill برای راهبرد جایگزین استفاده نکنید زیرا ویژگی‌های آن کامل نیست و مشکلات شناخته‌شده زیادی دارد.
    • اگر پویانمایی فقط تزئینی درنظر گرفته می‌شود، «ارتقای پیش‌رو» را انتخاب کنید و گزینه جایگزین ارائه ندهید.
  • باید به اولویت‌های کاربر احترام بگذارید: برخی‌از کاربران ترجیح می‌دهند حرکت کمتری در وب داشته باشند. از پُرسمان رسانه prefers-reduced-motion برای غیرفعال کردن یا کاهش پویانمایی‌ها برای این کاربران استفاده کنید.
  • باید سعی کنید فقط دارایی‌های CSS کارا را پویانمایی کنید: برای داشتن روان‌ترین پویانمایی‌ها، فقط دارایی‌هایی را پویانمایی کنید که رشته ترکیب‌کننده مرورگر می‌تواند آن‌ها را مدیریت کند، مثل transform و opacity. پویانمایی کردن ویژگی‌های دیگر مثل width یا height می‌تواند به مشکلات عملکردی منجر شود.
  • باید از ترتیب صحیح اعلام استفاده کنید: هنگام استفاده از ویژگی خلاصه animation، animation-timeline و animation-range را بعداز آن اعلام کنید تا از بازنشانی خط زمان توسط خلاصه جلوگیری شود.

وقتی چند عنصر DOM باید براساس خط زمان یکسانی پویانمایی شوند، یا وقتی باید فرزندان عنصری را که view-timeline روی آن تعریف شده است پویانمایی کنید، بهتر است از view-timeline نام‌گذاری‌شده استفاده کنید. اگر عنصری که پویانمایی می‌کنید همان عنصری باشد که view-timeline را تعریف می‌کند، می‌توانید بااستفاده از view() از view-timeline ناشناس استفاده کنید.

هنگام استفاده از تابع view() برای ایجاد پویانمایی پیمایش‌محور:

  • اختیاری به‌طور صریح محور موردنظر برای ردیابی را مشخص کنید: وقتی محور پیش‌فرض block را هدف قرار نمی‌دهید (مثلاً در پیمایشگر افقی)، به‌طور صریح مشخص کنید که کدام محور باید با view(block) یا view(inline) ردیابی شود.

هنگام استفاده از ویژگی view-timeline برای ایجاد پویانمایی پیمایش‌محور:

  • باید از CSS <dashed-ident> برای نام استفاده کنید (مثلاً view-timeline: --my-custom-name)
  • اختیاری محور موردنظر برای ردیابی را به‌طور صریح مشخص کنید: وقتی محور پیش‌فرض block را هدف قرار نمی‌دهید (مثلاً در پیمایشگر افقی)، به‌طور صریح مشخص کنید که کدام محور با view-timeline-axis ردیابی شود.
  • باید مطمئن شوید که دامنه جستجو کار می‌کند: وقتی عنصری که view-timeline را اعلام می‌کند، جد درخت مسطح عنصر پویانمایی‌شده نیست، بااستفاده از timeline-scope در جد مشترک، نمایان بودن نام view-timeline را بالا ببرید.

پشتیبانی مرورگر و راهبردهای جایگزین

بنابراین، معمولاً به یک استراتژی جایگزین نیاز است.

برای مرورگرهایی که از پویانمایی‌های پیمایش‌محور پشتیبانی نمی‌کنند، می‌توانید از یک جایگزین برای بازآفرینی جلوه‌های دیداری استفاده کنید. جایگزین‌ها معمولاً با شنونده پیمایش (برای جلوه‌های ScrollTimeline) یا IntersectionObserver API (برای جلوه‌های ViewTimeline) ساخته می‌شوند.

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

توجه داشته باشید که همه جلوه‌ها را نمی‌توان بااستفاده از رویکرد جایگزین بازآفرینی کرد.

به‌طور خاص برای این مورد استفاده، دستورگان زیر برای مرورگرهایی که از پویانمایی‌های پیمایش‌محور پشتیبانی نمی‌کنند، جایگزین را اعمال می‌کند. این ویژگی از Web Animations API (Element.animate()) برای ایجاد پویانمایی موقتاً متوقف‌شده برای هر مورد در گردونه استفاده می‌کند. سپس به رویداد scroll در پیمایشگر گوش می‌دهد و currentTime هر پویانمایی را براساس پیشرفت پیمایش مورد در پیمایشگر به‌روز می‌کند.

// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
  const scroller = document.querySelector('.scroller');
  const entries = document.querySelectorAll('.entry');

  // Create a map to store animations
  const animations = new Map();

  entries.forEach(entry => {
    const animation = entry.animate(
      {
        scale: ['0.5', '1', '0.5']
      },
      {
        duration: 1, // We'll control the time ourselves
        fill: 'both'
      }
    );
    animation.pause();
    animations.set(entry, animation);
  });

  // Update animations on scroll
  const tick = () => {
    const scrollerRect = scroller.getBoundingClientRect();

    entries.forEach(entry => {
      const animation = animations.get(entry);
      if (!animation) return;

      const entryRect = entry.getBoundingClientRect();
      const progress = (entryRect.left + entryRect.width / 2 - scrollerRect.left) / scrollerRect.width;

      animation.currentTime = progress;
    });
  };
    
  scroller.addEventListener('scroll', tick);
  tick();
}