# 機能設計書 101-ImageLoader

## 概要

本ドキュメントは、Three.jsライブラリにおける画像ファイル読み込み機能「ImageLoader」の設計について記述する。ImageLoaderは、HTMLのImage APIを使用して画像ファイルを非同期で読み込むローダークラスである。

### 本機能の処理概要

**業務上の目的・背景**：3Dグラフィックスアプリケーションにおいて、テクスチャや背景画像として使用する画像ファイルを効率的に読み込む必要がある。ImageLoaderは、この基盤となる画像読み込み機能を提供し、TextureLoaderやCubeTextureLoaderなど上位のローダーから内部的に利用される重要なコンポーネントである。

**機能の利用シーン**：
- テクスチャ用画像ファイルの読み込み時
- 背景画像やスカイボックス用画像の読み込み時
- UIスプライト用画像の読み込み時
- Data URI形式の画像データの読み込み時

**主要な処理内容**：
1. URLまたはData URIから画像ファイルを非同期読み込み
2. 読み込み完了/エラー時のコールバック実行
3. Cacheシステムとの連携による重複読み込みの防止
4. LoadingManagerとの連携による進捗管理
5. CORS対応のためのcrossOrigin設定

**関連システム・外部連携**：
- Cacheモジュール: 読み込み済み画像のキャッシュ管理
- LoadingManager: 複数リソースの読み込み進捗管理
- TextureLoader: ImageLoaderを内部で使用するテクスチャローダー
- CubeTextureLoader: キューブマップ用テクスチャローダー

**権限による制御**：特になし（ブラウザのセキュリティポリシーに依存）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接関連する画面なし（内部ユーティリティクラス） |

## 機能種別

データ読み込み / リソースローダー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| url | string | Yes | 読み込む画像のパス/URL（Data URIも可） | なし |
| onLoad | function(Image) | No | 読み込み完了時のコールバック | なし |
| onProgress | function | No | 進捗コールバック（このローダーでは未サポート） | なし |
| onError | function | No | エラー発生時のコールバック | なし |
| manager | LoadingManager | No | ローディングマネージャー | なし |

### 入力データソース

- ローカルファイルシステム上の画像ファイル
- リモートサーバー上の画像ファイル（URL指定）
- Data URI形式の埋め込み画像データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| image | HTMLImageElement | 読み込まれた画像要素 |

### 出力先

- onLoadコールバック関数への引数として渡される
- load()メソッドの戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. load()メソッド呼び出し
   └─ URLの解決（path接頭辞の付与、manager.resolveURL()適用）
2. キャッシュチェック
   └─ Cache.get()で既存エントリを確認
3-a. キャッシュヒット時
   └─ 完了済みなら即座にonLoadコールバック実行（非同期）
   └─ 読み込み中なら_loadingマップに追加
3-b. キャッシュミス時
   └─ 新規HTMLImageElement作成
   └─ load/errorイベントリスナー設定
   └─ CORS設定（Data URIでない場合）
   └─ Cacheに追加
   └─ image.srcにURL設定（読み込み開始）
4. 読み込み完了時
   └─ イベントリスナー削除
   └─ onLoadコールバック実行
   └─ 待機中コールバックの実行
   └─ manager.itemEnd()呼び出し
5. エラー時
   └─ イベントリスナー削除
   └─ onErrorコールバック実行
   └─ Cacheからエントリ削除
   └─ manager.itemError()/itemEnd()呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[load開始] --> B[URL解決]
    B --> C{キャッシュ確認}
    C -->|ヒット| D{読み込み完了?}
    D -->|Yes| E[onLoadコールバック実行]
    D -->|No| F[待機リストに追加]
    C -->|ミス| G[Image要素作成]
    G --> H[イベントリスナー設定]
    H --> I{Data URI?}
    I -->|No| J[CORS設定]
    I -->|Yes| K[Cacheに追加]
    J --> K
    K --> L[image.src設定]
    L --> M{読み込み結果}
    M -->|成功| N[onLoad実行・待機コールバック実行]
    M -->|失敗| O[onError実行・Cache削除]
    N --> P[終了]
    O --> P
    E --> P
    F --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-101 | キャッシュ活用 | 同一URLの画像は再読み込みせずキャッシュを使用 | Cache.enabled = trueの場合 |
| BR-102 | 重複リクエスト抑制 | 同一URLへの同時リクエストは1つにまとめる | 読み込み中のURLに対する新規リクエスト時 |
| BR-103 | CORS設定 | Data URI以外の場合はcrossOrigin属性を設定 | url.slice(0,5) !== 'data:'の場合 |

### 計算ロジック

特になし

## データベース操作仕様

該当なし（ファイル読み込み機能のため）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 画像読み込みエラー | ネットワークエラー、ファイル不存在、CORS違反等 | onErrorコールバック実行、Cacheからエントリ削除 |

### リトライ仕様

自動リトライ機能なし（アプリケーション側で実装が必要）

## トランザクション仕様

該当なし

## パフォーマンス要件

- キャッシュ機構により同一画像の重複読み込みを防止
- WeakMapを使用した_loadingマップによるメモリ効率化

## セキュリティ考慮事項

- CORS（Cross-Origin Resource Sharing）に対応
- crossOrigin属性のデフォルト値は'anonymous'
- Data URIの場合はCORS設定をスキップ

## 備考

- r84以降、プログレスイベントのサポートは廃止されている
- loadAsync()メソッドによるPromiseベースの読み込みも可能（Loaderクラスから継承）

---

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

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

### 推奨読解順序

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

まず、ImageLoaderが使用するキャッシュ機構と内部状態管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Cache.js | `src/loaders/Cache.js` | グローバルキャッシュオブジェクトの構造（enabled, files, add, get, remove, clear） |

**読解のコツ**: Cacheはシングルトンオブジェクトとして実装されており、enabledフラグでキャッシュ機能のオン/オフを制御している。

#### Step 2: 基底クラスを理解する

ImageLoaderが継承するLoaderクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Loader.js | `src/loaders/Loader.js` | 基底クラスのプロパティ（manager, crossOrigin, path等）とメソッド（loadAsync, setCrossOrigin等） |

**主要処理フロー**:
- **15-70行目**: コンストラクタでの初期化（manager, crossOrigin, withCredentials, path, resourcePath, requestHeader）
- **91-101行目**: loadAsync()によるPromiseラッパーの実装

#### Step 3: ImageLoaderの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ImageLoader.js | `src/loaders/ImageLoader.js` | load()メソッドの実装、キャッシュチェック、イベントハンドリング |

**主要処理フロー**:
- **5行目**: _loadingはWeakMapで読み込み中の画像と待機コールバックを管理
- **47-49行目**: URLの解決処理（path接頭辞とmanager.resolveURL()）
- **53-86行目**: キャッシュチェックと既存画像の再利用
- **88行目**: createElementNS()でimg要素を作成
- **90-111行目**: onImageLoad関数 - 成功時の処理
- **113-138行目**: onImageError関数 - エラー時の処理
- **147-148行目**: イベントリスナーの設定
- **150-154行目**: CORS設定（Data URI以外の場合）
- **156-159行目**: キャッシュ追加と読み込み開始

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

```
ImageLoader.load(url, onLoad, onProgress, onError)
    │
    ├─ this.manager.resolveURL(url)
    │
    ├─ Cache.get(`image:${url}`)
    │      └─ キャッシュヒット時は即座にonLoad実行
    │
    ├─ createElementNS('img')
    │
    ├─ image.addEventListener('load', onImageLoad)
    │      └─ onLoad(image)
    │      └─ _loadingの待機コールバック実行
    │      └─ this.manager.itemEnd(url)
    │
    ├─ image.addEventListener('error', onImageError)
    │      └─ onError(event)
    │      └─ Cache.remove(`image:${url}`)
    │      └─ this.manager.itemError(url)
    │      └─ this.manager.itemEnd(url)
    │
    ├─ Cache.add(`image:${url}`, image)
    │
    └─ image.src = url
```

### データフロー図

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

URL/Data URI ──▶ ImageLoader.load() ──▶ HTMLImageElement
                       │
                       ├── Cache (キャッシュ確認/保存)
                       │
                       ├── LoadingManager (進捗管理)
                       │
                       └── _loading WeakMap (重複リクエスト管理)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ImageLoader.js | `src/loaders/ImageLoader.js` | ソース | 画像ローダー本体 |
| Loader.js | `src/loaders/Loader.js` | ソース | ローダー基底クラス |
| Cache.js | `src/loaders/Cache.js` | ソース | キャッシュ管理 |
| LoadingManager.js | `src/loaders/LoadingManager.js` | ソース | 読み込み進捗管理 |
| utils.js | `src/utils.js` | ソース | createElementNS関数提供 |
