# 画面設計書 39-スタンドアロンアプリ

## 概要

本ドキュメントは、three.jsエディタからエクスポートされるスタンドアロンアプリケーションのテンプレート（editor/js/libs/app/index.html）の設計書である。エディタで作成した3Dシーンを独立したWebアプリケーションとして公開するための基盤を提供する。

### 本画面の処理概要

このテンプレートは、three.jsエディタで作成・編集した3DシーンをスタンドアロンのWebアプリケーションとして動作させるための最小構成を提供する。エクスポートされたapp.jsonファイルを読み込み、APP.Playerクラスでシーンを再生する。

**業務上の目的・背景**：three.jsエディタで作成した3Dコンテンツを、技術的な知識がないエンドユーザーに配布・公開するためのパッケージングソリューションを提供する。エクスポートされたアプリは、Webサーバーにデプロイするだけで動作し、three.jsの知識がなくても閲覧できる。これにより、3Dコンテンツの制作から配布までのワークフローを完結させることができる。

**画面へのアクセス方法**：three.jsエディタの「File > Publish」メニューからエクスポートし、出力されたフォルダをWebサーバーにデプロイしてアクセス。

**主要な操作・処理内容**：
1. app.jsonファイルの読み込み
2. APP.Playerクラスのインスタンス化
3. シーンデータのロードとパース
4. レンダラーサイズの設定
5. シーンの再生開始
6. ウィンドウリサイズへの対応

**画面遷移**：単一ページアプリケーションとして動作。外部遷移なし。

**権限による表示制御**：app.json内のスクリプトで実装可能。デフォルトでは認証なし。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | WebGLRenderer | 主機能 | エクスポートアプリのレンダリング |
| 110 | AnimationMixer | 補助機能 | アニメーション再生 |
| 24 | Scene | 主機能 | シーンデータの管理 |
| 19 | PerspectiveCamera | 補助機能 | カメラ制御 |

## 画面種別

スタンドアロンアプリケーション（公開用3Dビューア）

## URL/ルーティング

- デフォルト: `index.html`
- エクスポート時にカスタマイズ可能

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| app.json | 入力 | JSON | シーンデータ、スクリプト、設定 |
| ウィンドウサイズ | 入力 | Number | ブラウザのビューポートサイズ |
| 3Dレンダリング | 出力 | Canvas | シーンの描画 |

### app.json構造

```json
{
  "metadata": {
    "version": 4.5,
    "type": "App"
  },
  "project": {
    "shadows": true,
    "shadowType": 1,
    "toneMapping": 0,
    "toneMappingExposure": 1
  },
  "camera": { /* カメラオブジェクト */ },
  "scene": { /* シーングラフ */ },
  "scripts": { /* オブジェクト別スクリプト */ }
}
```

## 表示項目

| 表示項目 | 説明 |
|----------|------|
| 3Dシーン | エディタで作成したシーンのレンダリング |
| （オプション）UI要素 | スクリプトで追加されたUI |

## イベント仕様

### 1-ページロード

**トリガー**: DOMContentLoaded / module実行
**処理内容**:
1. FileLoaderでapp.jsonを読み込み
2. JSON.parse()でオブジェクトに変換
3. new APP.Player()でプレイヤーインスタンス生成
4. player.load(json)でシーンをロード（async）
5. player.setSize()でサイズ設定
6. player.play()で再生開始
7. document.body.appendChild(player.dom)でDOM追加

### 2-ウィンドウリサイズ

**トリガー**: window resize イベント
**処理内容**:
1. player.setSize(window.innerWidth, window.innerHeight)
2. 内部でカメラアスペクト比とレンダラーサイズを更新

### 3-スクリプトイベント（オプション）

**トリガー**: app.json内のスクリプト定義に依存
**処理内容**:
- update: 毎フレーム実行
- keydown/keyup: キーボードイベント
- pointerdown/pointerup/pointermove: ポインターイベント

## データベース更新仕様

該当なし（クライアントサイドのみで動作）

## メッセージ仕様

特になし（app.json内のスクリプトでカスタマイズ可能）

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| app.json読み込み失敗 | 空白画面（エラーハンドリングなし） |
| WebGL非対応ブラウザ | three.jsのデフォルトエラー |
| 不正なJSONフォーマット | JSON.parse例外（未キャッチ） |

## 備考

- Import Mapを使用してthree.jsとthree/webgpuをインポート
- window.THREE = THREE でグローバルにthree.jsを公開（スクリプト用）
- APP.Playerはeditor/js/libs/app/js/app.jsで定義
- WebGPUレンダラーにも対応（three/webgpuインポート）
- ontouchstart="" 属性でiOSのタッチイベント対応
- エディタからのエクスポート時にtitleタグが設定される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

app.jsonのフォーマットとAPP.Playerの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.html | `editor/js/libs/app/index.html` | Import Mapとモジュール構成 |

**読解のコツ**: Import Mapでthreeとthree/webgpuの2つをマッピング。APP.Playerがシーン再生の中心クラス。

#### Step 2: エントリーポイントを理解する

ページ初期化フローを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html | `editor/js/libs/app/index.html` | メインスクリプト（29-56行目） |

**主要処理フロー**:
1. **31行目**: import * as THREE from 'three'
2. **32行目**: import { APP } from './js/app.js'
3. **34行目**: window.THREE = THREE（グローバル公開）
4. **36行目**: new THREE.FileLoader()
5. **37行目**: loader.load('app.json', callback)
6. **39行目**: new APP.Player()
7. **40行目**: await player.load(JSON.parse(text))
8. **41行目**: player.setSize()
9. **42行目**: player.play()
10. **44行目**: document.body.appendChild(player.dom)
11. **46-50行目**: resizeイベントリスナー

#### Step 3: APP.Playerクラスを理解する

シーン再生の実装詳細を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | app.js | `editor/js/libs/app/js/app.js` | APP.Playerクラスの実装 |

**注意**: app.jsは存在しない可能性がある（テンプレートとしてエクスポート時に生成される場合）。エディタのPlayer.jsを参照。

### プログラム呼び出し階層図

```
index.html
    │
    ├─ import * as THREE from 'three'
    │
    ├─ import { APP } from './js/app.js'
    │
    ├─ window.THREE = THREE
    │
    ├─ new THREE.FileLoader()
    │      │
    │      └─ loader.load('app.json', callback)
    │             │
    │             ├─ JSON.parse(text)
    │             │
    │             └─ new APP.Player()
    │                    │
    │                    ├─ player.load(json)
    │                    │      ├─ シーンデータパース
    │                    │      ├─ カメラ設定
    │                    │      ├─ スクリプト初期化
    │                    │      └─ AnimationMixer設定
    │                    │
    │                    ├─ player.setSize()
    │                    │      ├─ renderer.setSize()
    │                    │      └─ camera.aspect更新
    │                    │
    │                    └─ player.play()
    │                           └─ requestAnimationFrame loop
    │
    └─ window.addEventListener('resize')
           └─ player.setSize()
```

### データフロー図

```
[入力]                     [処理]                         [出力]

app.json ────────────▶ FileLoader.load() ─────────────▶ JSONテキスト
                             │
                             └─ JSON.parse()
                                    │
                                    └─ APP.Player.load()
                                           │
                                           ├─ scene生成
                                           ├─ camera設定
                                           ├─ scripts初期化
                                           └─ animations設定

window.innerWidth ───▶ player.setSize() ──────────────▶ renderer/camera更新
window.innerHeight ──┘

player.play() ───────▶ requestAnimationFrame ─────────▶ レンダリングループ
                             │
                             ├─ scripts.update()
                             ├─ mixer.update()
                             └─ renderer.render()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html | `editor/js/libs/app/index.html` | テンプレート | スタンドアロンアプリのエントリーポイント |
| app.js | `editor/js/libs/app/js/app.js` | ソース | APP.Playerクラス（エクスポート時生成） |
| three.module.js | `js/three.module.js` | ライブラリ | three.jsコア（相対パス、エクスポート時コピー） |
| three.webgpu.js | `js/three.webgpu.js` | ライブラリ | WebGPU対応（相対パス、エクスポート時コピー） |
| app.json | `app.json` | データ | エクスポートされたシーンデータ |
| Player.js | `editor/js/Player.js` | ソース | エディタ内プレイヤー実装（参考） |
