UNPKG

@realsee/five

Version:

Realsee Renderer SDK

274 lines (207 loc) • 8.63 kB
# Events (事件系统) - **Summary**: Five 提供了一套基于发布/订阅模式的事件系统,用于监听用户交互、状态变更、数据加载及渲染生命周期。 - **Schema**: `on` / `once` / `off` 接口定义;`BaseEvent` / `BaseExtendableEvent` 事件对象。 - **Concepts**: Event 对象(`preventDefault` / `waitUntil`)、Gesture Events, State Events, Pano Events, Model Events, Lifecycle Events. - **Examples**: 监听全景移动、手势交互及状态变更;使用 `preventDefault` 拦截默认行为;使用 `waitUntil` 延迟点位切换。 ## Schema > **Definition**: [Five](../../five/application/five.d.ts), [EventTypes](../../five/application/events.d.ts) Five 实例提供了以下方法来管理事件监听: ### on 注册持久化事件监听器。 ```typescript five.on( name: string, callback: (...args: any[]) => void, once?: boolean ): () => void ``` - **name**: 事件名称(支持的事件见 Concepts)。 - **callback**: 事件触发时的回调函数。 - **once**: (可选) 是否仅执行一次,默认为 `false`。 - **返回**: 一个函数,调用该函数可取消当前监听。 ### once 注册一次性事件监听器(触发一次后自动销毁)。 ```typescript five.once( name: string, callback: (...args: any[]) => void ): () => void ``` ### off 取消事件监听。 ```typescript five.off( name?: string, callback?: (...args: any[]) => void ): void ``` - **name**: (可选) 若不传,则清空所有事件;若传,则取消指定类型的事件。 - **callback**: (可选) 若传,则仅取消该特定的回调函数;若不传,则取消该类型下的所有回调。 ## Event 对象 > **Definition**: [BaseEvent / BaseExtendableEvent](../../five/utils/event.d.ts) Five 中所有事件回调的参数都是一个 Event 对象,分为两种基础类型: ### BaseEvent 所有事件的基础接口,包含以下属性和方法: ```typescript interface BaseEvent { /** 事件类型名称 */ type: string; /** 事件触发时的时间戳 */ timeStamp: number; /** 阻止事件的默认行为 */ preventDefault(): void; /** 是否已调用过 preventDefault */ readonly defaultPrevented: boolean; } ``` ### BaseExtendableEvent 继承自 `BaseEvent`,额外提供 `waitUntil` 方法,用于在事件处理中插入异步等待逻辑: ```typescript interface BaseExtendableEvent extends BaseEvent { waitUntil(f: Promise<any>): void; } ``` 目前 `pano.prepare` 事件使用 `BaseExtendableEvent`(对应 `PanoPrepareEvent`),其余事件均基于 `BaseEvent`。 `PanoPrepareEvent` 额外包含以下属性: | 属性 | 类型 | 描述 | | :--- | :--- | :--- | | `options` | `MovePanoOptions` | 点位切换时的选项(如 `effect`、`duration`、`longitude`、`latitude`、`fov` 等)。**支持在回调中修改此对象**,修改后的值将影响实际的切换行为。 | | `prevMode` | `Mode` | 切换发生前的显示模式。 | | `prevPano` | `Pano` | 切换前的点位信息。 | | `pano` | `Pano` | 目标点位信息。 | ### preventDefault 调用 `event.preventDefault()` 可以阻止事件的默认行为。Five 内部会在触发事件后检查 `event.defaultPrevented`,若为 `true` 则跳过后续的默认处理逻辑。 比如: - `gesture.tap`:阻止默认的点位跳转或相机弹跳动画。 - `intersect.update`:阻止默认的交互高亮行为。 ```typescript // 示例:阻止点击时的默认点位跳转 five.on("gesture.tap", (event) => { if (shouldBlockNavigation()) { event.preventDefault(); // 执行自定义逻辑 showCustomMenu(event); } }); // 示例:阻止拖拽时的默认相机旋转 five.on("gesture.pan", (event) => { event.preventDefault(); // 用拖拽手势实现自定义交互(如绘制标注) drawAnnotation(event); }); ``` ### waitUntil `waitUntil(promise)` 仅在 `ExtendableEvent` 上可用。调用后,Five 会等待传入的 Promise 完成后再继续后续流程。可多次调用,所有 Promise 会被并行等待。 目前仅 `pano.prepare` 事件支持 `waitUntil`。 ```typescript // 示例:在切换点位前预加载资源 five.on("pano.prepare", (event) => { // event.pano 目标点位 // event.prevPano 切换前点位 // event.prevMode 切换前模式 // 等待自定义资源加载完成后再继续点位切换 event.waitUntil( loadCustomResources(event.pano) ); // 可以多次调用,所有 Promise 会被并行等待 event.waitUntil( preloadTextures(event.pano) ); }); // 示例:通过 waitUntil reject 来取消走点 five.on("pano.prepare", (event) => { event.waitUntil( showConfirmDialog("是否前往该点位?").then((confirmed) => { if (!confirmed) { throw new Error("用户取消走点"); } }) ); }); // 示例:修改 event.options 影响切换行为 five.on("pano.prepare", (event) => { // 修改切换动画效果为无动画 event.options.effect = "instant"; // 或修改切换后的相机朝向 event.options.longitude = Math.PI / 4; event.options.latitude = 0; event.options.fov = 90; // 注意:直接修改 event.options 属性即可,不需要重新赋值 event.options }); ``` > **注意**: `preventDefault` 和 `waitUntil` 必须在事件回调的同步执行阶段调用,不能放在 `await` 之后。 ## Concepts Five 的事件系统将事件主要分为以下几类: ### Gesture Events (交互手势) 监听用户的鼠标或触摸操作。 - `gesture.tap`: 点击/轻触。 - `gesture.dbltap`: 双击/双击轻触。 - `gesture.press`: 长按。 - `gesture.pan`: 平移/拖拽。 - `gesture.pinch`: 缩放(双指或滚轮)。 - `gesture.mousewheel`: 鼠标滚轮滚动。 - `gesture.mousemove`: 鼠标移动。 ### Pano Events (全景导航) 监听全景图的点位切换过程。 - `pano.prepare`: 准备切换到新点位。这是一个 `ExtendableEvent`,支持通过 `waitUntil(promise)` 延迟后续加载流程(如预加载资源),以及通过 `preventDefault()` 取消本次走点。事件对象包含 `options`(可修改,影响切换行为)、`prevMode`(切换前模式)、`prevPano`(切换前点位)、`pano`(目标点位)等属性。 - `pano.arrived`: 成功到达新点位(移动动画结束)。 - `pano.moving`: 正在移动到新点位(动画进行中)。 - `pano.willChange`: 即将发生点位变更(旧版兼容)。 - `pano.error`: 点位加载或移动出错。 ### State Events (状态变更) 监听 Five 内部状态(State)的变化,常用于 UI 同步或数据记录。 - `state.change`: 状态发生变更(可能是用户操作或代码触发)。 - `currentState.change`: 当前状态发生变更(通常指即时状态)。 - `state.synced`: 状态已同步。 ### Model & Work Events (数据加载) 监听场景数据(Work)或模型(Model)的加载生命周期。 - `works.load`: Work 数据开始加载。 - `works.ready`: Work 数据加载完成且 Controller 就绪。 - `model.load`: 模型开始加载。 - `models.load`: 所有模型加载完成。 ### Render Events (渲染循环) 监听每一帧的渲染过程。 - `render`: 每一帧渲染后触发。 - `render.prepare`: 每一帧渲染前触发。 ## Examples ### 快速上手 (Quick Example) 监听点击事件并打印日志。 ```typescript import { Five } from "@realsee/five"; const five = new Five(); // 监听点击事件 five.on("gesture.tap", (event) => { console.log("User tapped at:", event); }); // 监听点位变更完成 five.on("pano.arrived", (event) => { console.log("Arrived at pano:", event.pano); }); ``` ### 进阶用法 (Advanced Usage) 使用 `once` 监听一次性初始化事件,使用返回值取消监听。 ```typescript // 1. 等待首次数据加载完成 five.once("works.ready", () => { console.log("Five is ready!"); // 执行初始化逻辑,如自动巡游 }); // 2. 动态绑定与解绑 const onRender = () => { // 每一帧执行的逻辑 updateUI(); }; // 开始监听 five.on("render", onRender); // 在某个时刻取消监听(例如组件销毁时) // five.off("render", onRender); ``` ## Debugging - 使用 `five.on("error", (err) => console.error(err))` 捕获全局错误。 ## Related - [State](./state.md): 了解 State 的结构与变更机制。 - [Five](./five.md): Five 核心类说明。 --- ```yaml tags: [事件监听, 点击, 拖拽, 加载完成, 渲染回调, 生命周期, 回调, events, interaction, lifecycle, gesture, state, preventDefault, waitUntil, on, off, subscribe] ```