gsap的ScrollTrigger讓你的頁面更炫酷

之前做官網(wǎng),設(shè)計的交互雖然在其他網(wǎng)站很常見,但是我一時不知道如何實現(xiàn),直到我看到了gsap,發(fā)現(xiàn)原來這么簡單。

項目搭建

1. 創(chuàng)建vite項目,并安裝依賴

# 創(chuàng)建一個原生ts項目
pnpm create vite gsap-demo --template vanilla-ts
cd gsap-demo

# 安裝gsap依賴
pnpm add gsap

2. 初始化gsap

import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'

gsap.registerPlugin(ScrollTrigger)

效果一:橫向滾動

滾動頁面滾動條,gsap會接管滾動條,進行div的橫向滾動。

image.png

1. 編寫html

父組件flex布局,子元素設(shè)置三個圖片。

<div class="box-container">
    <div class="box">
    <img class="box-image" src="https://picsum.photos/1200/900" alt="box" />
    </div>
    <div class="box">
    <img class="box-image" src="https://picsum.photos/1200/900" alt="box" />
    </div>
    <div class="box">
    <img class="box-image" src="https://picsum.photos/1200/900" alt="box" />
    </div>
</div>
.box-container {
  display: flex;
  flex-wrap: nowrap;
  gap: 20px;
  overflow: hidden;
}

.box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  flex-shrink: 0;
}

.box-image {
  object-fit: cover;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  border-radius: 10px;
}

2. 配置gsap

const boxContainer: HTMLElement | null = document.querySelector('.box-container')
  const boxItems = gsap.utils.toArray('.box-container .box')
  if (!boxContainer) return
  gsap.to(boxItems, {
    xPercent: -100 * (boxItems.length - 1),
    ease: 'none',
    scrollTrigger: {
      trigger: boxContainer,
      pin: true,
      start: 'top top',
      scrub: 1,
      markers: true,
      end: `+=${boxContainer.offsetWidth || 0 - innerWidth}`,
    },
  })

詳細說明:

  • xPercent: -100 (boxItems.length - 1): 這行代碼設(shè)置了每個 boxItems 元素的水平移動百分比。xPercent 是一個相對移動的值,-100 (boxItems.length - 1) 意味著將所有的 boxItems 元素水平移動到最后一個元素的位置。
  • ease: 'none': 這里設(shè)置了動畫的緩動效果為“無”,即動畫將以線性方式進行,沒有加速或減速。
  • scrollTrigger: 這是 ScrollTrigger 插件的配置對象,用于定義滾動觸發(fā)的行為。
    • trigger: boxContainer: 指定哪個元素觸發(fā)滾動動畫。
    • pin: true: 將 boxContainer 固定在視口中,直到動畫結(jié)束。
    • start: 'top top': 定義動畫開始的滾動位置,當(dāng) boxContainer 的頂部與視口頂部對齊時開始。
    • scrub: 1: 使動畫與滾動同步,值為 1 表示動畫的平滑度。
    • markers: true: 顯示滾動觸發(fā)器的標記,方便調(diào)試。
    • end: +=${boxContainer.offsetWidth || 0 - innerWidth}: 定義動畫結(jié)束的滾動位置,計算方式是 boxContainer 的寬度減去視口的寬度。這段代碼的目的是在用戶滾動頁面時,創(chuàng)建一個水平滾動的動畫效果,使得 boxItems 元素在 boxContainer 內(nèi)水平移動。

3. 查看效果

設(shè)置了的start: 'top top'后,可以看到marker的scroller-startscroller-end都在視口的頂部。

當(dāng)marker的start移動到scroller-start后則開始動畫。

image.png

當(dāng)marker的end移動到scroller-end后則結(jié)束動畫

image.png

效果二:卡片效果

滾動頁面,卡片從右往左展示,類似卡片切換效果。

image.png

1. 編寫html

絕對定位card,讓他們交錯排布。

<div class="card-container">
    <div class="card card-1">
    <img class="card-image" src="https://picsum.photos/400/300" alt="card" />
    </div>
    <div class="card card-2">
    <img class="card-image" src="https://picsum.photos/400/300" alt="card" />
    </div>
    <div class="card card-3">
    <img class="card-image" src="https://picsum.photos/400/300" alt="card" />
    </div>
    <div class="card card-4">
    <img class="card-image" src="https://picsum.photos/400/300" alt="card" />
    </div>
    <div class="card card-5">
    <img class="card-image" src="https://picsum.photos/400/300" alt="card" />
    </div>
</div>
.card-container {
  position: relative;
  display: flex;
  flex-wrap: nowrap;
  gap: 20px;
  overflow: hidden;
  width: 100%;
  height: 100vh;
}

.card {
  width: 400px;
  height: 300px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  flex-shrink: 0;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  border-radius: 10px;
  border: 2px solid #ccc;
  overflow: hidden;
}

.card-1 {
  right: 10%;
}

.card-2 {
  right: 12%;
}

.card-3 {
  right: 14%;
}

.card-4 {
  right: 16%;
}

.card-5 {
  right: 18%;
}

2. 編寫gsap動畫

const cardContainer: HTMLElement | null = document.querySelector('.card-container')
  if (!cardContainer) return
  gsap.timeline({
    scrollTrigger: {
      trigger: cardContainer,
      pin: true,
      start: 'top top',
      scrub: 1,
      end: `+=${cardContainer.offsetWidth || 0 - innerWidth}`,
      markers: true,
    },
  })
    .to('.card-5', { xPercent: -110, scale: 1.1 }, 0)
    .to('.card-5', { xPercent: -250, scale: 1 }, 1)
    .to('.card-4', { xPercent: -110, scale: 1.1 }, 1)
    .to('.card-4', { xPercent: -250, scale: 1 }, 2)
    .to('.card-3', { xPercent: -110, scale: 1.1 }, 2)
    .to('.card-3', { xPercent: -250, scale: 1 }, 3)
    .to('.card-2', { xPercent: -110, scale: 1.1 }, 3)
    .to('.card-2', { xPercent: -250, scale: 1 }, 4)
    .to('.card-1', { xPercent: -110, scale: 1.1 }, 4)
    .to('.card-1', { xPercent: -250, scale: 1 }, 5)

詳細說明:

  • gsap.timeline: 創(chuàng)建一個時間軸動畫,允許多個動畫按順序執(zhí)行
  • gsap.timeline.to: 創(chuàng)建每個時間點的動畫詳情,例如本效果,就是每個卡片向左移動一定百分比和放大縮小效果。

3.查看效果

主要就是最后右邊移動到中間并放大,然后移動到最左邊縮小到正常大小,每個card依次執(zhí)行。

image.png

總結(jié)

主要還是要多看文檔,然后通過makers來確定滾動位置是否正確。尤其是結(jié)合整個頁面時,要保證頁面的高度時刻確定的,這樣才能讓頁面加載完畢后,gsap的makers計算正確,比如之前設(shè)置了圖片懶加載,但是忘了設(shè)置圖片的高度,導(dǎo)致下面的gsap計算錯誤,滾動效果出現(xiàn)問題,這個時候就需要開啟markers來確定問題。

參考文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容