@netless/appliance-plugin 1.1.27-beta.7 → 1.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/READMA.zh-CN.md +599 -0
- package/README.md +89 -4
- package/cdn/cdn.js +1 -1
- package/cdn/{fullWorker-CtDHN_.js → fullWorker-DCfVcI.js} +1 -1
- package/cdn/{subWorker-DuuVTa.js → subWorker-DtUO-T.js} +1 -1
- package/dist/appliance-plugin.js +1 -1
- package/dist/appliance-plugin.mjs +1 -1
- package/dist/fullWorker.js +1 -1
- package/dist/{index-BO1MFbPV.js → index-BVgkgGj9.js} +1 -1
- package/dist/index-Ci0eJ9wV.js +1 -0
- package/dist/{index-5QkhtZxL.mjs → index-Cqizo6hB.mjs} +2 -2
- package/dist/{index-UtFjMigk.mjs → index-Dble46rY.mjs} +1 -1
- package/dist/subWorker.js +1 -1
- package/package.json +4 -2
- package/dist/index-CP2FuJ5f.js +0 -1
package/READMA.zh-CN.md
ADDED
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
# appliance-plugin
|
|
2
|
+
|
|
3
|
+
该插件基于 white-web-sdk 的插件机制, 实现了一套白板的教具的绘制工具. 同时也基于 @netless/window-manager, 实现了可多窗口上使用.
|
|
4
|
+
|
|
5
|
+
## 简介
|
|
6
|
+
|
|
7
|
+
appliance-plugin, 依赖 [white-web-sdk](https://www.npmjs.com/package/white-web-sdk)、[@netless/window-manager](https://www.npmjs.com/package/@netless/window-manager), 并基于web API对 [offscreenCanvas](https://developer.mozilla.org/zh-CN/docs/Web/API/OffscreenCanvas) 的支持.
|
|
8
|
+
|
|
9
|
+
## 原理
|
|
10
|
+
|
|
11
|
+
1. 该插件主要是基于SpriteJS的2D功能,支持 webgl2 渲染,并可向后兼容降级为 webgl 和 canvas2d
|
|
12
|
+
2. 该插件通过双webWorker + offscreenCanvas机制,把绘制计算+渲染逻辑都放在独立的worker线程中处理.不占用主线程的cpu任务.
|
|
13
|
+
3. 针对移动端有些终端不支持offscreenCanvas,则会把它放在主进程处理.
|
|
14
|
+
|
|
15
|
+
## 插件用法
|
|
16
|
+
|
|
17
|
+
### 安装
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @netless/appliance-plugin
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 注册插件
|
|
24
|
+
|
|
25
|
+
插件可以支持两种场景,它们接入插件命名不同:
|
|
26
|
+
|
|
27
|
+
- 多窗口 `ApplianceMultiPlugin`
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { ApplianceMultiPlugin } from "@netless/appliance-plugin";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- 单白板 `ApplianceSinglePlugin`
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import { ApplianceSinglePlugin } from "@netless/appliance-plugin";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **workerjs文件cdn部署**
|
|
40
|
+
>
|
|
41
|
+
> 我们采用双worker并发来提高绘制效率,这样让它比主进程效率提高了40%以上.但是两个worker文件上的公共依赖都是重复的,所以如果直接构建到包中,那么会大大增加包体积.所以我们允许workerjs文件cdn部署,只要把@netless/appliance-plugin/cdn下的文件部署到cdn中即可,然后通过插件中的getInstance的第二个参数options.cdn中配置上两个workerjs的cdn地址即可.这样就可以解决包体积过大的问题.
|
|
42
|
+
>
|
|
43
|
+
> **总包大概在400kB,两个wokerjs各有800kB.** 如果需要考虑构建的包体积大小的,请选择配置cdn.
|
|
44
|
+
|
|
45
|
+
### 接入方式参考
|
|
46
|
+
|
|
47
|
+
#### fastboard(直接对接fastboard)
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
|
|
51
|
+
// 引入worker.js方式可选, 如果走cdn,可以不用从dist中引入,如果从dist中引入,需要以资源模块方式并通过bolb内联形式配置到options.cdn中.如`?raw`,这个需要打包器的支持,vite默认支持`?raw`,webpack需要配置 raw-loader or asset/source.
|
|
52
|
+
import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
|
|
53
|
+
import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
|
|
54
|
+
const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
|
|
55
|
+
const fullWorkerUrl = URL.createObjectURL(fullWorkerBlob);
|
|
56
|
+
const subWorkerBlob = new Blob([subWorkerString], {type: 'text/javascript'});
|
|
57
|
+
const subWorkerUrl = URL.createObjectURL(subWorkerBlob);
|
|
58
|
+
|
|
59
|
+
// 对接 fastboard-react
|
|
60
|
+
// 全打包方式引用
|
|
61
|
+
// import { useFastboard, Fastboard } from "@netless/fastboard-react/full";
|
|
62
|
+
// 分包引用
|
|
63
|
+
import { useFastboard, Fastboard } from "@netless/fastboard-react";
|
|
64
|
+
|
|
65
|
+
const app = useFastboard(() => ({
|
|
66
|
+
sdkConfig: {
|
|
67
|
+
...
|
|
68
|
+
},
|
|
69
|
+
joinRoom: {
|
|
70
|
+
...
|
|
71
|
+
},
|
|
72
|
+
managerConfig: {
|
|
73
|
+
cursor: true,
|
|
74
|
+
enableAppliancePlugin: true,
|
|
75
|
+
...
|
|
76
|
+
},
|
|
77
|
+
enableAppliancePlugin: {
|
|
78
|
+
cdn: {
|
|
79
|
+
fullWorkerUrl,
|
|
80
|
+
subWorkerUrl,
|
|
81
|
+
}
|
|
82
|
+
...
|
|
83
|
+
}
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
// 对接 fastboard
|
|
87
|
+
// 全打包方式引用
|
|
88
|
+
// import { createFastboard, createUI } from "@netless/fastboard/full";
|
|
89
|
+
// 分包引用
|
|
90
|
+
import { createFastboard, createUI } from "@netless/fastboard";
|
|
91
|
+
|
|
92
|
+
const fastboard = await createFastboard({
|
|
93
|
+
sdkConfig: {
|
|
94
|
+
...
|
|
95
|
+
},
|
|
96
|
+
joinRoom: {
|
|
97
|
+
...
|
|
98
|
+
},
|
|
99
|
+
managerConfig: {
|
|
100
|
+
cursor: true,
|
|
101
|
+
supportAppliancePlugin: true,
|
|
102
|
+
...
|
|
103
|
+
},
|
|
104
|
+
enableAppliancePlugin: {
|
|
105
|
+
cdn: {
|
|
106
|
+
fullWorkerUrl,
|
|
107
|
+
subWorkerUrl,
|
|
108
|
+
}
|
|
109
|
+
...
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### 多窗口(直接对接window-manager)
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
|
|
118
|
+
import '@netless/window-manager/dist/style.css';
|
|
119
|
+
import '@netless/appliance-plugin/dist/style.css';
|
|
120
|
+
|
|
121
|
+
import { WhiteWebSdk } from "white-web-sdk";
|
|
122
|
+
import { WindowManager } from "@netless/window-manager";
|
|
123
|
+
import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
|
|
124
|
+
// 引入worker.js方式可选, 如果走cdn,可以不用从dist中引入,如果从dist中引入,需要以资源模块方式并通过bolb内联形式配置到options.cdn中.如`?raw`,这个需要打包器的支持,vite默认支持`?raw`,webpack需要配置 raw-loader or asset/source.
|
|
125
|
+
import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
|
|
126
|
+
import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
|
|
127
|
+
const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
|
|
128
|
+
const fullWorkerUrl = URL.createObjectURL(fullWorkerBlob);
|
|
129
|
+
const subWorkerBlob = new Blob([subWorkerString], {type: 'text/javascript'});
|
|
130
|
+
const subWorkerUrl = URL.createObjectURL(subWorkerBlob);
|
|
131
|
+
|
|
132
|
+
const whiteWebSdk = new WhiteWebSdk(...)
|
|
133
|
+
const room = await whiteWebSdk.joinRoom({
|
|
134
|
+
...
|
|
135
|
+
invisiblePlugins: [WindowManager, ApplianceMultiPlugin],
|
|
136
|
+
useMultiViews: true,
|
|
137
|
+
})
|
|
138
|
+
const manager = await WindowManager.mount({ room , container:elm, chessboard: true, cursor: true, supportAppliancePlugin: true});
|
|
139
|
+
if (manager) {
|
|
140
|
+
await manager.switchMainViewToWriter();
|
|
141
|
+
await ApplianceMultiPlugin.getInstance(manager,
|
|
142
|
+
{
|
|
143
|
+
options: {
|
|
144
|
+
cdn: {
|
|
145
|
+
fullWorkerUrl,
|
|
146
|
+
subWorkerUrl,
|
|
147
|
+
}
|
|
148
|
+
...
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
> **注意** 项目中需要引入css文件 `import '@netless/appliance-plugin/dist/style.css';`
|
|
156
|
+
|
|
157
|
+
#### 单白板(直接对接white-web-sdk)
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
|
|
161
|
+
import '@netless/appliance-plugin/dist/style.css';
|
|
162
|
+
|
|
163
|
+
import { WhiteWebSdk } from "white-web-sdk";
|
|
164
|
+
import { ApplianceSinglePlugin, ApplianceSigleWrapper } from '@netless/appliance-plugin';
|
|
165
|
+
// 引入worker.js方式可选, 如果走cdn,可以不用从dist中引入,如果从dist中引入,需要以资源模块方式并通过bolb内联形式配置到options.cdn中.如`?raw`,这个需要打包器的支持,vite默认支持`?raw`,webpack需要配置 raw-loader or asset/source.
|
|
166
|
+
import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
|
|
167
|
+
import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
|
|
168
|
+
const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
|
|
169
|
+
const fullWorkerUrl = URL.createObjectURL(fullWorkerBlob);
|
|
170
|
+
const subWorkerBlob = new Blob([subWorkerString], {type: 'text/javascript'});
|
|
171
|
+
const subWorkerUrl = URL.createObjectURL(subWorkerBlob);
|
|
172
|
+
|
|
173
|
+
const whiteWebSdk = new WhiteWebSdk(...)
|
|
174
|
+
const room = await whiteWebSdk.joinRoom({
|
|
175
|
+
...
|
|
176
|
+
invisiblePlugins: [ApplianceSinglePlugin],
|
|
177
|
+
wrappedComponents: [ApplianceSigleWrapper]
|
|
178
|
+
})
|
|
179
|
+
await ApplianceSinglePlugin.getInstance(room,
|
|
180
|
+
{
|
|
181
|
+
options: {
|
|
182
|
+
cdn: {
|
|
183
|
+
fullWorkerUrl,
|
|
184
|
+
subWorkerUrl,
|
|
185
|
+
}
|
|
186
|
+
...
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
> **注意** 项目中需要引入css文件 `import '@netless/appliance-plugin/dist/style.css';`
|
|
193
|
+
|
|
194
|
+
#### 关于?raw的webpack配置
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
module: {
|
|
198
|
+
rules: [
|
|
199
|
+
// ...
|
|
200
|
+
{
|
|
201
|
+
test: /\.m?js$/,
|
|
202
|
+
resourceQuery: { not: [/raw/] },
|
|
203
|
+
use: [ ... ]
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
resourceQuery: /raw/,
|
|
207
|
+
type: 'asset/source',
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## 调用介绍
|
|
214
|
+
|
|
215
|
+
### api介绍
|
|
216
|
+
|
|
217
|
+
#### 优化原有接口
|
|
218
|
+
|
|
219
|
+
插件重新实现了一些room或windowmanager上的同名接口,但是我们内部已经通过`injectMethodToObject` 重新注入回原来的对象中.从而外部用户无需任何改动.如以下几个:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
// 内部 hack
|
|
223
|
+
injectMethodToObject(windowmanager, "undo");
|
|
224
|
+
injectMethodToObject(windowmanager, "redo");
|
|
225
|
+
injectMethodToObject(windowmanager, "cleanCurrentScene");
|
|
226
|
+
injectMethodToObject(windowmanager, "insertImage");
|
|
227
|
+
injectMethodToObject(windowmanager, "completeImageUpload");
|
|
228
|
+
injectMethodToObject(windowmanager, "lockImage");
|
|
229
|
+
injectMethodToObject(room, "getImagesInformation");
|
|
230
|
+
injectMethodToObject(room, "callbacks");
|
|
231
|
+
injectMethodToObject(room, "screenshotToCanvasAsync");
|
|
232
|
+
injectMethodToObject(room, "getBoundingRectAsync");
|
|
233
|
+
injectMethodToObject(room, "scenePreviewAsync");
|
|
234
|
+
injectMethodToObject(windowmanager.mainView, "setMemberState");
|
|
235
|
+
// 这些我们可以通过前端日志看到调用行为,例如:
|
|
236
|
+
// [ApplianceMultiPlugin] setMemberState
|
|
237
|
+
// [ApplianceMultiPlugin] cleanCurrentScene
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
具体涉及以下接口:
|
|
241
|
+
|
|
242
|
+
1. room上接口
|
|
243
|
+
|
|
244
|
+
- [`setMemberState`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#setmemberstate)
|
|
245
|
+
- [`undo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#undo)
|
|
246
|
+
- [`redo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#redo)
|
|
247
|
+
- [`callbacks`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#callbacks)
|
|
248
|
+
- [`insertImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#insertImage)
|
|
249
|
+
- [`lockImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#lockImage)
|
|
250
|
+
- [`completeImageUpload`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#completeImageUpload)
|
|
251
|
+
- `getImagesInformation`
|
|
252
|
+
- [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
|
|
253
|
+
|
|
254
|
+
2. windowmanager上接口
|
|
255
|
+
|
|
256
|
+
- [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
|
|
257
|
+
- [`canUndoSteps`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#canUndoSteps)
|
|
258
|
+
- [`canRedoSteps`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#canUndoSteps)
|
|
259
|
+
|
|
260
|
+
3. windowmanager的mainview上的接口
|
|
261
|
+
|
|
262
|
+
- [`setMemberState`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#setmemberstate)
|
|
263
|
+
- [`undo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#undo)
|
|
264
|
+
- [`redo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#redo)
|
|
265
|
+
- [`callbacks`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#callbacks)
|
|
266
|
+
- [`insertImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#insertImage)
|
|
267
|
+
- [`lockImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#lockImage)
|
|
268
|
+
- [`completeImageUpload`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#completeImageUpload)
|
|
269
|
+
- `getImagesInformation`
|
|
270
|
+
- [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
|
|
271
|
+
|
|
272
|
+
4. 自定义
|
|
273
|
+
|
|
274
|
+
- `getBoundingRectAsync` 替代接口 room.getBoundingRect
|
|
275
|
+
- `screenshotToCanvasAsync` 替代接口 [room.screenshotToCanvas](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#screenshotToCanvas)
|
|
276
|
+
- `scenePreviewAsync` 替代接口 [room.scenePreview](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#scenePreview)
|
|
277
|
+
- `fillSceneSnapshotAsync` 替代接口 [room.fillSceneSnapshot](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#fillSceneSnapshot)
|
|
278
|
+
- `destroy` 销毁appliance-plugin的实例
|
|
279
|
+
- `addListener` 添加appliance-plugin内部事件监听器
|
|
280
|
+
- `removeListener` 移除appliance-plugin内部事件监听器
|
|
281
|
+
- `disableDeviceInputs` 替代接口 [room.disableDeviceInputs](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableDeviceInputs)
|
|
282
|
+
- `disableEraseImage` 替代接口 [room.disableEraseImage](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableEraseImage) **该方法只禁止整体擦除的橡皮擦对图片的擦除, 局部橡皮擦无效**
|
|
283
|
+
- `disableCameraTransform` 替代接口 [room.disableCameraTransform](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableCameraTransform) (Version >=1.1.17)
|
|
284
|
+
- `insertText` 在指定位置插入文字 (Version >=1.1.18)
|
|
285
|
+
- `updateText` 编辑指定文字的内容 (Version >=1.1.18)
|
|
286
|
+
- `blurText` 失去文本焦点 (Version >=1.1.19)
|
|
287
|
+
- `hasElements` 指定场景下是否存在元素 (Version >=1.1.19)
|
|
288
|
+
- `getElements` 获取场景下的所有元素 (Version >=1.1.19)
|
|
289
|
+
- `stopDraw` 停止Draw事件 (Version >=1.1.19)
|
|
290
|
+
- `setViewLocalScenePathChange` 设置白板本地场景路径变化 (Version >=1.1.27)
|
|
291
|
+
|
|
292
|
+
5. 不兼容
|
|
293
|
+
|
|
294
|
+
- [`exportScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#exportScene) appliance-plugin开启后,笔记不能按room的方式导出
|
|
295
|
+
- [服务端截图](https://doc.shengwang.cn/doc/whiteboard/restful/fastboard-sdk/restful-wb/operations/post-v5-rooms-uuid-screenshots), appliance-plugin开启后, 笔记不能通过调用服务端截图方式获取截图,而需要改用`screenshotToCanvasAsync`获取
|
|
296
|
+
|
|
297
|
+
#### 新功能
|
|
298
|
+
|
|
299
|
+
1. 激光铅笔教具 (Version >=1.1.1)
|
|
300
|
+
```js
|
|
301
|
+
import { EStrokeType, ApplianceNames } from "@netless/appliance-plugin";
|
|
302
|
+
room.setMemberState({
|
|
303
|
+
currentApplianceName: ApplianceNames.laserPen,
|
|
304
|
+
strokeType: EStrokeType.Normal,
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+

|
|
308
|
+
2. 扩展教具 (Version >=1.1.1)
|
|
309
|
+
在原来的[白板教具](https://doc.shengwang.cn/api-ref/whiteboard/javascript/globals.html#memberstate)类型上,增加了一些扩展功能属性,如下:
|
|
310
|
+
|
|
311
|
+
```js
|
|
312
|
+
export enum EStrokeType {
|
|
313
|
+
/** 实心线条 */
|
|
314
|
+
Normal = 'Normal',
|
|
315
|
+
/** 带笔锋线条 */
|
|
316
|
+
Stroke = 'Stroke',
|
|
317
|
+
/** 虚线线条 */
|
|
318
|
+
Dotted = 'Dotted',
|
|
319
|
+
/** 长虚线线条 */
|
|
320
|
+
LongDotted = 'LongDotted'
|
|
321
|
+
};
|
|
322
|
+
export type ExtendMemberState = {
|
|
323
|
+
/** 当前用户所选择的教具 */
|
|
324
|
+
currentApplianceName: ApplianceNames;
|
|
325
|
+
/** 是否开启笔锋 */
|
|
326
|
+
strokeType?: EStrokeType;
|
|
327
|
+
/** 是否删除整条线段 */
|
|
328
|
+
isLine?: boolean;
|
|
329
|
+
/** 线框透明度 */
|
|
330
|
+
strokeOpacity?: number;
|
|
331
|
+
/** 是否开启激光笔 */
|
|
332
|
+
useLaserPen?: boolean;
|
|
333
|
+
/** 激光笔保持时间, second */
|
|
334
|
+
duration?: number;
|
|
335
|
+
/** 填充样式 */
|
|
336
|
+
fillColor?: Color;
|
|
337
|
+
/** 填充透明度 */
|
|
338
|
+
fillOpacity?: number;
|
|
339
|
+
/** 使用 ``shape`` 教具时,绘制图形的具体类型 */
|
|
340
|
+
shapeType?: ShapeType;
|
|
341
|
+
/** 多边形顶点数 */
|
|
342
|
+
vertices?:number;
|
|
343
|
+
/** 多边形向内顶点步长 */
|
|
344
|
+
innerVerticeStep?:number;
|
|
345
|
+
/** 多边形向内顶点与外顶点半径比率 */
|
|
346
|
+
innerRatio?: number;
|
|
347
|
+
/** 文字透明度 */
|
|
348
|
+
textOpacity?: number;
|
|
349
|
+
/** 文字背景颜色 */
|
|
350
|
+
textBgColor?: Color;
|
|
351
|
+
/** 文字背景颜色透明度 */
|
|
352
|
+
textBgOpacity?: number;
|
|
353
|
+
/** 位置 */
|
|
354
|
+
placement?: SpeechBalloonPlacement;
|
|
355
|
+
};
|
|
356
|
+
import { ExtendMemberState, ApplianceNames } from '@netless/appliance-plugin';
|
|
357
|
+
/** 设置教具状态 */
|
|
358
|
+
room.setMemberState({ ... } as ExtendMemberState);
|
|
359
|
+
manager.mainView.setMemberState({ ... } as ExtendMemberState);
|
|
360
|
+
appliance.setMemberState({ ... } as ExtendMemberState);
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
- 设置笔记类型:
|
|
364
|
+
|
|
365
|
+
```js
|
|
366
|
+
// 实心线条
|
|
367
|
+
setMemberState({ strokeType: EStrokeType.Normal });
|
|
368
|
+
// 带笔锋线条
|
|
369
|
+
setMemberState({ strokeType: EStrokeType.Stroke });
|
|
370
|
+
// 虚线线条
|
|
371
|
+
setMemberState({ strokeType: EStrokeType.Dotted });
|
|
372
|
+
// 长虚线线条
|
|
373
|
+
setMemberState({ strokeType: EStrokeType.LongDotted });
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+

|
|
377
|
+
- 设置笔记、图形边框透明度(马克笔):
|
|
378
|
+
|
|
379
|
+
```js
|
|
380
|
+
setMemberState({ strokeOpacity: 0.5 });
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+

|
|
384
|
+
- 设置文字颜色、透明度、背景颜色、透明度
|
|
385
|
+
|
|
386
|
+
```js
|
|
387
|
+
setMemberState({
|
|
388
|
+
textOpacity: 0.5,
|
|
389
|
+
textBgOpacity: 0.5,
|
|
390
|
+
textBgColor: [0, 0, 0],
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+

|
|
395
|
+
- 设置图形填充色及透明度
|
|
396
|
+
|
|
397
|
+
```js
|
|
398
|
+
setMemberState({ fillOpacity: 0.5, fillColor: [0, 0, 0] });
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+

|
|
402
|
+
- 自定义正多边形
|
|
403
|
+
|
|
404
|
+
```js
|
|
405
|
+
// 正五边形
|
|
406
|
+
setMemberState({
|
|
407
|
+
currentApplianceName: ApplianceNames.shape,
|
|
408
|
+
shapeType: ShapeType.Polygon,
|
|
409
|
+
vertices: 5,
|
|
410
|
+
});
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+

|
|
414
|
+
- 自定义星形
|
|
415
|
+
|
|
416
|
+
```js
|
|
417
|
+
// 胖六角星
|
|
418
|
+
setMemberState({
|
|
419
|
+
currentApplianceName: ApplianceNames.shape,
|
|
420
|
+
shapeType: ShapeType.Star,
|
|
421
|
+
vertices: 12,
|
|
422
|
+
innerVerticeStep: 2,
|
|
423
|
+
innerRatio: 0.8,
|
|
424
|
+
});
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+

|
|
428
|
+
- 自定义泡泡框方向
|
|
429
|
+
|
|
430
|
+
```js
|
|
431
|
+
// 左下角提示框
|
|
432
|
+
setMemberState({
|
|
433
|
+
currentApplianceName: ApplianceNames.shape,
|
|
434
|
+
shapeType: ShapeType.SpeechBalloon,
|
|
435
|
+
placement: "bottomLeft",
|
|
436
|
+
});
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+

|
|
440
|
+
|
|
441
|
+
3. 分屏显示笔记(小白板功能),需要结合[`@netless/app-little-white-board`](https://github.com/netless-io/app-little-white-board) (Version >=1.1.3)
|
|
442
|
+

|
|
443
|
+
4. 文字编辑API (Version >=1.1.18)
|
|
444
|
+
```js
|
|
445
|
+
/** 在指定位置插入文字
|
|
446
|
+
* @param x 第一个字的的左侧边中点,世界坐标系中的 x 坐标
|
|
447
|
+
* @param y 第一个字的的左侧边中点,世界坐标系中的 y 坐标
|
|
448
|
+
* @param textContent 初始化文字的内容,不传则为空
|
|
449
|
+
* @returns 该文字的标识符
|
|
450
|
+
*/
|
|
451
|
+
insertText(x: number, y: number, textContent?: string): string | undefined;
|
|
452
|
+
|
|
453
|
+
/** 编辑指定文字的内容
|
|
454
|
+
* @param identifier 文字的标识符。为 insertText() 的返回值。
|
|
455
|
+
* @param textContent 文字要改成的内容
|
|
456
|
+
*/
|
|
457
|
+
updateText(identifier: string, textContent: string): void;
|
|
458
|
+
|
|
459
|
+
/** 失去文本焦点 */
|
|
460
|
+
blurText(): void;
|
|
461
|
+
```
|
|
462
|
+
5. 元素查询API (Version >=1.1.19)
|
|
463
|
+
```js
|
|
464
|
+
/** 指定场景下是否存在元素
|
|
465
|
+
* @param scenePath 场景路径, 默认取当前聚焦的场景
|
|
466
|
+
* @param filter 过滤条件
|
|
467
|
+
* @returns 是否存在元素
|
|
468
|
+
*/
|
|
469
|
+
hasElements(
|
|
470
|
+
scenePath?: string,
|
|
471
|
+
filter?: (toolsType: EToolsKey) => boolean,
|
|
472
|
+
): boolean;
|
|
473
|
+
|
|
474
|
+
/** 获取场景下的所有元素
|
|
475
|
+
* @param scenePath 场景路径, 默认取当前聚焦的场景
|
|
476
|
+
* @param filter 过滤条件
|
|
477
|
+
* @returns 所有元素
|
|
478
|
+
*/
|
|
479
|
+
getElements(
|
|
480
|
+
scenePath?: string,
|
|
481
|
+
filter?: (toolsType: EToolsKey) => boolean,
|
|
482
|
+
): BaseCollectorReducerAction[];
|
|
483
|
+
```
|
|
484
|
+
6. 小地图功能 (Version >=1.1.6)
|
|
485
|
+
```js
|
|
486
|
+
/** 创建小地图
|
|
487
|
+
* @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
|
|
488
|
+
* @param div 小地图DOM容器
|
|
489
|
+
*/
|
|
490
|
+
createMiniMap(viewId: string, div: HTMLElement): Promise<void>;
|
|
491
|
+
/** 销毁小地图 */
|
|
492
|
+
destroyMiniMap(viewId: string): Promise<boolean>;
|
|
493
|
+
```
|
|
494
|
+

|
|
495
|
+
7. 过滤笔记 (Version >=1.1.6)
|
|
496
|
+
``js
|
|
497
|
+
/** 过滤笔记
|
|
498
|
+
* @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
|
|
499
|
+
* @param filter 过滤条件
|
|
500
|
+
* render: 笔记是否能要渲染, [uid1, uid2, ...] 或 true. true, 即都会渲染, [uid1, uid2, ...] 为指定渲染的用户uid集合
|
|
501
|
+
* hide: 笔记是否隐藏, [uid1, uid2, ...] 或 true. true, 即都要隐藏, [uid1, uid2, ...] 为指定隐藏的用户uid集合
|
|
502
|
+
* clear: 笔记是否可被清除, [uid1, uid2, ...] 或 true. true, 即都可以被清除, [uid1, uid2, ...] 为指定可被清除的用户uid集合
|
|
503
|
+
* @param isSync 是否同步到其他用户, 默认为true, 即会同步到其他用户
|
|
504
|
+
*/
|
|
505
|
+
filterRenderByUid(viewId: string, filter: { render?: _ArrayTrue, hide?: _ArrayTrue, clear?: _ArrayTrue}, isSync?:boolean): void;
|
|
506
|
+
/** 取消过滤笔记
|
|
507
|
+
* @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
|
|
508
|
+
* @param isSync 是否同步到其他用户, 默认为true, 即会同步到其他用户. 请保持和filterRenderByUid设置的一致
|
|
509
|
+
*/
|
|
510
|
+
cancelFilterRender(viewId: string, isSync?:boolean): void;
|
|
511
|
+
``
|
|
512
|
+

|
|
513
|
+
8. 设置白板本地场景路径变化 (Version >=1.1.27)
|
|
514
|
+
```js
|
|
515
|
+
/** 设置白板本地场景路径变化
|
|
516
|
+
* @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
|
|
517
|
+
* @param scenePath 要设置的场景路径
|
|
518
|
+
*/
|
|
519
|
+
setViewLocalScenePathChange(viewId: string, scenePath: string): Promise<void>;
|
|
520
|
+
```
|
|
521
|
+
<!-- 9. 手写图形自动联想功能:`autoDraw` (version >=1.1.7)
|
|
522
|
+
```js
|
|
523
|
+
export type AutoDrawOptions = {
|
|
524
|
+
/** 自动联想rest api地址 */
|
|
525
|
+
hostServer: string;
|
|
526
|
+
/** 存放联想icon列表的容器 */
|
|
527
|
+
container: HTMLDivElement;
|
|
528
|
+
/** 绘制结束多久开始激活联想 */
|
|
529
|
+
delay?: number;
|
|
530
|
+
};
|
|
531
|
+
import { ApplianceMultiPlugin, AutoDrawPlugin } from '@netless/appliance-plugin';
|
|
532
|
+
const plugin = await ApplianceMultiPlugin.getInstance(...);
|
|
533
|
+
const autoDrawPlugin = new AutoDrawPlugin({
|
|
534
|
+
container: topBarDiv,
|
|
535
|
+
hostServer: 'https://autodraw-white-backup-hk-hkxykbfofr.cn-hongkong.fcapp.run',
|
|
536
|
+
delay: 2000
|
|
537
|
+
});
|
|
538
|
+
plugin.usePlugin(autoDrawPlugin);
|
|
539
|
+
```
|
|
540
|
+
 -->
|
|
541
|
+
|
|
542
|
+
### 配置参数
|
|
543
|
+
|
|
544
|
+
`getInstance(wm: WindowManager, adaptor: ApplianceAdaptor)`
|
|
545
|
+
|
|
546
|
+
- wm: ` WindowManager\room\player`。多窗口模式下传入的是WindowManager,单窗口模式下传入的是room或者player(白板回放模式)。
|
|
547
|
+
- adaptor: 配置适配器.
|
|
548
|
+
- `options: AppliancePluginOptions`; 必须配置, 两个worker的cdn地址。
|
|
549
|
+
```js
|
|
550
|
+
export type AppliancePluginOptions = {
|
|
551
|
+
/** cdn配置项 */
|
|
552
|
+
cdn: CdnOpt;
|
|
553
|
+
/** 扩展配置项 */
|
|
554
|
+
extras?: ExtrasOptions;
|
|
555
|
+
...
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
扩展配置项 (`ExtrasOptions`):
|
|
560
|
+
```js
|
|
561
|
+
export type ExtrasOptions = {
|
|
562
|
+
/** 使用简单模式, 默认 false (Version >=1.1.22) */
|
|
563
|
+
useSimple?: boolean;
|
|
564
|
+
/** 文字编辑器配置 */
|
|
565
|
+
textEditor?: {
|
|
566
|
+
/** 是否显示浮动栏 */
|
|
567
|
+
showFloatBar?: boolean;
|
|
568
|
+
/** 是否可以通过selector教具切换 */
|
|
569
|
+
canSelectorSwitch?: boolean;
|
|
570
|
+
/** 是否右边界自动换行 */
|
|
571
|
+
rightBoundBreak?: boolean;
|
|
572
|
+
/** 扩展字体列表 (Version >=1.1.22) */
|
|
573
|
+
extendFontFaces?: { fontFamily: string; src: string }[];
|
|
574
|
+
/** 加载字体超时时间,单位:毫秒 */
|
|
575
|
+
loadFontFacesTimeout?: number;
|
|
576
|
+
};
|
|
577
|
+
/** 撤销重做配置项 */
|
|
578
|
+
undoRedo?: {
|
|
579
|
+
/** 是否启用全局撤销重做, 默认值为 false (Version >=1.1.27) */
|
|
580
|
+
enableGlobal?: boolean;
|
|
581
|
+
/** 撤销重做最大堆栈长度, 默认值为 20 */
|
|
582
|
+
maxStackLength?: number;
|
|
583
|
+
};
|
|
584
|
+
// ... 其他配置项
|
|
585
|
+
};
|
|
586
|
+
```
|
|
587
|
+
- `cursorAdapter?: CursorAdapter`; 非必填, 单白板模式下, 配置的自定义鼠标样式。
|
|
588
|
+
- `logger?: Logger`; 非必填, 配置日志打印器对象. 不填写默认在本地console输出, 如果需要把日志上传到指定server, 则需要手动配置.
|
|
589
|
+
> 如需要上传到白板日志服务器,可以把room上的logger配置到该项目。
|
|
590
|
+
|
|
591
|
+
### 前端调试介绍
|
|
592
|
+
|
|
593
|
+
对接过程中如果想了解和跟踪插件内部状态,可以通过以下几个控制台指令,查看内部数据.
|
|
594
|
+
|
|
595
|
+
```js
|
|
596
|
+
const applianPlugin = await ApplianceSinglePlugin.getInstance(...)
|
|
597
|
+
appliancePlugin.currentManager // 可以查看到包版本号,内部状态等
|
|
598
|
+
appliancePlugin.currentManager.consoleWorkerInfo() // 可以查看到worker上的绘制信息
|
|
599
|
+
```
|