カーソルキー上下左右でパノラマを操作します。
コードをメモ帳などのテキストエディタに貼り付け、ファイルを「index.html」などの拡張子が.htmlのファイルとして保存します。その後、保存したファイルをブラウザで開けば、コードが実行されます。
説明:
Webカメラ映像の取得とテクスチャ化:
Webカメラの映像を取得し、VideoTextureオブジェクトを使ってテクスチャに変換します。これを後で円筒に貼り付けます。
円筒の作成:
CylinderGeometryで円筒形状を作成し、その上にWebカメラの映像をテクスチャとして貼り付けます。テクスチャは内側から見えるようにTHREE.DoubleSideを使用しています。
カメラ位置の設定:
カメラは円筒の内部の中心に位置しており、視点が常に円筒の中心を向くように設定されています。
キー入力による回転制御:
上下キーで円筒のX軸(横回転)を制御し、左右キーでY軸(縦回転)を制御します。キーが押されるたびに、指定された回転速度で回転角度が増減します。
アニメーションの更新:
animate関数で、フレームごとに円筒の回転状態を更新し、シーン全体をカメラの視点からレンダリングしています。
このコードを使うと、Webカメラで撮影した映像を貼り付けた円筒の内部で、キー操作に応じて視点が移動するパノラマビューを楽しめます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>360度パノラマビュー</title>
<style>
body { margin: 0; } /* ページの余白をなくす */
canvas { display: block; } /* キャンバスの表示設定 */
</style>
</head>
<body>
<!-- Three.js ライブラリの読み込み -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// グローバル変数宣言
let camera, scene, renderer, cylinder; // カメラ、シーン、レンダラー、円筒オブジェクト
let videoTexture; // Webカメラの映像をテクスチャにするための変数
let cylinderRotationX = Math.PI / 2; // 円筒のX軸回転角度の初期値(90度横向きに倒す)
let cylinderRotationY = 0; // 円筒のY軸回転角度の初期値
const rotationSpeed = 0.02; // 円筒の回転速度
// 初期化関数
function init() {
// シーンの作成
scene = new THREE.Scene();
// レンダラーの作成とサイズ設定
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement); // レンダラーのDOM要素をページに追加
// カメラを作成し、円筒の中心に配置
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 0); // カメラの位置を円筒の中心にセット
// Webカメラの映像を取得
const video = document.createElement('video'); // video要素を作成
navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
video.srcObject = stream; // Webカメラのストリームを設定
video.play(); // 映像再生
// 映像を横向きにするためのCSS回転設定
video.style.transform = 'rotate(90deg)';
// Webカメラ映像をテクスチャに変換
videoTexture = new THREE.VideoTexture(video);
// 円筒のジオメトリ(形状)を作成(円周5, 高さ10, 分割数32)
const geometry = new THREE.CylinderGeometry(5, 5, 10, 32, 1, true);
// テクスチャを適用したマテリアルを作成し、内側が見えるようにDoubleSide設定
const material = new THREE.MeshBasicMaterial({ map: videoTexture, side: THREE.DoubleSide });
// 円筒メッシュの作成と回転設定
cylinder = new THREE.Mesh(geometry, material);
cylinder.rotation.x = cylinderRotationX; // X軸に90度回転させて横向きに配置
scene.add(cylinder); // シーンに円筒を追加
// アニメーション開始
animate();
});
// ウィンドウサイズ変更時にカメラとレンダラーの調整
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight); // レンダラーサイズ更新
camera.aspect = window.innerWidth / window.innerHeight; // カメラのアスペクト比更新
camera.updateProjectionMatrix(); // カメラの投影行列更新
});
// キーボード入力で円筒の回転を制御
window.addEventListener('keydown', (event) => {
if (event.key === 'ArrowLeft') {
cylinderRotationY += rotationSpeed; // 左キーで円筒のY軸回転を増加
} else if (event.key === 'ArrowRight') {
cylinderRotationY -= rotationSpeed; // 右キーで円筒のY軸回転を減少
} else if (event.key === 'ArrowUp') {
cylinderRotationX += rotationSpeed; // 上キーで円筒のX軸回転を増加
} else if (event.key === 'ArrowDown') {
cylinderRotationX -= rotationSpeed; // 下キーで円筒のX軸回転を減少
}
});
}
// アニメーションループ
function animate() {
requestAnimationFrame(animate); // フレームごとの再描画リクエスト
// 円筒のX軸とY軸を回転させる
cylinder.rotation.x = cylinderRotationX; // X軸回転角度を適用
cylinder.rotation.y = cylinderRotationY; // Y軸回転角度を適用
// シーンをカメラの視点でレンダリング
renderer.render(scene, camera);
}
// 初期化関数の実行
init();
</script>
</body>
</html>