カメラが現在画面を貫いて次画面へ潜り込む 3D ページ遷移。現在の画面は手前へ飛び抜け、次の画面が奥から迫り上がってくる。Pure CSS 3D(perspective + translateZ)、WebGL なし。
Live demo: ./index.html
| 項目 | 内容 |
|---|---|
| ジャンル | D · 3D・空間 |
| 用途 | Tr · ページ遷移 |
| 主な参考 | Bruno Simon portfolio |
| 依存 | なし(Pure HTML + CSS + Vanilla JS) |
| 推奨配置 | フルスクリーンのセクション切り替え、ポートフォリオ、オンボーディング |
.deck に perspective を掛け、子の各 .screen を 3 状態のどれかに置くだけ。実際の 3D 変形は CSS が担当し、JS は data-state を切り替えるだけ。
| 状態 | transform | opacity | 意味 |
|---|---|---|---|
active |
translateZ(0) |
1 | カメラ正面(表示中) |
next |
translateZ(-depth) |
0 | 奥に待機 → 迫ってくる |
prev |
translateZ(+pass) |
0 | 手前へ通過 → 飛び抜けた |
進む:現在画面が active → prev(手前へ拡大しながら消える=カメラが貫通)、次画面が next → active(奥から原寸へ迫る)。戻る:対称に、現在画面が active → next(奥へ引く)、前画面が prev → active(手前から戻る)。
transition で transform と opacity を補間するだけなので、フレームループ不要・GPU 合成(will-change)。
style.css と script.js を移植先へ。外部依存ゼロ。
<link rel="stylesheet" href="./camera-dive.css">
<div class="camera" data-camera-deck>
<div class="deck">
<section class="screen">…画面1…</section>
<section class="screen">…画面2…</section>
<section class="screen">…画面3…</section>
</div>
<!-- 任意のコントロール(あれば自動で配線される) -->
<div class="deck-ui">
<button class="deck-btn" data-deck-prev aria-label="前">←</button>
<div class="deck-dots" data-deck-dots></div>
<button class="deck-btn" data-deck-next aria-label="次">→</button>
</div>
<span class="deck-count" data-deck-count></span>
</div>
<script src="./camera-dive.js"></script>.screenは何枚でも可。中身は自由data-deck-prev/data-deck-next/data-deck-dots/data-deck-countは任意。置けば JS が自動配線- ドットは JS が
.screenの数だけ自動生成 ← / →キーでも移動(.cameraにフォーカス/ホバー中)
デモでは .screen--a … --d のクラスで背景色を差し替えている。任意のクラス/インラインスタイルで自由に。
| 変数 | 役割 | デフォルト |
|---|---|---|
--cam-perspective |
遠近の強さ(小さいほど誇張される) | 1200px |
--cam-depth |
next 画面が待機する奥行き |
1500px |
--cam-pass |
prev 画面が手前へ飛ぶ距離 |
800px |
--cam-dur |
遷移時間 | 900ms |
--cam-ease |
イージング | cubic-bezier(.7,0,.2,1) |
--cam-stage |
ステージ(カメラ枠)の高さ | min(80vh,680px) |
--cam-durを変えたら、script.jsの連打ロック時間(既定 700ms)も合わせて調整すると気持ちよい。
/* 誇張を強く(突き抜け感アップ) */
.camera{ --cam-perspective:800px; --cam-pass:1100px; }
/* フルビューポートのステージに */
.camera{ --cam-stage:100vh; }prefers-reduced-motion: reduce のとき、Z 方向の移動を止めて単純なクロスフェードに切り替える。非アクティブ画面は aria-hidden="true"。
- 遷移中は
animatingフラグで連打をロック(既定 700ms)。--cam-durを大きくしたらこの値も伸ばす .deckはoverflow:hiddenで枠外を切る。prev画面が手前へ飛ぶ際、枠いっぱいに拡大してから消える- 画面数が非常に多い場合でも全
.screenが DOM に常駐する(重い中身なら遅延描画を別途検討)
ANIMATION DESIGN STUDY の一部として公開(コピペ自由)。