WebGL不使用。CSS 3D TransformだけでWebサイトを『ドローン飛行』できるブックマークレットを作ってみた

- アプローチの概要:脱・平面(No WebGL, Pure DOM)
通常、ブラウザ上で3D表現をするならThree.jsなどのWebGLライブラリを使うのが一般的です。しかし、このブックマークレットでは**「既存のWebサイトのDOM要素(divやimg)をそのまま3D空間に配置する」**という手法をとっています。
これにより、Canvasに描画し直すのではなく、「生きたWebサイト」の中に入り込む体験を実現しました。
- コア技術:transform-style: preserve-3d
このハックの肝は、<html> と <body> に適用したたった一行のCSSです。
CSS
body {
transform-style: preserve-3d;
perspective: 800px;
}
perspective: 奥行きの強さを定義します。
preserve-3d: これが重要です。通常、DOM要素は親要素の平面内に描画されてしまいますが、これを指定することで、子要素がZ軸(奥行き)を持ったまま3D空間に存在できるようになります。
- 「カメラ」の実装(逆変換の発想)
CSSには「カメラ」というオブジェクトは存在しません。そこで、**「世界(body)の方をカメラと逆方向に動かす」**ことで、擬似的に視点移動を実現しています。
JavaScript
/* カメラが前に進む = 世界が後ろに下がる */
var transform =
'translateZ(600px)' + // 視点距離のオフセット
'rotateX(' + cam.rx + 'deg)' + // 視線の上下
'rotateY(' + cam.ry + 'deg)' + // 視線の左右
'translate3d(' + (-cam.x) + 'px,' + cam.y + 'px,' + cam.z + 'px)'; // 逆移動
document.body.style.transform = transform;
プレイヤーが「Wキー」を押すと cam.z が増加し、計算式によって body 全体が手前に迫ってくるため、あたかも前進しているように見えます。
- DOMの「3D分解」ロジック
Webサイトをバラバラにする「分解深度(Explode Z)」機能は、各要素にランダムな固有値を持たせることで実現しています。
初期化時: ページ内の主要なタグ(div, img, h1...)を取得し、それぞれに -1.0 〜 1.0 のランダムな係数(rnd)を割り当ててメモリ上に保持します。
スライダー操作時: ユーザーが設定した「深度(explodeZ)」と係数を掛け合わせます。
JavaScript
// スライダーの値(explodeZ)に応じて各要素をZ軸方向に飛ばす
var z = target.rnd * explodeZ;
target.el.style.transform = 'translateZ(' + z + 'px)';
これにより、ある要素は奥へ、ある要素は手前へと飛び出し、Webサイトのレイヤー構造が可視化されます。
- UI/UX:没入感を高めるHUDデザイン
操作パネルは単なるHTMLですが、**「コックピット視点」**を演出するためにCSSグラデーションを活用しました。画像素材は一切使っていません。
グリッド背景: linear-gradient を組み合わせて、無限に続く緑色のグリッド線を描画。
テキスト: text-shadow を使い、古いCRTモニターのような「発光感」を表現。
- パフォーマンスへの配慮
DOM要素を大量に動かすのはブラウザにとって重い処理です。
requestAnimationFrame: スムーズな描画ループを実現。
will-change: transform: ブラウザに対して「この要素は動くぞ」と事前に伝え、GPUコンポジットを有効化(ハードウェアアクセラレーション)。
除外処理: scriptタグやstyleタグ、自分自身のUIパネルなどは操作対象から外し、無駄な計算を防いでいます。
XYZの座標計算で、三角関数(Math.sin, Math.cos)を使って移動ベクトルを計算するのが懐かしくて楽しかったです
Discussion