ドラッグ&ドロップで .glb
ファイルをアップロードし、サーバーに保存してから A-Frame で表示する構成 を作成します。
目次
✅ 完成イメージ
- ユーザーが
.glb
ファイルをドラッグ&ドロップ - JavaScript がファイルを PHP にアップロード
- アップロード完了後、自動的に
view.php
に遷移して表示
📁 ディレクトリ構成(例)
/your-project/ ├── index.html ← ドラッグ&ドロップ画面 ├── upload.php ← アップロード処理(PHP) ├── view.php ← A-Frame で表示するページ └── uploads/ ← アップロード先フォルダ
① index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>GLBドラッグ&ドロップ</title> <style> #drop-area { border: 2px dashed #aaa; border-radius: 10px; width: 100%; max-width: 400px; margin: 50px auto; padding: 30px; text-align: center; font-family: sans-serif; color: #555; } #drop-area.hover { border-color: #333; background-color: #f0f0f0; } </style> </head> <body> <div id="drop-area"> <p>ここに .glb ファイルを<br>ドラッグ&ドロップ</p> <div id="file-list"></div> </div> <script> const dropArea = document.getElementById('drop-area'); const fileList = document.getElementById('file-list'); // イベント処理 ['dragenter', 'dragover'].forEach(eventName => { dropArea.addEventListener(eventName, (e) => { e.preventDefault(); e.stopPropagation(); dropArea.classList.add('hover'); }, false); }); ['dragleave', 'drop'].forEach(eventName => { dropArea.addEventListener(eventName, (e) => { e.preventDefault(); e.stopPropagation(); dropArea.classList.remove('hover'); }, false); }); dropArea.addEventListener('drop', (e) => { const file = e.dataTransfer.files[0]; if (file && file.name.endsWith('.glb')) { uploadFile(file); } else { fileList.innerHTML = '<p style="color:red;">.glbファイルのみアップロード可能です。</p>'; } }); function uploadFile(file) { const formData = new FormData(); formData.append('glbfile', file); fetch('upload.php', { method: 'POST', body: formData }) .then(res => res.text()) .then(response => { if (response.startsWith('OK:')) { const filename = response.replace('OK:', '').trim(); window.location.href = `view.php?file=${encodeURIComponent(filename)}`; } else { fileList.innerHTML = `<p style="color:red;">${response}</p>`; } }) .catch(() => { fileList.innerHTML = '<p style="color:red;">アップロードエラーが発生しました。</p>'; }); } </script> </body> </html>
② upload.php
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['glbfile'])) { $uploadDir = 'uploads/'; $file = $_FILES['glbfile']; $filename = basename($file['name']); // セキュリティチェック if (!preg_match('/\.glb$/i', $filename)) { echo "エラー: .glbファイルのみ許可されています。"; exit; } if (!is_dir($uploadDir)) { mkdir($uploadDir, 0777, true); } $targetFile = $uploadDir . uniqid() . '_' . $filename; if (move_uploaded_file($file['tmp_name'], $targetFile)) { echo "OK:" . basename($targetFile); } else { echo "ファイルの保存に失敗しました。"; } } else { echo "不正なリクエストです。"; } ?>
③ view.php
<?php $filename = isset($_GET['file']) ? $_GET['file'] : ''; $filepath = 'uploads/' . $filename; if (!preg_match('/^[\w\-\.]+\.glb$/', $filename) || !file_exists($filepath)) { die('ファイルが見つかりません。'); } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title><?= htmlspecialchars($filename) ?> を表示</title> <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script> </head> <body> <h2>アップロードされたGLBを表示</h2> <a-scene background="color: #ECECEC"> <a-assets> <a-asset-item id="model" src="<?= htmlspecialchars($filepath) ?>"></a-asset-item> </a-assets> <a-entity gltf-model="#model" position="0 1.6 -2" rotation="0 45 0"></a-entity> <a-light type="ambient" color="#fff"></a-light> <a-light type="directional" position="1 2 1" intensity="0.5"></a-light> <a-camera position="0 1.6 0"></a-camera> </a-scene> <p><a href="index.html">戻る</a></p> </body> </html>
✅ ポイント
.glb
のみ許可- ファイル名をユニークにすることで重複回避
- サーバー上に保存されたファイルを A-Frame で読み込み
もっと進化させてみたい場合:
- サムネイル表示
- 複数ファイルアップロード
- ファイル削除機能
- DBと連携
なども可能です。必要なら一緒に作れます!