ドラッグ&ドロップで .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と連携
なども可能です。必要なら一緒に作れます!