@netless/appliance-plugin 1.1.27 → 1.1.28

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 CHANGED
@@ -1,16 +1,16 @@
1
1
  # appliance-plugin
2
2
 
3
- 该插件基于 white-web-sdk 的插件机制, 实现了一套白板的教具的绘制工具. 同时也基于 @netless/window-manager, 实现了可多窗口上使用.
3
+ 该插件基于 white-web-sdk 的插件机制,实现了一套白板教具的绘制工具。同时也基于 @netless/window-manager,实现了可在多窗口上使用。
4
4
 
5
5
  ## 简介
6
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) 的支持.
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
8
 
9
9
  ## 原理
10
10
 
11
- 1. 该插件主要是基于SpriteJS的2D功能,支持 webgl2 渲染,并可向后兼容降级为 webglcanvas2d
12
- 2. 该插件通过双webWorker + offscreenCanvas机制,把绘制计算+渲染逻辑都放在独立的worker线程中处理.不占用主线程的cpu任务.
13
- 3. 针对移动端有些终端不支持offscreenCanvas,则会把它放在主进程处理.
11
+ 1. 该插件主要是基于 SpriteJS 2D 功能,支持 WebGL2 渲染,并可向后兼容降级为 WebGLCanvas2D。
12
+ 2. 该插件通过双 WebWorker + OffscreenCanvas 机制,把绘制计算和渲染逻辑都放在独立的 worker 线程中处理,不占用主线程的 CPU 任务。
13
+ 3. 针对移动端有些终端不支持 OffscreenCanvas,则会把它放在主线程处理。
14
14
 
15
15
  ## 插件用法
16
16
 
@@ -23,32 +23,27 @@ npm install @netless/appliance-plugin
23
23
  ### 注册插件
24
24
 
25
25
  插件可以支持两种场景,它们接入插件命名不同:
26
-
27
26
  - 多窗口 `ApplianceMultiPlugin`
28
-
29
27
  ```js
30
- import { ApplianceMultiPlugin } from "@netless/appliance-plugin";
28
+ import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
31
29
  ```
32
-
33
30
  - 单白板 `ApplianceSinglePlugin`
34
-
35
31
  ```js
36
- import { ApplianceSinglePlugin } from "@netless/appliance-plugin";
32
+ import { ApplianceSinglePlugin } from '@netless/appliance-plugin';
37
33
  ```
38
34
 
39
- > **workerjs文件cdn部署**
35
+ > **worker.js 文件 CDN 部署**
40
36
  >
41
- > 我们采用双worker并发来提高绘制效率,这样让它比主进程效率提高了40%以上.但是两个worker文件上的公共依赖都是重复的,所以如果直接构建到包中,那么会大大增加包体积.所以我们允许workerjs文件cdn部署,只要把@netless/appliance-plugin/cdn下的文件部署到cdn中即可,然后通过插件中的getInstance的第二个参数options.cdn中配置上两个workerjscdn地址即可.这样就可以解决包体积过大的问题.
37
+ > 我们采用双 worker 并发来提高绘制效率,这样让它比主线程效率提高了 40% 以上。但是两个 worker 文件上的公共依赖都是重复的,所以如果直接构建到包中,那么会大大增加包体积。所以我们允许 worker.js 文件 CDN 部署,只要把 `@netless/appliance-plugin/cdn` 下的文件部署到 CDN 中即可,然后通过插件中的 `getInstance` 的第二个参数 `options.cdn` 中配置上两个 worker.js CDN 地址即可。这样就可以解决包体积过大的问题。
42
38
  >
43
- > **总包大概在400kB,两个wokerjs各有800kB.** 如果需要考虑构建的包体积大小的,请选择配置cdn.
39
+ > **总包大概在 400kB,两个 worker.js 各有 800kB。** 如果需要考虑构建的包体积大小的,请选择配置 CDN。
44
40
 
45
41
  ### 接入方式参考
46
42
 
47
43
  #### fastboard(直接对接fastboard)
48
-
49
44
  ```js
50
45
 
51
- // 引入worker.js方式可选, 如果走cdn,可以不用从dist中引入,如果从dist中引入,需要以资源模块方式并通过bolb内联形式配置到options.cdn中.如`?raw`,这个需要打包器的支持,vite默认支持`?raw`,webpack需要配置 raw-loader or asset/source.
46
+ // 引入 worker.js 方式可选,如果走 CDN,可以不用从 dist 中引入。如果从 dist 中引入,需要以资源模块方式并通过 blob 内联形式配置到 options.cdn 中。如 `?raw`,这个需要打包器的支持,vite 默认支持 `?raw`,webpack 需要配置 raw-loader asset/source
52
47
  import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
53
48
  import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
54
49
  const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
@@ -121,7 +116,7 @@ import '@netless/appliance-plugin/dist/style.css';
121
116
  import { WhiteWebSdk } from "white-web-sdk";
122
117
  import { WindowManager } from "@netless/window-manager";
123
118
  import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
124
- // 引入worker.js方式可选, 如果走cdn,可以不用从dist中引入,如果从dist中引入,需要以资源模块方式并通过bolb内联形式配置到options.cdn中.如`?raw`,这个需要打包器的支持,vite默认支持`?raw`,webpack需要配置 raw-loader or asset/source.
119
+ // 引入 worker.js 方式可选,如果走 CDN,可以不用从 dist 中引入。如果从 dist 中引入,需要以资源模块方式并通过 blob 内联形式配置到 options.cdn 中。如 `?raw`,这个需要打包器的支持,vite 默认支持 `?raw`,webpack 需要配置 raw-loader asset/source
125
120
  import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
126
121
  import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
127
122
  const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
@@ -133,9 +128,9 @@ const whiteWebSdk = new WhiteWebSdk(...)
133
128
  const room = await whiteWebSdk.joinRoom({
134
129
  ...
135
130
  invisiblePlugins: [WindowManager, ApplianceMultiPlugin],
136
- useMultiViews: true,
131
+ useMultiViews: true,
137
132
  })
138
- const manager = await WindowManager.mount({ room , container:elm, chessboard: true, cursor: true, supportAppliancePlugin: true});
133
+ const manager = await WindowManager.mount({ room, container: elm, chessboard: true, cursor: true, supportAppliancePlugin: true});
139
134
  if (manager) {
140
135
  await manager.switchMainViewToWriter();
141
136
  await ApplianceMultiPlugin.getInstance(manager,
@@ -144,7 +139,7 @@ if (manager) {
144
139
  cdn: {
145
140
  fullWorkerUrl,
146
141
  subWorkerUrl,
147
- }
142
+ },
148
143
  ...
149
144
  }
150
145
  }
@@ -162,7 +157,7 @@ import '@netless/appliance-plugin/dist/style.css';
162
157
 
163
158
  import { WhiteWebSdk } from "white-web-sdk";
164
159
  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.
160
+ // 引入 worker.js 方式可选,如果走 CDN,可以不用从 dist 中引入。如果从 dist 中引入,需要以资源模块方式并通过 blob 内联形式配置到 options.cdn 中。如 `?raw`,这个需要打包器的支持,vite 默认支持 `?raw`,webpack 需要配置 raw-loader asset/source
166
161
  import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
167
162
  import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
168
163
  const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
@@ -176,7 +171,7 @@ const room = await whiteWebSdk.joinRoom({
176
171
  invisiblePlugins: [ApplianceSinglePlugin],
177
172
  wrappedComponents: [ApplianceSigleWrapper]
178
173
  })
179
- await ApplianceSinglePlugin.getInstance(room,
174
+ await ApplianceSinglePlugin.getInstance(room,
180
175
  {
181
176
  options: {
182
177
  cdn: {
@@ -216,22 +211,21 @@ module: {
216
211
 
217
212
  #### 优化原有接口
218
213
 
219
- 插件重新实现了一些room或windowmanager上的同名接口,但是我们内部已经通过`injectMethodToObject` 重新注入回原来的对象中.从而外部用户无需任何改动.如以下几个:
220
-
214
+ 插件重新实现了一些 room windowmanager 上的同名接口,但是我们内部已经通过 `injectMethodToObject` 重新注入回原来的对象中。从而外部用户无需任何改动。如以下几个:
221
215
  ```js
222
216
  // 内部 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");
217
+ injectMethodToObject(windowmanager, 'undo');
218
+ injectMethodToObject(windowmanager, 'redo');
219
+ injectMethodToObject(windowmanager,'cleanCurrentScene');
220
+ injectMethodToObject(windowmanager,'insertImage');
221
+ injectMethodToObject(windowmanager,'completeImageUpload');
222
+ injectMethodToObject(windowmanager,'lockImage');
223
+ injectMethodToObject(room,'getImagesInformation');
224
+ injectMethodToObject(room,'callbacks');
225
+ injectMethodToObject(room,'screenshotToCanvasAsync');
226
+ injectMethodToObject(room,'getBoundingRectAsync');
227
+ injectMethodToObject(room,'scenePreviewAsync');
228
+ injectMethodToObject(windowmanager.mainView,'setMemberState');
235
229
  // 这些我们可以通过前端日志看到调用行为,例如:
236
230
  // [ApplianceMultiPlugin] setMemberState
237
231
  // [ApplianceMultiPlugin] cleanCurrentScene
@@ -240,7 +234,6 @@ injectMethodToObject(windowmanager.mainView, "setMemberState");
240
234
  具体涉及以下接口:
241
235
 
242
236
  1. room上接口
243
-
244
237
  - [`setMemberState`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#setmemberstate)
245
238
  - [`undo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#undo)
246
239
  - [`redo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#redo)
@@ -251,14 +244,12 @@ injectMethodToObject(windowmanager.mainView, "setMemberState");
251
244
  - `getImagesInformation`
252
245
  - [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
253
246
 
254
- 2. windowmanager上接口
255
-
247
+ 2. WindowManager 接口
256
248
  - [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
257
249
  - [`canUndoSteps`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#canUndoSteps)
258
250
  - [`canRedoSteps`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#canUndoSteps)
259
251
 
260
- 3. windowmanagermainview上的接口
261
-
252
+ 3. WindowManager mainView 上的接口
262
253
  - [`setMemberState`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#setmemberstate)
263
254
  - [`undo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#undo)
264
255
  - [`redo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#redo)
@@ -269,331 +260,413 @@ injectMethodToObject(windowmanager.mainView, "setMemberState");
269
260
  - `getImagesInformation`
270
261
  - [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
271
262
 
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`获取
263
+ 4. 自定义接口
264
+ - `getBoundingRectAsync` - 替代接口 `room.getBoundingRect`
265
+ - `screenshotToCanvasAsync` - 替代接口 [room.screenshotToCanvas](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#screenshotToCanvas)
266
+ - `scenePreviewAsync` - 替代接口 [room.scenePreview](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#scenePreview)
267
+ - `fillSceneSnapshotAsync` - 替代接口 [room.fillSceneSnapshot](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#fillSceneSnapshot)
268
+ - `destroy` - 销毁 appliance-plugin 的实例
269
+ - `addListener` - 添加 appliance-plugin 内部事件监听器
270
+ - `removeListener` - 移除 appliance-plugin 内部事件监听器
271
+ - `disableDeviceInputs` - 替代接口 [room.disableDeviceInputs](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableDeviceInputs)
272
+ - `disableEraseImage` - 替代接口 [room.disableEraseImage](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableEraseImage) **该方法只禁止整体擦除的橡皮擦对图片的擦除,局部橡皮擦无效**
273
+ - `disableCameraTransform` - 替代接口 [room.disableCameraTransform](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableCameraTransform) (Version >=1.1.17)
274
+ - `insertText` - 在指定位置插入文字 (Version >=1.1.18)
275
+ - `updateText` - 编辑指定文字的内容 (Version >=1.1.18)
276
+ - `blurText` - 失去文本焦点 (Version >=1.1.19)
277
+ - `hasElements` - 指定场景下是否存在元素 (Version >=1.1.19)
278
+ - `getElements` - 获取场景下的所有元素 (Version >=1.1.19)
279
+ - `stopDraw` - 停止Draw事件 (Version >=1.1.19)
280
+ - `setViewLocalScenePathChange` - 设置白板本地场景路径变化 (Version >=1.1.27)
281
+
282
+ 5. 不兼容接口
283
+ - [`exportScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#exportScene) - appliance-plugin 开启后,笔记不能按 room 的方式导出
284
+ - [服务端截图](https://doc.shengwang.cn/doc/whiteboard/restful/fastboard-sdk/restful-wb/operations/post-v5-rooms-uuid-screenshots) - appliance-plugin 开启后,笔记不能通过调用服务端截图方式获取截图,而需要改用 `screenshotToCanvasAsync` 获取
296
285
 
297
286
  #### 新功能
287
+ ##### 激光铅笔教具 (Version >=1.1.1)
288
+ ```js
289
+ import { EStrokeType, ApplianceNames } from '@netless/appliance-plugin';
290
+ room.setMemberState({currentApplianceName: ApplianceNames.laserPen, strokeType: EStrokeType.Normal});
291
+ ```
292
+ ![Image](https://github.com/user-attachments/assets/3cd10c3a-b17b-4c01-b9d4-868c69116d96)
298
293
 
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
- ![Image](https://github.com/user-attachments/assets/3cd10c3a-b17b-4c01-b9d4-868c69116d96)
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
- ![Image](https://github.com/user-attachments/assets/fabe4ea7-db42-4c31-a751-10df4dd82807)
377
- - 设置笔记、图形边框透明度(马克笔):
378
-
379
- ```js
380
- setMemberState({ strokeOpacity: 0.5 });
381
- ```
382
-
383
- ![Image](https://github.com/user-attachments/assets/1aac265d-9643-4858-bcc6-a43af94ed73e)
384
- - 设置文字颜色、透明度、背景颜色、透明度
385
-
386
- ```js
387
- setMemberState({
388
- textOpacity: 0.5,
389
- textBgOpacity: 0.5,
390
- textBgColor: [0, 0, 0],
391
- });
392
- ```
393
-
394
- ![Image](https://github.com/user-attachments/assets/b59a9864-8f3f-4700-abee-2ccbe264cc86)
395
- - 设置图形填充色及透明度
396
-
397
- ```js
398
- setMemberState({ fillOpacity: 0.5, fillColor: [0, 0, 0] });
399
- ```
400
-
401
- ![Image](https://github.com/user-attachments/assets/468b930c-3db0-4355-87be-6b55af764799)
402
- - 自定义正多边形
403
-
404
- ```js
405
- // 正五边形
406
- setMemberState({
407
- currentApplianceName: ApplianceNames.shape,
408
- shapeType: ShapeType.Polygon,
409
- vertices: 5,
410
- });
411
- ```
412
-
413
- ![Image](https://github.com/user-attachments/assets/f34540f5-d779-42f9-bb8a-91250fcfe4e1)
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
- ![Image](https://github.com/user-attachments/assets/49215362-722a-47d3-998f-cc933a2b5126)
428
- - 自定义泡泡框方向
429
-
430
- ```js
431
- // 左下角提示框
432
- setMemberState({
433
- currentApplianceName: ApplianceNames.shape,
434
- shapeType: ShapeType.SpeechBalloon,
435
- placement: "bottomLeft",
436
- });
437
- ```
438
-
439
- ![Image](https://github.com/user-attachments/assets/6d52dedf-ca21-406d-a353-d801273b98bf)
440
-
441
- 3. 分屏显示笔记(小白板功能),需要结合[`@netless/app-little-white-board`](https://github.com/netless-io/app-little-white-board) (Version >=1.1.3)
442
- ![Image](https://github.com/user-attachments/assets/20810ea6-7d85-4e72-b75f-185599fffaf8)
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
- ![Image](https://github.com/user-attachments/assets/8888dc2f-ba66-4807-aa12-16530b3b8a3c)
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
- ``
294
+ ##### 扩展教具 (Version >=1.1.1)
295
+ 在原来的[白板教具](https://doc.shengwang.cn/api-ref/whiteboard/javascript/globals.html#memberstate)类型上,增加了一些扩展功能属性,如下:
296
+
297
+ ```js
298
+ export enum EStrokeType {
299
+ /** 实心线条 */
300
+ Normal = 'Normal',
301
+ /** 带笔锋线条 */
302
+ Stroke = 'Stroke',
303
+ /** 虚线线条 */
304
+ Dotted = 'Dotted',
305
+ /** 长虚线线条 */
306
+ LongDotted = 'LongDotted'
307
+ };
308
+ export type ExtendMemberState = {
309
+ /** 当前用户所选择的教具 */
310
+ currentApplianceName: ApplianceNames;
311
+ /** 是否开启笔锋 */
312
+ strokeType?: EStrokeType;
313
+ /** 是否删除整条线段 */
314
+ isLine?: boolean;
315
+ /** 线框透明度 */
316
+ strokeOpacity?: number;
317
+ /** 是否开启激光笔 */
318
+ useLaserPen?: boolean;
319
+ /** 激光笔保持时间, second */
320
+ duration?: number;
321
+ /** 填充样式 */
322
+ fillColor?: Color;
323
+ /** 填充透明度 */
324
+ fillOpacity?: number;
325
+ /** 使用 ``shape`` 教具时,绘制图形的具体类型 */
326
+ shapeType?: ShapeType;
327
+ /** 多边形顶点数 */
328
+ vertices?:number;
329
+ /** 多边形向内顶点步长 */
330
+ innerVerticeStep?:number;
331
+ /** 多边形向内顶点与外顶点半径比率 */
332
+ innerRatio?: number;
333
+ /** 文字透明度 */
334
+ textOpacity?: number;
335
+ /** 文字背景颜色 */
336
+ textBgColor?: Color;
337
+ /** 文字背景颜色透明度 */
338
+ textBgOpacity?: number;
339
+ /** 位置 */
340
+ placement?: SpeechBalloonPlacement;
341
+ };
342
+ import { ExtendMemberState, ApplianceNames } from '@netless/appliance-plugin';
343
+ /** 设置教具状态 */
344
+ room.setMemberState({ ... } as ExtendMemberState);
345
+ manager.mainView.setMemberState({ ... } as ExtendMemberState);
346
+ appliance.setMemberState({ ... } as ExtendMemberState);
347
+ ```
348
+ 1. 设置笔记类型:
349
+ ```js
350
+ // 实心线条
351
+ setMemberState({strokeType: EStrokeType.Normal });
352
+ // 带笔锋线条
353
+ setMemberState({strokeType: EStrokeType.Stroke });
354
+ // 虚线线条
355
+ setMemberState({strokeType: EStrokeType.Dotted });
356
+ // 长虚线线条
357
+ setMemberState({strokeType: EStrokeType.LongDotted });
358
+ ```
359
+ ![Image](https://github.com/user-attachments/assets/fabe4ea7-db42-4c31-a751-10df4dd82807)
360
+
361
+ 2. 设置笔记、图形边框透明度(马克笔):
362
+ ```js
363
+ setMemberState({strokeOpacity: 0.5 });
364
+ ```
365
+ ![Image](https://github.com/user-attachments/assets/1aac265d-9643-4858-bcc6-a43af94ed73e)
366
+
367
+ 3. 设置文字颜色、透明度、背景颜色、透明度
368
+ ```js
369
+ setMemberState({textOpacity: 0.5, textBgOpacity: 0.5, textBgColor:[0, 0, 0]});
370
+ ```
371
+ ![Image](https://github.com/user-attachments/assets/b59a9864-8f3f-4700-abee-2ccbe264cc86)
372
+
373
+ 4. 设置图形填充色及透明度
374
+ ```js
375
+ setMemberState({fillOpacity: 0.5, fillColor:[0, 0, 0]});
376
+ ```
377
+ ![Image](https://github.com/user-attachments/assets/468b930c-3db0-4355-87be-6b55af764799)
378
+
379
+ 5. 自定义正多边形
380
+ ```js
381
+ // 正五边形
382
+ setMemberState({currentApplianceName: ApplianceNames.shape, shapeType: ShapeType.Polygon, vertices: 5});
383
+ ```
384
+ ![Image](https://github.com/user-attachments/assets/f34540f5-d779-42f9-bb8a-91250fcfe4e1)
385
+
386
+ 6. 自定义星形
387
+ ```js
388
+ // 胖六角星
389
+ setMemberState({currentApplianceName: ApplianceNames.shape, shapeType: ShapeType.Star, vertices: 12, innerVerticeStep: 2, innerRatio: 0.8});
390
+ ```
391
+ ![Image](https://github.com/user-attachments/assets/49215362-722a-47d3-998f-cc933a2b5126)
392
+
393
+ 7. 自定义泡泡框方向
394
+ ```js
395
+ // 左下角提示框
396
+ setMemberState({currentApplianceName: ApplianceNames.shape, shapeType: ShapeType.SpeechBalloon, placement: 'bottomLeft'});
397
+ ```
398
+ ![Image](https://github.com/user-attachments/assets/6d52dedf-ca21-406d-a353-d801273b98bf)
399
+
400
+ ##### 分屏显示笔记(小白板功能),需要结合[`@netless/app-little-white-board`](https://github.com/netless-io/app-little-white-board) (Version >=1.1.3)
401
+ ![Image](https://github.com/user-attachments/assets/20810ea6-7d85-4e72-b75f-185599fffaf8)
402
+
403
+ ##### 小地图功能 (Version >=1.1.6)
404
+ ```js
405
+ /** 创建小地图
406
+ * @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
407
+ * @param div 小地图DOM容器
408
+ */
409
+ createMiniMap(viewId: string, div: HTMLElement): Promise<void>;
410
+ /** 销毁小地图 */
411
+ destroyMiniMap(viewId: string): Promise<boolean>;
412
+ ```
413
+ ![Image](https://github.com/user-attachments/assets/8888dc2f-ba66-4807-aa12-16530b3b8a3c)
414
+
415
+ ##### 文字编辑API (Version >=1.1.18)
416
+ ```js
417
+ /** 在指定位置插入文字
418
+ * @param x 第一个字的的左侧边中点,世界坐标系中的 x 坐标
419
+ * @param y 第一个字的的左侧边中点,世界坐标系中的 y 坐标
420
+ * @param textContent 初始化文字的内容,不传则为空
421
+ * @returns 该文字的标识符
422
+ */
423
+ insertText(x: number, y: number, textContent?: string): string | undefined;
424
+
425
+ /** 编辑指定文字的内容
426
+ * @param identifier 文字的标识符。为 insertText() 的返回值。
427
+ * @param textContent 文字要改成的内容
428
+ */
429
+ updateText(identifier: string, textContent: string): void;
430
+
431
+ /** 失去文本焦点 */
432
+ blurText(): void;
433
+ ```
434
+
435
+ ##### 元素查询API (Version >=1.1.19)
436
+ ```js
437
+ /** 指定场景下是否存在元素
438
+ * @param scenePath 场景路径, 默认取当前聚焦的场景
439
+ * @param filter 过滤条件
440
+ * @returns 是否存在元素
441
+ */
442
+ hasElements(
443
+ scenePath?: string,
444
+ filter?: (toolsType: EToolsKey) => boolean,
445
+ ): boolean;
446
+
447
+ /** 获取场景下的所有元素
448
+ * @param scenePath 场景路径, 默认取当前聚焦的场景
449
+ * @param filter 过滤条件
450
+ * @returns 所有元素
451
+ */
452
+ getElements(
453
+ scenePath?: string,
454
+ filter?: (toolsType: EToolsKey) => boolean,
455
+ ): BaseCollectorReducerAction[];
456
+ ```
457
+
458
+ ##### 过滤笔记 (Version >=1.1.6)
459
+ ```js
460
+ /** 过滤笔记
461
+ * @param viewId 多白板下的白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
462
+ * @param filter 过滤条件
463
+ * render: 笔记是否能要渲染, [uid1, uid2, ...] 或 true. true, 即都会渲染; [uid1, uid2, ...] 为指定渲染的用户uid集合
464
+ * hide: 笔记是否隐藏, [uid1, uid2, ...] 或 true. true, 即都要隐藏; [uid1, uid2, ...] 为指定隐藏的用户uid集合
465
+ * clear: 笔记是否可被擦除, [uid1, uid2, ...] 或 true. true, 即都可以被擦除; [uid1, uid2, ...] 为指定可被擦除的用户uid集合
466
+ * @param isSync 是否同步到白板房间中, 默认为true, 即设置会同步给所有用户
467
+ */
468
+ filterRenderByUid(viewId: string, filter: { render?: _ArrayTrue, hide?: _ArrayTrue, clear?: _ArrayTrue}, isSync?:boolean): void;
469
+ /** 取消过滤笔记
470
+ * @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
471
+ * @param isSync 是否同步到白板房间中, 默认为true, 即会同步到其他用户. 请保持和filterRenderByUid设置的一致
472
+ */
473
+ cancelFilterRender(viewId: string, isSync?:boolean): void;
474
+ ```
512
475
  ![Image](https://github.com/user-attachments/assets/7952ee1d-4f9c-4e86-802a-bac8e4ae6a51)
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;
476
+
477
+ ##### 设置白板本地场景路径变化 (Version >=1.1.27)
478
+ ```js
479
+ /** 设置白板本地场景路径变化
480
+ * @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的appID
481
+ * @param scenePath 要设置的场景路径
482
+ */
483
+ setViewLocalScenePathChange(viewId: string, scenePath: string): Promise<void>;
484
+ ```
485
+
486
+ ##### ExtrasOption自定义教具配置
487
+ 1. 自定义画笔样式
488
+ - 短虚线样式
489
+ ```ts
490
+ export type DottedOpt = {
491
+ /** 虚线端点样式, square: 平头, round: 圆头, 默认值为 round */
492
+ lineCap: "square" | "round";
493
+ /** 虚线,单线段长度, 默认值为 1, 即单线段长度为 1 */
494
+ segment: number;
495
+ /** 虚线,单线段间隔, 默认值为 2, 即单线段间隔为 2 * thickness */
496
+ gap: number;
497
+ };
498
+ /** 短虚线样式 */
499
+ dottedStroke: {
500
+ lineCap: "round",
501
+ segment: 1,
502
+ gap: 2,
503
+ },
504
+ ```
505
+ ![Image](https://github.com/user-attachments/assets/5dc7e2bf-c285-45f0-89d2-849b4792dc7e)
506
+ - 长虚线样式
507
+ ```ts
508
+ export type LongDottedOpt = {
509
+ /** 长虚线端点样式, square: 平头, round: 圆头, 默认值为 round */
510
+ lineCap: "square" | "round";
511
+ /** 长虚线,单线段长度, 默认值为 1, 即单线段长度为 1 * thickness */
512
+ segment: number;
513
+ /** 长虚线,单线段间隔, 默认值为 2, 即单线段间隔为 2 * thickness */
514
+ gap: number;
515
+ };
516
+ /** 长虚线线样式 */
517
+ longDottedStroke: {
518
+ lineCap: "round",
519
+ segment: 2,
520
+ gap: 3,
521
+ },
522
+ ```
523
+ ![Image](https://github.com/user-attachments/assets/a305c1a1-b366-444a-ace6-3e0ecbf5ad19)
524
+ - 普通画笔样式
525
+ ```ts
526
+ export type NormalOpt = {
527
+ /** 端点样式, square: 平头, round: 圆头, 默认值为 round */
528
+ lineCap: "square" | "round";
530
529
  };
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);
530
+ /** 普通画笔样式 */
531
+ normalStroke: {
532
+ lineCap: "round",
533
+ }
539
534
  ```
540
- ![Image](https://github.com/user-attachments/assets/c388691c-ae72-44ec-bbb7-e92c3a73c9c7) -->
535
+ ![Image](https://github.com/user-attachments/assets/23979f81-057a-408f-8302-de228ef00b4f)
536
+
537
+ 2. 文字自定义样式
538
+ ```ts
539
+ export type TextEditorOpt = {
540
+ /** 是否显示浮动栏 */
541
+ showFloatBar?: boolean;
542
+ /** 是否可以通过selector教具切换 */
543
+ canSelectorSwitch?: boolean;
544
+ /** 是否右边界自动换行 */
545
+ rightBoundBreak?: boolean;
546
+ /** 扩展字体列表 */
547
+ extendFontFaces?: { fontFamily: string; src: string }[];
548
+ /** 加载字体超时时间,单位:毫秒 */
549
+ loadFontFacesTimeout?: number;
550
+ };
551
+ // 比如: 设置统一字体库
552
+ textEditor: {
553
+ showFloatBar: false,
554
+ canSelectorSwitch: false,
555
+ rightBoundBreak: true,
556
+ extendFontFaces: [
557
+ {
558
+ fontFamily: "Noto Sans SC",
559
+ src: "https://fonts.gstatic.com/s/opensans/v44/memvYaGs126MiZpBA-UvWbX2vVnXBbObj2OVTS-mu0SC55I.woff2",
560
+ },
561
+ ],
562
+ loadFontFacesTimeout: 20000,
563
+ },
564
+ ```
565
+ 需要结合css style实现
566
+ ```css
567
+ @font-face {
568
+ font-family: "Noto Sans SC";
569
+ src: url("https://fonts.gstatic.com/s/opensans/v44/memvYaGs126MiZpBA-UvWbX2vVnXBbObj2OVTS-mu0SC55I.woff2")
570
+ format("woff2");
571
+ font-display: swap;
572
+ }
573
+ html {
574
+ font-family: "Noto Sans SC";
575
+ }
576
+ ```
577
+
578
+ ##### 手写图形自动联想功能:`autoDraw`,需要结合[@netless/appliance-extend-auto-draw-plugin](https://www.npmjs.com/package/@netless/appliance-extend-auto-draw-plugin)
579
+ ```js
580
+ export interface AutoDrawOptions {
581
+ /** 用于访问 OpenRouter 所有模型的 API 密钥 */
582
+ apiKey?: string;
583
+ /** 自定义使用的模型 */
584
+ customModel?: string;
585
+ /** 用于渲染图标的容器 */
586
+ container: HTMLDivElement;
587
+ /** 渲染图标的延迟时间,默认为 2000ms */
588
+ delay?: number;
589
+ /**
590
+ * 将文件上传到 OSS 服务器并返回 URL 地址,如果返回 undefined 则不会使用此功能
591
+ * @param file 文件对象
592
+ * @returns 图片 URL 字符串
593
+ */
594
+ uploadFile?: (file: File) => Promise<string | undefined>;
595
+ }
596
+ import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
597
+ import { AutoDrawPlugin } from '@netless/appliance-extend-auto-draw-plugin';
598
+ const plugin = await ApplianceMultiPlugin.getInstance(...);
599
+ const autoDrawPlugin = new AutoDrawPlugin({
600
+ container: topBarDiv,
601
+ delay: 2000
602
+ });
603
+ plugin.usePlugin(autoDrawPlugin);
604
+ ```
605
+ ![Image](https://github.com/user-attachments/assets/c388691c-ae72-44ec-bbb7-e92c3a73c9c7)
541
606
 
542
607
  ### 配置参数
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
608
+ `getInstance(wm: WindowManager | Room | Player, adaptor: ApplianceAdaptor)`
609
+ - `wm`: `WindowManager | Room | Player`。多窗口模式下传入的是 `WindowManager`,单窗口模式下传入的是 `Room` 或者 `Player`(白板回放模式)。
610
+ - `adaptor`: 配置适配器。
611
+ - `options: AppliancePluginOptions` - 必须配置,其中 `cdn` 为必填项。
612
+ ```js
550
613
  export type AppliancePluginOptions = {
551
614
  /** cdn配置项 */
552
615
  cdn: CdnOpt;
553
- /** 扩展配置项 */
616
+ /** 额外配置项 */
554
617
  extras?: ExtrasOptions;
555
- ...
618
+ };
619
+ export type CdnOpt = {
620
+ /** full worker url 地址, 绘制完整数据的线程 */
621
+ fullWorkerUrl?: string;
622
+ /** sub worker url 地址, 绘制一帧数据的线程 */
623
+ subWorkerUrl?: string;
624
+ };
625
+ export type ExtrasOptions = {
626
+ /** 是否使用简单模式, 默认值为 ``false``
627
+ * true: 简单模式:
628
+ 1、绘制将使用单worker绘制,画笔过程中无法使用贝塞尔圆滑处理。
629
+ 2、移除部分新功能:小地图、pointerPen(激光笔)、autoDraw插件。
630
+ */
631
+ useSimple: boolean;
632
+ /** 是否使用 worker, 默认值为 ``auto``
633
+ * auto: 自动选择(如果浏览器支持 offscreenCanvas 则使用 webWorker, 否则使用主线程)
634
+ * mainThread: 使用主线程, canvas 绘制数据。
635
+ */
636
+ useWorker?: UseWorkerType;
637
+ /** 同步数据配置项 */
638
+ syncOpt?: SyncOpt;
639
+ /** 画布配置项 */
640
+ canvasOpt?: CanvasOpt;
641
+ /** 指针配置项 */
642
+ cursor?: CursorOpt;
643
+ /** 画布缓存配置项 */
644
+ bufferSize?: BufferSizeOpt;
645
+ /** 贝塞尔优化配置项 */
646
+ bezier?: BezierOpt;
647
+ /** 局部橡皮擦配置项 */
648
+ pencilEraser?: PencilEraserOpt;
649
+ /** 线条粗细范围配置项 */
650
+ strokeWidth?: StrokeWidthOpt,
651
+ /** 文字编辑器配置项 */
652
+ textEditor?: TextEditorOpt;
653
+ /** 撤销重做配置项 */
654
+ undoRedo?: {
655
+ /** 是否启用全局撤销重做, 默认值为 false (Version >=1.1.27) */
656
+ enableGlobal?: boolean;
657
+ /** 撤销重做最大堆栈长度, 默认值为 20 */
658
+ maxStackLength?: number;
659
+ };
556
660
  }
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
- 对接过程中如果想了解和跟踪插件内部状态,可以通过以下几个控制台指令,查看内部数据.
661
+ ```
662
+ - `cursorAdapter?: CursorAdapter` - 非必填,单白板模式下,配置的自定义鼠标样式。
663
+ - `logger?: Logger` - 非必填,配置日志打印器对象。不填写默认在本地 console 输出,如果需要把日志上传到指定 server,则需要手动配置。
664
+ > 如需要上传到白板日志服务器,可以把 `room.logger` 配置到该项目。
594
665
 
666
+ ### 前端调试
667
+ 对接过程中如果想了解和跟踪插件内部状态,可以通过以下几个控制台指令,查看内部数据。
595
668
  ```js
596
- const applianPlugin = await ApplianceSinglePlugin.getInstance(...)
597
- appliancePlugin.currentManager // 可以查看到包版本号,内部状态等
598
- appliancePlugin.currentManager.consoleWorkerInfo() // 可以查看到worker上的绘制信息
669
+ const appliancePlugin = await ApplianceSinglePlugin.getInstance(...)
670
+ appliancePlugin.currentManager // 可以查看到包版本号,内部状态等
671
+ appliancePlugin.currentManager.consoleWorkerInfo() // 可以查看到 worker 上的绘制信息
599
672
  ```