# 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

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

    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
`textureOptions` | `TextureOptions` | `{}` | 贴图加载策略，同上
`onlyRenderIfNeeds` | `boolean` | `true` | 是否仅在需要时渲染，建议保持 `true`
`antialias` | `boolean` | `false` | 抗锯齿，开启会增加性能消耗
`modeChangeDuration` | `number` | `1000` | 模式切换动画时长 (ms)
`enableWheel` | `boolean` | `true` | 是否支持滚轮缩放

## Examples

### 快速上手 (Quick Example)

创建一个全屏的 Five 实例并加载数据。

    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);

### 进阶用法：自定义渲染器与视口

使用外部渲染器并指定视口区域（例如用于分屏渲染）。

    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` 实现平滑的视角漫游。

    // 简单移动到指定视角
    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。
- `works`: 当前加载的所有 Work 数据列表。详见 Work。
- `model`: 当前加载的 Model 数据（主 Model）。详见 Model。
- `models`: 当前加载的所有 Model 数据列表。详见 Model。

### 实例方法 (Instance Methods)

- `appendTo(element: HTMLElement)`: 将 canvas 挂载到指定 DOM 元素。
- `load(work: Work, state?: State, duration?: number)`: 加载场景数据。详见 Work。
- `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。
- `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。
- `on(event, callback)` / `off(event, callback)`: 事件监听。详见 Event。

## Related

- Work: Work 数据结构说明。
- Model: Model 数据结构说明。
- State: 状态管理详解。
- Event: 事件系统说明。
- Image Options: 图片加载配置。
- Mode: 模态切换说明。
- Parameter: 其他核心参数。

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