# Five (Five 核心类)

- **Summary**: Five 是 @realsee/five 的核心类，负责 3D 场景的渲染、资源加载、用户交互和状态管理。
- **Schema**: FiveInitArgs 初始化参数接口。
- **Concepts**: Instance Management, Rendering Loop, Resource Loading, State Sync.
- **Configuration**: Five 初始化参数详解。
- **Examples**: 基础初始化、加载数据、销毁实例。

## Schema

### FiveInitArgs

> **Definition**: [FiveInitArgs](../../five/application/fiveInitArgs.d.ts)

`new Five(args)` 的初始化参数对象。

```typescript
interface FiveInitArgs {
  /** 外部传入的渲染器 (如果传入，部分渲染配置将失效) */
  renderer?: THREE.WebGLRenderer;
  /**
   * 屏幕渲染区域 { left, bottom, width, height }
   * 必须配合外部 renderer 使用
   */
  viewport?: Viewport;
  /** 背景颜色 (默认 0x181A1C) */
  backgroundColor?: number | THREE.Color;
  /** 背景透明度 (0-1, 默认 1) */
  backgroundAlpha?: number;
  /** 是否开启抗锯齿 (默认 false) */
  antialias?: boolean;
  /** 全景图配置 (见 image-options.md) */
  imageOptions?: ImageOptions;
  /** 贴图配置 (见 image-options.md) */
  textureOptions?: TextureOptions;
  /** 是否按需渲染 (默认 true, 推荐开启以节省性能) */
  onlyRenderIfNeeds?: boolean;
  /** 模式切换动画时长 (ms, 默认 1000) */
  modeChangeDuration?: number;
  /** 是否支持滚轮缩放 (默认 true) */
  enableWheel?: boolean;
  /** 插件列表 */
  plugins?: FivePlugin[];
  /** 是否显示 Powered by Realsee */
  poweredByRealsee?: boolean;
}
```

## Concepts

### Instance Management (实例管理)
Five 实例是整个 3D 场景的入口。
- **Singleton-like**: 虽然支持多实例，但在同一个 DOM 容器中通常只维护一个 Five 实例。
- **Lifecycle**: 包含 `appendTo` (挂载)、`load` (加载数据)、`dispose` (销毁) 等生命周期方法。

### Rendering Loop (渲染循环)
Five 内部维护了一个 `requestAnimationFrame` 循环。
- **按需渲染**: 默认开启 `onlyRenderIfNeeds`，仅在画面发生变化（如视角移动、数据加载）时才触发 WebGL 绘制，大幅降低能耗。
- **手动触发**: 可以通过 `five.needsRender = true` 强制下一帧进行渲染。

### Resource Loading (资源加载)
通过 `load()` 方法加载 Work 数据。
- **数据解析**: 自动解析 Work 数据结构，生成场景图。
- **预加载**: 支持配置预加载策略，平衡首屏速度与流量。

## Configuration

| 参数 | 类型 | 默认值 | 说明 |
| :--- | :--- | :--- | :--- |
| `imageOptions` | `ImageOptions` | `{}` | 图片加载策略，详见 [Image Options](./image-options.md) |
| `textureOptions` | `TextureOptions` | `{}` | 贴图加载策略，同上 |
| `onlyRenderIfNeeds` | `boolean` | `true` | 是否仅在需要时渲染，建议保持 `true` |
| `antialias` | `boolean` | `false` | 抗锯齿，开启会增加性能消耗 |
| `modeChangeDuration` | `number` | `1000` | 模式切换动画时长 (ms) |
| `enableWheel` | `boolean` | `true` | 是否支持滚轮缩放 |

## Examples

### 快速上手 (Quick Example)
创建一个全屏的 Five 实例并加载数据。

```typescript
import { Five, parseWork } from "@realsee/five";

// 1. 初始化实例
const five = new Five({
  imageOptions: { size: 512 }, // 初始加载小图
  onlyRenderIfNeeds: true
});

// 2. 挂载到 DOM
five.appendTo(document.getElementById("app"));

// 3. 加载数据
// workData 通常来自服务端 API
five.load(workData);
```

### 进阶用法：自定义渲染器与视口
使用外部渲染器并指定视口区域（例如用于分屏渲染）。

```typescript
import * as THREE from "three";
import { Five } from "@realsee/five";

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const five = new Five({
  renderer: renderer,
  viewport: { left: 0, bottom: 0, width: 0.5, height: 1 } // 仅占用左半屏
});

five.load(workData);
```

### 进阶用法：自定义相机动画

使用 `updateCamera` 或 `updateCameraWithKeyframes` 实现平滑的视角漫游。

```typescript
// 简单移动到指定视角
five.updateCamera(
  { longitude: Math.PI / 2, latitude: 0 }, // 目标姿态
  1000 // 动画时长 1秒
).then(() => {
  console.log("移动完成");
}).catch(() => {
  console.log("移动被打断");
});

// 复杂关键帧动画
const keyframes = [
  { progress: 0, value: { longitude: 0, latitude: 0 } },
  { progress: 0.5, value: { longitude: Math.PI / 4, latitude: 0.2 } },
  { progress: 1, value: { longitude: Math.PI / 2, latitude: 0 } }
];

five.updateCameraWithKeyframes(keyframes, 2000).then(() => {
  console.log("关键帧动画完成");
});
```

### 实例属性 (Instance Properties)

- **`work`**: 当前加载的 Work 数据（主 Work）。详见 [Work](./work.md)。
- **`works`**: 当前加载的所有 Work 数据列表。详见 [Work](./work.md)。
- **`model`**: 当前加载的 Model 数据（主 Model）。详见 [Model](./model.md)。
- **`models`**: 当前加载的所有 Model 数据列表。详见 [Model](./model.md)。

### 实例方法 (Instance Methods)

- **`appendTo(element: HTMLElement)`**: 将 canvas 挂载到指定 DOM 元素。
- **`load(work: Work, state?: State, duration?: number)`**: 加载场景数据。详见 [Work](./work.md)。
- **`dispose()`**: 销毁实例，释放 WebGL 上下文与内存。
- **`updateCamera(pose: Partial<Pose>, duration: number, userAction?: boolean)`**: 移动相机（不触发点位移动）。移动相机的视角或位置，不会改变当前所在的 PanoIndex。如果动画中途被打断，Promise 会被 reject。
- **`updateCameraWithKeyframes(keyframes: { progress: number; value: Pose; key?: string }[], duration: number, userAction?: boolean)`**: 通过关键帧动画移动相机。
- **`refresh()`**: 强制刷新画布尺寸。通常在窗口 resize 时调用，Five 会自动监听 resize，但在某些布局变化场景下可能需要手动调用。
- **`getPixels(x, y, width, height, ...)` / `getPixels(options)`**: 获取画布指定区域的像素数据。常用于截图、生成缩略图或颜色拾取。支持配置区域、像素比 (pixelRatio)、Y轴翻转 (flipY) 及是否忽略全景图 (skipPanorama) 等。
- **`project2d(vector: THREE.Vector3, testModel?: boolean): THREE.Vector2 | null`**: 计算三维坐标对应到屏幕的二维坐标。如果坐标在视野外或被遮挡（开启 testModel 时），返回 null。详见 [Screen Project](./screen-project.md)。
- **`ready(args?: { tile?: boolean })`**: Promise，当 Five 状态稳定时 resolve。
  - **Resolve 时机**：
    1. **状态同步**：相机姿态已通过动画过渡到目标状态（`stateSynced` 为 true）。
    2. **模型加载**：如果是 Floorplan/Topview/Mapview/Model 模态，需等待模型加载完成 (`modelScene.loaded`)。
    3. **瓦片加载**：如果是 Panorama 模态且传入了 `{ tile: true }`，需等待当前视角的瓦片加载完成。
- **`setState(state: Partial<State>, options?: ChangeStateOptions)`**: 变更当前状态（如点位、视角）。详见 [State](./state.md)。
- **`on(event, callback)` / `off(event, callback)`**: 事件监听。详见 [Event](./event.md)。

## Related

*   [Work](./work.md): Work 数据结构说明。
*   [Model](./model.md): Model 数据结构说明。
*   [State](./state.md): 状态管理详解。
*   [Event](./event.md): 事件系统说明。
*   [Image Options](./image-options.md): 图片加载配置。
*   [Mode](./mode.md): 模态切换说明。
*   [Parameter](./parameter.md): 其他核心参数。

---

```yaml
tags: [初始化, 创建实例, 渲染器, 销毁, 入口, 构造函数, five, initialization, core, instance, lifecycle, canvas, appendTo, dispose]
```
