概要
セクションを画面にピン留めした状態でスクロールを進め、横方向のタイムライン上にステップカードが順番に立ち上がっていく、制作フロー・サービス手順の紹介向け演出。
使用技術
・GSAP + ScrollTrigger(ピン留め・スクラブ)
・`gsap.matchMedia()` によるレスポンシブ出し分け / FontAwesome / Google Fonts(Montserrat・Noto Sans JP)
実装ポイント
・PC(min-width: 1024px)では `pin: true`・`scrub: 1`・`end: “+=2000″` のタイムラインでセクションを固定し、スクロール量をアニメーション進行に変換。`anticipatePin: 1` でピン開始のカクつきを抑制
・横ラインは `scaleX` を0→1で伸ばし、各ステップは `position = index * 0.18` でタイムライン上に時間差配置。円マーカー(`scale` + `back.out(1.7)`)→接続線(`scaleY`)→カード(`opacity` + `y`)の順に連鎖出現
・背景の巨大文字は別ScrollTriggerで `x: -200`・`scrub` の横パララックス
・`gsap.matchMedia()` で画面幅ごとに処理を分離。SP(max-width: 1023px)ではピンを使わず、各カードを個別トリガーで `x: 30`→`0` の縦積みフェードインに切り替え、メディアクエリ解除時のクリーンアップも自動化
コアスニペット
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".process-section",
start: "top top", end: "+=2000",
pin: true, scrub: 1, anticipatePin: 1,
},
});
items.forEach((item, index) => {
const position = index * 0.18;
tl.to(item.querySelector(".process__circle"), { scale: 1, duration: 0.15, ease: "back.out(1.7)" }, position);
tl.to(item.querySelector(".process__connect-line"), { scaleY: 1, duration: 0.15 }, position + 0.05);
tl.to(item.querySelector(".process__card"), { opacity: 1, y: 0, duration: 0.3, ease: "power2.out" }, position + 0.1);
});