插件 Plugins

Five 提供了工厂模式的插件机制, 提供了 FivePlugin FivePluginInstance FivePluginInits 接口来帮助创建和使用插件

  1. 插件即是将一些通用的对于 five 的操作的一些复用的抽象。
  2. 可以通过插件来组织代码,减少逻辑依赖。
mkdir a-five-plugin
npm init -y
npm install @realsee/five
npx five-plugin-init
.
├── README.md
├── devtools
│ ├── external-five.js
│ ├── external-three.js
│ ├── tsconfig.build.json
│ ├── webpack.bundle.js
│ └── webpack.example.js
├── docs
├── examples
│ ├── data.json
│ ├── index.html
│ └── index.ts
├── lib
│ └── index.ts
├── package.json
└── tsconfig.json
  • example: 开发环境,编译 example 下的 index.ts, 监听变化,并且开启端口监听,可以通过 localhost:8080 访问
  • build:doc: 通过 typedoc 生成项目文档,生成目标在 docs 目录下
  • build:typescript: 通过 tsc 编译 ts 代码,生成目标在 build 目录下
  • build:bundle: 通过 webpack 编译 unpack 包, 生成目标在 bundle 目录下
  • build:all: npm run build:doc && npm run build:typescript && && npm run build:example && npm run build:bundle

编译配置均在 devtools 目录下, 可以自行修改配置

  • ts 的编译参数在 devtools/tsconfig.build.json
  • bundle 的 webpack 配置在 devtools/webpack.bundle.js
  • 往 npm 发布,默认发布的入口文件在 build/index.js, 即通过 tsc 编译得到的代码。你可以在 package.json 中修改。
  • bundle 包发布,可以直接使用 build:bundle 生成的结果。
type FivePlugin<Parameters, Returns>;
  • Parameters 插件定义的参数
  • Returns 插件返回的实例

这是一个在当five显示界面被点击时 打印 "tap!" 的一个简单插件, 并且可以拉取历史列表

import { FivePlugin } from "@realsee/five";

// 打印的内容
type TapRecordPluginParameter = string;

// 实例方法
type TapRecordPluginReturns = {
// 一个返回历史列表的防范
getHistory: () => string[]
};

const TapRecordPlugin: FivePlugin<
TapRecordPluginParameter,
TapRecordPluginReturns
> = (five, message = "tap!") => {

const list: string[] = [];

five.on("tapGesture", () => {
console.log(message);
list.push(`${new Date().toUTCString()} ${message}`);
});

return { getHistory: () => list.slice() };
};
  • 工厂函数的参数是 five 实例 以及对应的插件需要的参数, 参数使用后面在插件初始化中详细说明。
  • 工厂函数的返回将在 five.plugis 中取到,后面会详细说明。
type FivePluginInit<FivePlugin>

就上面 TapRecordPlugin 的例子来初始化插件

import Five, { FivePluginInits } from "@realsee/five";

const five = new Five({
plugins: [
[
// 插件
TapRecordPlugin,

// 插件对象在 five.plugins 中的命名实例名称,
// 比如这个就是通过 five.plguins.tapRecord 获取到插件实例
"tapRecord",

// 插件参数,必须符合 TapRecordPluginParameter 的生命
"tap!"
] as FivePluginInit<typeof TapRecordPlugin>
]
});

// five.load(...)
  • 需要使用 as FivePluginInit 的方法声明,否则无法约束参数
  • 第一个参数必须唯一的,不要出现插件间冲突
type FivePluginInstance<FivePlugin>;

简单例子 就上面 TapRecordPlugin 的例子来获取历时点击列表

import { FivePluginInstance } from "@realsee/five";

// five.plugins.tapRecord 可以获取到插件实例 "tapRecord" 是插件初始化声明确定的
// 通过 FivePluginInstance 在约束类型,否则均为 any
const tapRecord: FivePluginInstance<typeof TapRecordPlugin> = five.plugins.tapRecord;

// 现在就可以获取到历时列表了
const getHistory: string[] = tapRecord.getHistory();

console.log(getHistory);
import Five, { FivePlugin, FivePluginInit, FivePluginInstance } from "@realsee/five";

// 打印的内容
type TapRecordPluginParameter = string;

// 实例方法
type TapRecordPluginReturns = {
// 一个返回历史列表的防范
getHistory: () => string[]
};

const TapRecordPlugin: FivePlugin<
TapRecordPluginParameter,
TapRecordPluginReturns
> = (five, message = "tap!") => {

const list: string[] = [];

five.on("tapGesture", () => {
console.log(message);
list.push(`${new Date().toUTCString()} ${message}`);
});

return { getHistory: () => list.slice() };
};

const five = new Five({
plugins: [
[
// 插件对象在 five.plugins 中的命名实例名称,
// 比如这个就是通过 five.plguins.tapRecord 获取到插件实例
"tapRecord",

// 插件
TapRecordPlugin,

// 插件参数,必须符合 TapRecordPluginParameter 的生命
"tap!"
] as FivePluginInit<typeof TapRecordPlugin>
]
});

// five.load(...)

// five.plugins.tapRecord 可以获取到插件实例 "tapRecord" 是插件初始化声明确定的
// 通过 FivePluginInstance 在约束类型,否则均为 any
const tapRecord: FivePluginInstance<typeof TapRecordPlugin> = five.plugins.tapRecord;

// 现在就可以获取到历时列表了
const getHistory: string[] = tapRecord.getHistory();

console.log(getHistory);
  1. 插件初始化的时机在 new Five 时,Five 并没有调用 load 来创建VR,请通过监听事件的方式,在合适的时机获取模型。
  2. 如果插件内容需要有 five 销毁同时销毁的内容,请监听 five.on("dispose") 事件来处理。
  3. 不要出现初始化插件同名的现象,会出现插件间冲突。
""