@realsee/five
Version:
Realsee Renderer SDK
222 lines (159 loc) • 7.15 kB
Markdown
# 相机动画 (Camera Animation)
- **Summary**: 介绍如何在 Five 中通过编程方式控制相机运动,包括旋转、位移、全景切换以及模态转换时的动画效果。
- **Schema**: `State` (状态), `MovePanoOptions` (移动参数)。
- **Concepts**: Pose (位姿), Animation Loop, Easing (缓动), Fly/Fade Effect。
- **Configuration**: `modeChangeDuration`, `movePanoOptions`。
- **Examples**: 旋转视角、切换全景点、模态切换动画。
## Schema
### MovePanoOptions
> **Definition**: [MovePanoOptions](../../five/types/movePanoOptions.d.ts)
点位移动参数配置。
```typescript
interface MovePanoOptions extends Partial<Omit<State, "offset" | 'distance' | 'mode'>> {
/** 动画效果: 'fly' | 'fade' | 'instant' ... */
effect?: MovePanoEffect;
/** 走点图片过度策略 */
effectEasing?: (progress: number) => number;
/**
* 运动耗时 (ms)
* - number: 固定时长
* - function: (distance, speed) => number 根据距离动态计算
*/
duration?: number | ((distance: number, speed: number) => number) | string | null;
/** 运动开始回调 */
moveStartCallback?: (toState: State) => void;
/** 运动结束回调 */
moveEndCallback?: (state: State) => void;
/** 运动被取消回调 */
moveCancelCallback?: () => void;
}
```
### MovePanoEffect
```typescript
type MovePanoEffect =
| "fly" // 通过相机移动方式变化 (默认)
| "instant" // 直接变化 (无动画)
| "fade" // 通过渐变方式变化
| "model"; // 通过过度到模型
```
## Core Methods (核心方法)
Five 提供了多种层级的 API 来控制相机动画。
### 1. setState
最通用的状态更新方法。可以通过修改 `longitude` / `latitude` (旋转) 或 `fov` (缩放) 来产生动画。
```typescript
five.setState(state: Partial<State>, immediately?: boolean): void
```
* `state`: 目标状态 (包含 mode, panoIndex, longitude, latitude, fov 等)。
* `immediately`: 是否立即跳转 (无动画)。默认为 `false` (有动画)。
### 2. moveToPano
专用于全景点位之间的切换。支持 "飞行" (Fly) 和 "渐变" (Fade) 两种效果。
```typescript
five.moveToPano(panoIndex: number, options?: MovePanoOptions): Promise<void>
```
* `options.effect`: 切换效果。`'fly'` (空间飞行) 或 `'fade'` (淡入淡出)。
* `options.duration`: 动画时长 (ms)。
* `options.moveEndCallback`: 动画结束回调。
### 3. changeMode
切换交互模式 (如从全景切换到模型鸟瞰)。
```typescript
five.changeMode(mode: Mode, options?, animationOptions?): Promise<void>
```
### 4. updateCamera
在不切换全景点位的情况下,将相机平滑动画到目标位姿。适用于"定点环顾"或"聚焦某个方向"等场景。
```typescript
five.updateCamera(pose: Partial<Pose>, duration: number, userAction?: boolean): Promise<void>
```
* `pose`: 目标位姿 (longitude, latitude, fov, offset, distance 等)。
* `duration`: 动画时长 (ms)。
* `userAction`: 是否标记为用户触发。
* **返回**: `Promise<void>`,动画完成时 resolve,被打断时 reject。
> 与 `setState` 的区别:`updateCamera` 返回 Promise,可以精确等待动画结束;`setState` 是 fire-and-forget 风格。
## Concepts
### Pose (位姿)
相机的状态主要由位姿描述:
* **Longitude (经度)**: 水平旋转角度 (0 - 2π)。
* **Latitude (纬度)**: 垂直旋转角度 (-π/2 - π/2)。
* **FOV (视场角)**: 相机可视范围角度。
### Animation Effects (动画效果)
* **Linear / Easing**: 大多数 `setState` 产生的旋转和缩放动画使用平滑的缓动函数 (Ease-in-out)。
* **Fly (飞行)**: 模拟真实空间中的移动,相机位置会发生物理位移。适用于 `Panorama` 模式下的点位切换。
* **Fade (渐变)**: 保持相机位置不变,通过透明度渐变切换场景。适用于距离较远或不通视的点位切换。
## Configuration
### Global Configuration (全局配置)
在 `new Five(config)` 初始化时可以设置全局动画参数:
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `modeChangeDuration` | `number` | `1000` | 模态切换 (如 Panorama -> Mapview) 的默认时长 (ms)。 |
### MovePanoOptions Configuration (移动参数)
调用 `five.moveToPano(index, options)` 时使用的配置参数:
| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `effect` | `MovePanoEffect` | `'fly'` | 动画效果。<br>`'fly'`: 空间移动(模拟行走);<br>`'fade'`: 淡入淡出(保持位置不变);<br>`'instant'`: 瞬间跳转。 |
| `duration` | `number` \| `Function` | - | 动画时长 (ms)。若不传,则根据距离和速度自动计算。 |
| `effectEasing` | `Function` | - | 自定义过渡效果的缓动函数。 |
| `moveEndCallback` | `Function` | - | 动画结束后的回调函数。 |
## Examples
### 1. 旋转视角 (Rotate Camera)
平滑旋转到指定角度。
```typescript
// 旋转到水平 0 度,垂直 0 度
five.setState({
longitude: 0,
latitude: 0
});
// 立即跳转 (无动画)
five.setState({ longitude: Math.PI }, true);
```
### 2. 切换全景点 (Change Pano)
模拟行走效果切换到下一个房间。
```typescript
// 飞向索引为 2 的全景点
five.moveToPano(2, {
effect: 'fly', // 飞行效果
duration: 1500, // 1.5秒
moveEndCallback: () => {
console.log("到达目的地");
}
});
```
### 3. 模态切换 (Change Mode)
从全景模式切换到户型图模式。
```typescript
// 切换到 Floorplan 模式
five.changeMode('Floorplan');
// 切换回 Panorama 模式,并指定进入时的视角
five.setState({
mode: 'Panorama',
panoIndex: 0,
longitude: Math.PI / 2
});
```
### 4. 自动巡更 (Auto Tour)
通过连续调用 `setState` 或 `moveToPano` 实现简单的自动导览。
```typescript
async function startTour() {
// 1. 先看天花板
five.setState({ latitude: Math.PI / 3 });
await wait(2000); // 等待动画完成
// 2. 移动到下一个点
await five.moveToPano(1, { effect: 'fly' });
// 3. 切换到模型鸟瞰
await five.changeMode('Mapview');
}
function wait(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
```
## Common Pitfalls
1. **并发调用**: 尽量避免在动画过程中再次调用 `setState`,这可能会打断当前动画或导致状态突变。建议使用 `Promise` 或回调等待动画结束。
3. **相机位姿**: 确保传入的 `longitude` / `latitude` 符合 Five 的坐标系定义 (Y-up, 右手系)。
## Related
* [Five](./five.md): Five 核心类及 `setState` 方法。
* [Mode](./mode.md): 各种交互模式说明。
* [State](./state.md): 状态对象的完整定义。
* [Move Pano Effect](./move-pano-effect.md): 全景点位切换的过渡效果配置。
* [Coordinate System](./coordinate-system.md): 坐标系定义,理解 longitude/latitude 的含义。
---
```yaml
tags: [巡航, 动画, 旋转, 缩放, 运镜, 导览, camera-animation, pose, state, auto-tour, fly-through, rotate, zoom, transition]
```