スクロールする前に、
3秒で世界観を渡す

Three.js の粒子ヒーロー。ドラッグで回せます。

指示テンプレを見る
— ドラッグで視点が動きます —

これは何か

「3Dウェブサイトの指示文6本のうち5本が実際に動いた」という記事の中身を確かめ、 そのまま使える日本語の指示テンプレに組み直したものです。 上のヒーローは、テンプレ①をそのまま実行して出てきた実物です。

効いていたのは「3Dにして」ではなく、部品の名前を書くこと。

書く言葉効果
Three.js(CDNの版まで指定)存在しない書き方を使われるのを防ぐ
OrbitControlsドラッグで回せる操作が付く
GLSL fragment shader粒子ではなく面で描く演出になる
overlay は pointer-events:none文字が3Dの操作を邪魔しない(最頻の事故)
粒子数の上限・単一の板で描くスマホで落ちない

指示テンプレ 5本

貼るだけで動きます。①〜⑤の共通骨格は 主役 / 動きの源 / 操作 / 重ねる文字 / 重さの上限 の5点です。

① 粒子のヒーロー(このページの実物)

1ファイルのHTMLを作ってください。
・Three.js r128 のUMD版をCDNで読み込む
・主役:8000個の粒子を渦状に配置した銀河。時間で常にゆっくり回す
・操作:OrbitControls を入れる。ズームは無効、自動回転は有効
・重ねる文字:中央に見出しと1行の説明とボタン。
  重ねる箱は pointer-events:none、ボタンだけ pointer-events:auto
・重さ:粒子は8000個まで。スマホでは端末の解像度倍率を2までに抑える
・画面サイズ変更に追従させる
・外部ファイルは作らず、この1ファイルで完結させる

② 面で描く光(GLSLのグラデーション)

1ファイルのHTMLを作ってください。
・Three.js r128 のUMD版をCDNで読み込む
・主役:画面いっぱいの板を1枚だけ置き、GLSLのfragment shaderで
  ゆっくり流れるオーロラ状のグラデーションを描く
・動きの源:uniform の時間(uTime)だけ。ジオメトリは動かさない
・重ねる文字:左下にサービス名。箱は pointer-events:none
・重さ:描くのは単一の板1枚のみ。ループの中で新しい変数を作らない
・色は #05060a と #F77B22 を基調にする

③ スクロール連動(読み進めると形が変わる)

1ファイルのHTMLを作ってください。
・Three.js r128 のUMD版をCDNで読み込む
・主役:中央にトーラスノット1つ。金属質の材質と環境光
・動きの源:ページのスクロール量を0〜1に正規化し、
  その値で回転角・カメラのZ位置・材質の粗さを変える
・操作:スクロールのみ(OrbitControlsは入れない)
・重ねる文字:セクション3つ分の縦長の本文を上に重ねる。
  本文は読めるように背景を半透明の暗色にする
・重さ:requestAnimationFrame の中でスクロール値を読むこと(scrollイベント内で描画しない)

④ 商品を回して見せる(3Dビューア)

1ファイルのHTMLを作ってください。
・Three.js r128 のUMD版 と OrbitControls、GLTFLoader をCDNで読み込む
・主役:GLTFのモデルを1つ読み込んで中央に置く(URLは差し替え可能な定数にする)
・読み込み中は「読み込み中」の表示を出し、完了で消す
・操作:OrbitControls(回転と拡大のみ、上下の回りすぎは制限する)
・照明:環境光+正面からの平行光。影は落とさない
・重ねる文字:右下に操作の説明を小さく。pointer-events:none
・重さ:モデルが読めなかったときは黒画面にせず、代わりに立方体を出す

⑤ 背景だけ3D(既存LPに足す用)

既存のHTMLに、背景としてだけ動く3Dを足してください。
・canvasは position:fixed; inset:0; z-index:-1; pointer-events:none
・主役:ゆっくり漂う半透明の粒子2000個。色は薄いグレー1色
・既存の文字・ボタンの動作は一切変えないこと
・動きの源:時間のみ。スクロールでは変えない
・重さ:粒子2000個まで、端末の解像度倍率は1.5まで
・追加するのは script タグ1つと canvas 1つだけにする

実際に踏んだ落とし穴

どこで使うか

3DスクロールHPの営業サンプル、LPのヒーロー、ファネルの入口。 動画を作らずに「動く」画面が作れるので、素材費も生成枠も使いません。 重い動画ヒーローの置き換えとして一番効きます。