CARLOS LASTRES お問い合わせ

three.jsとGSAPで作るスクロール演出の基本と注意点

Claude Codeでスクロール連動の3Dサイトを作る手順。ループの組み方、日本語の文字演出、表示の重さ対策、動きを減らす設定への対応まで。

スクロールに合わせて製品が回転したり、見出しが一文字ずつ現れたりするサイト。採用サイトやブランドサイトの提案で「こういう動きを入れたい」と言われることも多いと思います。見た目は高度ですが、中身はほぼ一つの数値です。そのセクションをどこまで読み進めたかを0から1で表し、それを動きに対応させているだけです。

私は自分のプロダクトのサイトを、three.js、GSAP、Lenisを組み合わせて作っています。配線の大半はClaude Codeに書かせています。このガイドでは、その構成と、日本語サイトならではの注意点、そして表示の重さと酔いへの配慮をまとめます。

道具は「一番軽いもの」から選ぶ

  • フェードインなど簡単な出現:CSSのスクロール駆動アニメーション(animation-timeline: view())。JavaScript不要です。まだ全ブラウザ対応ではないので、効かなくても内容が読める作りにしておきます。
  • セクションを固定して動かす演出:GSAPのScrollTrigger。GSAPは2025年からプラグインも含めて商用でも無料です。クライアント案件で有料ライセンスの稟議を通す必要はもうありません。
  • 製品の回転や分解:連番画像をcanvasに描き、スクロール位置でコマを選ぶ方法。
  • 本物の3D:three.js。スクロールでカメラやモデルを動かします。

そこにLenisを重ねると、ホイールの一段ごとのカクつきがなくなり、動きがなめらかにつながります。

最初の土台づくり

効果を足す前に、ループが一本だけの土台を作ってもらいます。空のフォルダでClaude Codeにこう頼みます。

Vite(素のJavaScript)でプロジェクトを作成し、three、gsap、lenis を入れてください。
requestAnimationFrame のループは一本だけにします。
GSAPのticker で Lenis と ScrollTrigger を動かし、three.js の描画も同じticker の中で行う。
lenis/dist/lenis.css を読み込む。
背面に固定のcanvas、id付きの縦長セクションを5つ。演出はまだ入れない。
開発サーバーを起動してURLを教えてください。

スクロールサイトがガタつく原因で一番多いのは、ループが二重三重になっていることです。プロンプトで一つずつ演出を足していくと、気づかないうちにそうなります。最初に「一本だけ」と決めておくのが効きます。

日本語の文字演出で気をつけること

英語向けのチュートリアルには「単語ごとに分割して順番に出す」演出がよく出てきます。日本語は単語の間にスペースがないので、そのまま真似すると一行まるごと一つの「単語」として扱われます。

  • 一文字ずつ出すなら、文字単位の分割で問題ありません。
  • 意味のまとまりで出したいなら、ブラウザ標準のIntl.Segmenterで日本語を単語に区切ってから分割するよう指示します。
  • 分割した文字がスクリーンリーダーで一文字ずつ読み上げられないよう、元の文をaria-labelで持たせます。
  • 日本語Webフォントは容量が大きいので、使う文字だけにサブセット化するか、見出しだけに使います。フォント待ちで演出が始まらないのが一番もったいないです。
見出しを文字演出にしてください。日本語なので Intl.Segmenter('ja', { granularity: 'word' })
で語に区切り、語ごとに下から現れるようにします。元の文は aria-label で保持し、
分割した要素は aria-hidden にしてください。

重さ対策は最初から

カクつくスクロール演出は、演出がないより印象が悪くなります。私が毎回Claudeに渡しているルールはこれです。

  • 動かすのは transform と opacity だけ。幅や位置のプロパティは毎フレーム再計算が走ります。
  • three.jsのピクセル比は2で頭打ち:renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  • canvasが画面外にあるとき、タブが裏にあるときは描画を止める。
  • 3DモデルはDracoなどで圧縮、連番画像はWebPかAVIFで、枚数は60から150枚程度に抑える。
  • 確認は手元の高性能なMacではなく、普通のスマホで。電車の中で開く人を想像してください。

演出がいくつか入ったら、足すのをやめて点検させます。

このサイトのスクロール性能を点検してください。レイアウト系プロパティを
アニメーションしている箇所、requestAnimationFrame のループ、二重に作られうる
ScrollTrigger、画面外でも動いているWebGL処理を一覧にして、一つずつ直し、
何を変えたか教えてください。

「動きを減らす」設定は必ず尊重する

大きなスクロール演出で気分が悪くなる人は実際にいます。OSで動きを減らす設定をしている人には、prefers-reduced-motionとして伝わります。

const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
  // 固定やスクラブの演出はここで作る
});
mm.add('(prefers-reduced-motion: reduce)', () => {
  // 各シーンの完成状態を表示するだけ。固定はしない
});

Lenisはこの設定がオンのとき、自動でなめらかスクロールを切ってくれます。2024年4月から、民間事業者にも障害のある人への合理的配慮の提供が義務化されました。企業サイトの提案では、この対応を最初から見積もりに入れておくと話が通りやすくなります。

まずは自分のサイトの一ページで、固定セクションを一つと、出現演出を一つだけ作ってみてください。スマホでなめらかに動き、動きを減らす設定でも読みやすいことを確認してから、次の演出に進む。この順番を守るだけで、仕上がりの印象はかなり変わります。

関連ガイド

← AIガイド一覧へ