# 画面設計書 30-SVGサンプル

## 概要

本ドキュメントは、three.js Examples における SVG レンダラーを使用したサンプル群（2件）の画面設計書である。3D シーンを SVG 形式でベクターグラフィックスとしてレンダリングする SVGRenderer のデモンストレーションを提供する。

### 本画面の処理概要

SVGサンプル画面は、three.js の SVGRenderer を使用して 3D シーンを SVG（Scalable Vector Graphics）形式で描画するサンプル集である。WebGL を使用せず、DOM ベースの SVG 要素として 3D グラフィックスをレンダリングする。Projector クラスを使用して 3D ジオメトリを 2D に投影し、SVG の path 要素として出力する。

**業務上の目的・背景**：ベクターグラフィックスとして 3D シーンを描画したい場合に使用する。解像度に依存しないクリアな出力が可能で、印刷品質が高い。アニメーションロゴ、インタラクティブな図表、地図、UI などに適している。ただし、テクスチャ、シャドウ、高度なシェーディングには対応していない。

**画面へのアクセス方法**：
1. examples/index.html にアクセス
2. 左側パネルの「svg」カテゴリを選択
3. 目的のサンプル（svg_lines または svg_sandbox）を選択

**主要な操作・処理内容**：
1. SVGRenderer の初期化と DOM への追加
2. 3D オブジェクト（メッシュ、ライン、スプライト）の作成
3. SVGObject によるカスタム SVG 要素の追加
4. レンダリングループでの SVG 更新

**画面遷移**：
- 遷移元：Examples一覧画面（examples/index.html）
- 遷移先：なし（各サンプルは独立して動作）
- GitHub ソースコードページへの外部リンクあり

**権限による表示制御**：なし（パブリックアクセス）

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Object3D | 主機能 | 3Dオブジェクトの配置管理 |
| 19 | PerspectiveCamera | 補助機能 | カメラ設定 |
| 24 | Scene | 補助機能 | シーングラフ管理 |
| 7 | BufferGeometry | 補助機能 | ジオメトリデータ管理 |

## 画面種別

サンプル / デモンストレーション

## URL/ルーティング

- カテゴリ: `examples/index.html` (svg)
- 個別サンプル:
  - `examples/svg_lines.html` - ライン描画
  - `examples/svg_sandbox.html` - サンドボックス

## 入出力項目

| 項目名 | 入出力 | データ型 | 説明 |
|--------|--------|----------|------|
| 3D シーン | 入力 | Scene | レンダリング対象 |
| マウス操作 | 入力 | Event (mouse) | カメラ操作（sandbox のみ） |
| SVG 出力 | 出力 | SVG element | ベクターグラフィックス |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| SVG グラフィックス | SVG (DOM) | SVGRenderer による 2D ベクター表示 |
| 情報パネル | HTML div | サンプル説明（lines のみ） |
| Stats パネル | DOM | パフォーマンス表示（sandbox のみ） |

## イベント仕様

### 1-SVGRenderer 初期化

レンダラーの初期化と DOM への追加：
1. new SVGRenderer() でインスタンス作成
2. renderer.setSize() でサイズ設定
3. renderer.setQuality('low'|'high') で品質設定（オプション）
4. document.body.appendChild(renderer.domElement) で DOM に追加

### 2-3D オブジェクト作成

各種 3D オブジェクトを作成してシーンに追加：
1. Mesh - BoxGeometry, CylinderGeometry, PlaneGeometry 等
2. Line - LineBasicMaterial, LineDashedMaterial
3. Sprite - SpriteMaterial
4. SVGObject - カスタム SVG 要素をラップ

### 3-SVGObject によるカスタム要素

SVG 要素を 3D シーンに配置：
1. document.createElementNS('http://www.w3.org/2000/svg', 'circle') で SVG 要素作成
2. 属性（stroke, fill, r 等）を設定
3. new SVGObject(node) でラップ
4. object.position.set() で 3D 位置設定
5. scene.add(object) でシーンに追加

### 4-レンダリングループ

毎フレームの処理：
1. requestAnimationFrame(animate) でループ
2. オブジェクトの回転更新
3. controls.update()（使用時）
4. renderer.render(scene, camera) で SVG レンダリング

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

### 操作別データベース影響一覧

本画面はフロントエンドのみで動作するサンプルであり、データベースへのアクセスは行わない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベース操作なし |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|-----------|----------|
| エラー | THREE.SVGRenderer.render: camera is not an instance of Camera. | カメラが Camera インスタンスでない場合 |

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| SVG 非対応ブラウザ | 古いブラウザでは描画されない可能性 |
| 複雑なジオメトリ | パフォーマンス低下、overdraw 設定で調整 |
| テクスチャ使用 | SVGRenderer はテクスチャ非対応、色のみ |

## 備考

- SVGRenderer は WebGL を使用しないため、GPU 非依存
- ベクターグラフィックスのため解像度に依存しない高品質出力
- テクスチャ、シャドウ、高度なシェーディングは非対応
- SVGObject でカスタム SVG 要素を 3D 空間に配置可能
- Projector クラスで 3D → 2D 投影を行い、Painter's Algorithm でソート
- overdraw プロパティでアンチエイリアスギャップを調整可能
- setQuality('high'|'low') でレンダリング品質を設定

---

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

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

### 推奨読解順序

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

SVGRenderer と SVGObject の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SVGRenderer.js | `examples/jsm/renderers/SVGRenderer.js` | SVG レンダリングの実装 |
| 1-2 | Projector.js | `examples/jsm/renderers/Projector.js` | 3D → 2D 投影 |

**読解のコツ**: SVGRenderer は Projector を使用して 3D シーンを 2D に投影し、RenderableFace, RenderableLine, RenderableSprite として処理する。各要素は SVG の path 要素に変換される。SVGObject は Object3D を継承し、任意の SVG 要素をラップする。

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

svg_sandbox サンプルの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | svg_sandbox.html | `examples/svg_sandbox.html` | 複合的な SVG サンプル |
| 2-2 | svg_lines.html | `examples/svg_lines.html` | ライン描画サンプル |

**主要処理フロー（svg_sandbox.html）**:
1. **Line 26-31**: THREE, Stats, OrbitControls, SVGRenderer のインポート
2. **Line 42-46**: PerspectiveCamera の作成
3. **Line 47-48**: Scene の作成
4. **Line 52-59**: BufferGeometryLoader で QRCode モデル読み込み
5. **Line 63-93**: 各種 Mesh の作成（Box, Plane, Cylinder）
6. **Line 97-158**: BufferGeometry でランダム三角形を生成
7. **Line 162-172**: Sprite の作成
8. **Line 176-189**: SVGObject でカスタム circle 要素を追加
9. **Line 193-206**: FileLoader で外部 SVG ファイルを読み込み SVGObject として追加
10. **Line 210-215**: ライトの追加
11. **Line 217-220**: SVGRenderer の作成と設定
12. **Line 222-226**: OrbitControls と Stats の設定
13. **Line 245-261**: animate() と render() 関数

**主要処理フロー（svg_lines.html）**:
1. **Line 31-33**: THREE, SVGRenderer のインポート
2. **Line 42-52**: PerspectiveCamera, Scene, SVGRenderer の作成
3. **Line 56-68**: 円形の頂点配列を生成
4. **Line 70-71**: BufferGeometry を作成
5. **Line 75-85**: LineBasicMaterial でラインを作成（3本）
6. **Line 87-95**: LineDashedMaterial で破線ラインを作成
7. **Line 112-129**: animate() でラインを回転させてレンダリング

#### Step 3: SVGRenderer の内部構造を理解する

レンダリング処理の詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SVGRenderer.js | `examples/jsm/renderers/SVGRenderer.js` (Line 77-188) | プロパティと設定 |
| 3-2 | SVGRenderer.js | `examples/jsm/renderers/SVGRenderer.js` (Line 342-508) | render() メソッド |

**主要処理フロー**:
- autoClear, sortObjects, sortElements プロパティで動作制御
- overdraw プロパティでアンチエイリアスギャップを調整
- setQuality() で shape-rendering 属性を設定
- render() で Projector.projectScene() を呼び出し
- RenderableFace, RenderableLine, RenderableSprite を処理
- SVGObject は traverseVisible() で検出して変換

#### Step 4: SVGObject を理解する

カスタム SVG 要素の配置方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SVGRenderer.js | `examples/jsm/renderers/SVGRenderer.js` (Line 25-54) | SVGObject クラス |
| 4-2 | svg_sandbox.html | `examples/svg_sandbox.html` (Line 176-206) | SVGObject の使用例 |

**主要処理フロー**:
- SVGObject は Object3D を継承
- node プロパティに SVG 要素を保持
- render() 時に 3D 位置をスクリーン座標に変換
- node に translate 変換を適用して配置

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

```
svg_sandbox.html (エントリーポイント)
    |
    +-- init()
    |      |
    |      +-- THREE.PerspectiveCamera()
    |      +-- THREE.Scene()
    |      |
    |      +-- THREE.BufferGeometryLoader()
    |      |      +-- loader.load('QRCode_buffergeometry.json')
    |      |
    |      +-- [各種 Mesh の作成]
    |      |      +-- THREE.BoxGeometry()
    |      |      +-- THREE.PlaneGeometry()
    |      |      +-- THREE.CylinderGeometry()
    |      |      +-- THREE.BufferGeometry()
    |      |
    |      +-- [Sprite の作成]
    |      |      +-- THREE.SpriteMaterial()
    |      |      +-- THREE.Sprite()
    |      |
    |      +-- [SVGObject の作成]
    |      |      +-- document.createElementNS('svg', 'circle')
    |      |      +-- new SVGObject(node)
    |      |      +-- scene.add(object)
    |      |
    |      +-- THREE.FileLoader()
    |      |      +-- fileLoader.load('hexagon.svg')
    |      |      +-- new SVGObject(node)
    |      |
    |      +-- THREE.AmbientLight()
    |      +-- THREE.DirectionalLight()
    |      |
    |      +-- SVGRenderer()
    |      |      +-- setSize()
    |      |      +-- setQuality('low')
    |      |      +-- document.body.appendChild()
    |      |
    |      +-- OrbitControls()
    |      +-- Stats()
    |
    +-- animate()
           +-- requestAnimationFrame(animate)
           +-- render()
                  +-- group.rotation.x += 0.01
                  +-- controls.update()
                  +-- renderer.render(scene, camera)
                         +-- Projector.projectScene()
                         +-- calculateLights()
                         +-- renderSprite() / renderLine() / renderFace3()
                         +-- flushPath()
```

### データフロー図

```
[SVG レンダリングのデータフロー]

Scene (3D オブジェクト)
        |
        v
Projector.projectScene(scene, camera)
        |
        +-- RenderableFace (三角形)
        |      |
        |      +-- renderFace3()
        |             +-- path = 'M...L...L...z'
        |             +-- style = 'fill:...'
        |
        +-- RenderableLine (線分)
        |      |
        |      +-- renderLine()
        |             +-- path = 'M...L...'
        |             +-- style = 'stroke:...'
        |
        +-- RenderableSprite (スプライト)
               |
               +-- renderSprite()
                      +-- path = 'M...h...v...h...z'
                      +-- style = 'fill:...'
                              |
                              v
                    addPath(style, path)
                              |
                              v
                    flushPath()
                              |
                              v
                    <path d="..." style="..."/>
                              |
                              v
                    SVG DOM に追加


[SVGObject のデータフロー]

SVGObject (node: SVG 要素)
        |
        +-- position (3D ワールド座標)
        |
        v
scene.traverseVisible()
        |
        v
vector3.setFromMatrixPosition(object.matrixWorld)
vector3.applyMatrix4(viewProjectionMatrix)
        |
        v
スクリーン座標 (x, y, z)
        |
        v
node.setAttribute('transform', 'translate(x, y)')
        |
        v
SVG DOM に追加
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SVGRenderer.js | `examples/jsm/renderers/SVGRenderer.js` | ソース | SVG レンダラー |
| Projector.js | `examples/jsm/renderers/Projector.js` | ソース | 3D → 2D 投影 |
| OrbitControls.js | `examples/jsm/controls/OrbitControls.js` | ソース | カメラコントロール |
| stats.module.js | `examples/jsm/libs/stats.module.js` | ソース | パフォーマンス表示 |
| svg_sandbox.html | `examples/svg_sandbox.html` | テンプレート | サンドボックスサンプル |
| svg_lines.html | `examples/svg_lines.html` | テンプレート | ライン描画サンプル |
| QRCode_buffergeometry.json | `examples/models/json/QRCode_buffergeometry.json` | リソース | QRコードモデル |
| hexagon.svg | `examples/models/svg/hexagon.svg` | リソース | 六角形 SVG |
