モバイルで吸い付くように回る3D地球儀:慣性カメラドラッグとPWA防災ダッシュボードのUI/UX設計

📅 2026-08-29 ✍️ prosalmontech #QuakeViewer3D#PWA#UI/UX#タッチジェスチャー#モバイル最適化#フロントエンド

地震速報や宇宙の3Dビジュアライゼーションは、PCの大画面だけでなく「今まさに揺れを感じた瞬間にポケットから取り出したスマートフォン」の上で快適に動作しなければ、実用的な防災ツールとは言えません。

しかし、モバイルブラウザで3D球体を操作する際、多くのユーザーが直面するのが「指の動きと地球の回転が滑ってズレる」「北極付近でカメラが突然あらぬ方向へ反転する」「指を離すとピタッと止まって無機質に感じる」というストレスです。QuakeViewer3Dでは、まるで机の上の本物の地球儀を指先でスピンさせているかのような、吸い付くような操作感を実現しました。本記事では、その数学的アルゴリズムとPWA防災ダッシュボードのUI/UX設計を解説します。

1. なぜ標準のOrbitControlsではモバイル操作に違和感が出るのか?

Three.jsで広く使われている OrbitControls は、基本的にPCのマウス操作(左右ドラッグで方位角、上下ドラッグで仰角を変更する球面極座標系)を前提に設計されています。

この方式をスマートフォンのタッチスクリーンにそのまま適用すると、以下のような致命的な操作感の乖離が発生します:

2. アークボール(Arcball)投影とクォータニオンによる全方位球面回転

QuakeViewer3Dでは、この問題を解決するためにアークボール(Arcball / Trackball)回転アルゴリズムをゼロから自作しました。

画面上の2Dタッチ座標 $(x, y)$ を、画面背後にある仮想的な3D単位球面上の一点 $\vec{v} = (v_x, v_y, v_z)$ に射影します。指が前回のフレームの点 $\vec{v_1}$ から今回の点 $\vec{v_2}$ に移動したとき、その2つのベクトルの外積と内積から回転軸と回転角を算出し、四元数(Quaternion)として合成します:

// 2Dスクリーン座標を3D仮想球面上に射影する関数
function projectToSphere(x, y, width, height) {
    const r = Math.min(width, height) * 0.45;
    const px = (x - width / 2) / r;
    const py = (height / 2 - y) / r;
    const d2 = px * px + py * py;
    
    if (d2 <= 1.0) {
        return new THREE.Vector3(px, py, Math.sqrt(1.0 - d2)).normalize();
    } else {
        // 球の外側をドラッグした場合は双曲線でスムーズに減衰
        return new THREE.Vector3(px, py, 1.0 / (2.0 * Math.sqrt(d2))).normalize();
    }
}

// タッチ移動イベントでのクォータニオン回転合成
function onTouchMove(currPos, prevPos) {
    const v1 = projectToSphere(prevPos.x, prevPos.y, viewWidth, viewHeight);
    const v2 = projectToSphere(currPos.x, currPos.y, viewWidth, viewHeight);
    
    const axis = new THREE.Vector3().crossVectors(v1, v2).normalize();
    const angle = Math.acos(Math.min(1.0, v1.dot(v2))) * ROTATION_SENSITIVITY;
    
    const deltaQuat = new THREE.Quaternion().setFromAxisAngle(axis, angle);
    globeGroup.quaternion.premultiply(deltaQuat);
}

クォータニオン演算をベースとすることで、特異点やジンバルロックは原理的に存在しなくなり、どの方向へ指をスワイプしても、指が触れた地表が指先に吸い付くようにダイレクトに追従します。

3. 物理シミュレーションに基づく指数減衰慣性(Inertial Damping)

デジタル地球儀に生命を吹き込むのが「慣性スクロール(Inertia)」です。指を勢いよくフリックして離した際、瞬間的に地球儀が停止すると安っぽさを感じさせます。

QuakeViewer3Dでは、指が離れる直前3フレームの平均角速度ベクトル $\vec{\omega}$ を計算し、指を離した瞬間に慣性シミュレーションモードへ移行させます。毎フレーム、物理学における粘性摩擦抵抗を模した指数減衰係数($\gamma \approx 0.94$)を乗算して徐々に回転を落ち着かせます:

// アニメーションループ内での慣性回転ステップ
function updateInertia(deltaTime) {
    if (!isUserTouching && angularVelocity.lengthSq() > 0.000001) {
        const angle = angularVelocity.length() * deltaTime;
        const axis = angularVelocity.clone().normalize();
        
        const deltaQuat = new THREE.Quaternion().setFromAxisAngle(axis, angle);
        globeGroup.quaternion.premultiply(deltaQuat);
        
        // 粘性減衰(摩擦力)の適用
        angularVelocity.multiplyScalar(Math.pow(0.92, deltaTime * 60));
    }
}

この慣性計算により、ユーザーは地球儀を勢いよくスピンさせて地球の裏側へ一瞬で移動したり、ゆっくり指先で微調整したりといった、直感的で心地よいフィジカルな操作感を体験できます。

4. 片手操作に最適化したボトムシートHUDとPWA(Progressive Web App)設計

モバイル画面の専有面積は極めて貴重です。画面上部に大きな固定コントロールバーを配置すると、せっかくの3D地球儀が半分隠れてしまいます。

5. まとめとフロントエンドUXの追求

Webブラウザ上で動作する3Dアプリだからといって、ネイティブアプリに操作感で劣ってよい理由はありません。

「アークボールクォータニオンによる幾何学的追従」「物理慣性シミュレーションによる滑らかな手触り」「親指に最適化したPWAインターフェース」の3点を徹底的に作り込むことで、QuakeViewer3Dは緊急時にもストレスなく頼れる防災プラットフォームとしての完成度を高めました。

🚀 prosalmontech ポートフォリオ

SatViewer3D、QuakeViewer3D、NihongoChatAI、JPQuizなど、開発中のアプリ・Webサービスを公開中!

トップページでプロダクトを見る