@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/README.md CHANGED
@@ -10,8 +10,9 @@ appliance-plugin, Depend on [white-web-SDK](https://www.npmjs.com/package/white-
10
10
 
11
11
  ## Principle
12
12
 
13
- 1. The plugin is mainly based on the 2D functionality of SpriteJS, supports webgl2 rendering, and is backward compatible with downgrades to webgl and canvas2d
14
- 2. The plugin uses the dual webWorker+offscreenCanvas mechanism to process the drawing calculation + rendering logic in a separate worker thread. Does not occupy cpu tasks of the main thread.
13
+ 1. The plugin is mainly based on the 2D functionality of SpriteJS, supports WebGL2 rendering, and is backward compatible with downgrades to WebGL and Canvas2D.
14
+ 2. The plugin uses the dual WebWorker + OffscreenCanvas mechanism to process the drawing calculation and rendering logic in a separate worker thread, not occupying the CPU tasks of the main thread.
15
+ 3. For mobile terminals that do not support OffscreenCanvas, it will be processed in the main thread.
15
16
 
16
17
  ## Plugin usage
17
18
 
@@ -21,34 +22,30 @@ appliance-plugin, Depend on [white-web-SDK](https://www.npmjs.com/package/white-
21
22
  npm install @netless/appliance-plugin
22
23
  ```
23
24
 
24
- ### Sign up for plugins
25
-
26
- Plug-ins can support two scenarios, their access plug-in names are different:
27
-
28
- - Multi-window 'ApplianceMultiPlugin'
25
+ ### Register Plugin
29
26
 
27
+ Plugins can support two scenarios, they have different plugin names:
28
+ - Multi-window `ApplianceMultiPlugin`
30
29
  ```js
31
- import { ApplianceMultiPlugin } from "@netless/appliance-plugin";
30
+ import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
32
31
  ```
33
-
34
- - Single whiteboard 'ApplianceSinglePlugin'
35
-
32
+ - Single whiteboard `ApplianceSinglePlugin`
36
33
  ```js
37
- import { ApplianceSinglePlugin } from "@netless/appliance-plugin";
34
+ import { ApplianceSinglePlugin } from '@netless/appliance-plugin';
38
35
  ```
39
36
 
40
- > workerjs file cdn deployment
37
+ > **worker.js file CDN deployment**
41
38
  >
42
- > We used two-worker concurrency to improve drawing efficiency, which improved it by more than 40% over single-thread efficiency. However, the common dependencies on the two worker files are repeated, so building directly into the package will greatly increase the package size. So we allow the workerjs file cdn deployment by simply deploying the file under @netless/appliance-plugin/cdn into the cdn and then configuring the c of the last two workerjs via the second parameter of getInstance in the plug-in, options.cdn The dn address is fine. This solves the problem of excessive package size
39
+ > We use dual worker concurrency to improve drawing efficiency, which makes it more than 40% more efficient than the main thread. However, the common dependencies on the two worker files are duplicated, so if we build them directly into the package, it will greatly increase the package size. So we allow worker.js files to be deployed via CDN. Just deploy the files under `@netless/appliance-plugin/cdn` to the CDN, and then configure the CDN addresses of the two worker.js files in the second parameter `options.cdn` of `getInstance` in the plugin. This solves the problem of excessive package size.
43
40
  >
44
- > - **The total package is about 300kB, and the two wokerjs are 600kB each** If you need to consider the size of the package you are building, select Configure cdn.
45
-
46
- ### Access mode reference
41
+ > **The total package is about 400kB, and the two worker.js files are 800kB each.** If you need to consider the size of the build package, please choose to configure CDN.
47
42
 
48
- #### fastboard(interconnection with fastboard)
43
+ ### Access Mode Reference
49
44
 
45
+ #### fastboard (Direct integration with fastboard)
50
46
  ```js
51
- // The method of importing worker.js is optional. If cdn is used, it does not need to be imported from dist. If dist is imported, it needs to be configured into options.cdn in the form of resource module and bolb inline. Such as '?raw', this requires packer support,vite default support '?raw',webpack needs to configure raw-loader or asset/source.
47
+
48
+ // The method of importing worker.js is optional. If using CDN, you don't need to import from dist. If importing from dist, you need to configure it into options.cdn in the form of a resource module and blob inline. Such as `?raw`, this requires packer support. Vite supports `?raw` by default, webpack needs to configure raw-loader or asset/source.
52
49
  import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
53
50
  import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
54
51
  const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
@@ -56,10 +53,10 @@ const fullWorkerUrl = URL.createObjectURL(fullWorkerBlob);
56
53
  const subWorkerBlob = new Blob([subWorkerString], {type: 'text/javascript'});
57
54
  const subWorkerUrl = URL.createObjectURL(subWorkerBlob);
58
55
 
59
- // interconnection with fastboard-react
56
+ // Integration with fastboard-react
60
57
  // Full package mode reference
61
58
  // import { useFastboard, Fastboard } from "@netless/fastboard-react/full";
62
- // Subcontract reference
59
+ // Subpackage reference
63
60
  import { useFastboard, Fastboard } from "@netless/fastboard-react";
64
61
 
65
62
  const app = useFastboard(() => ({
@@ -83,10 +80,10 @@ const app = useFastboard(() => ({
83
80
  }
84
81
  }));
85
82
 
86
- // interconnection with fastboard
83
+ // Integration with fastboard
87
84
  // Full package mode reference
88
85
  // import { createFastboard, createUI } from "@netless/fastboard/full";
89
- // Subcontract reference
86
+ // Subpackage reference
90
87
  import { createFastboard, createUI } from "@netless/fastboard";
91
88
 
92
89
  const fastboard = await createFastboard({
@@ -111,15 +108,17 @@ const fastboard = await createFastboard({
111
108
  });
112
109
  ```
113
110
 
114
- #### Multi-window (Interconnecting with window-manager)
111
+ #### Multi-window (Direct integration with window-manager)
115
112
 
116
113
  ```js
114
+
117
115
  import '@netless/window-manager/dist/style.css';
118
116
  import '@netless/appliance-plugin/dist/style.css';
117
+
119
118
  import { WhiteWebSdk } from "white-web-sdk";
120
119
  import { WindowManager } from "@netless/window-manager";
121
120
  import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
122
- // The method of importing worker.js is optional. If cdn is used, it does not need to be imported from dist. If dist is imported, it needs to be configured into options.cdn in the form of resource module and bolb inline. Such as '?raw', this requires packer support,vite default support '?raw',webpack needs to configure raw-loader or asset/source.
121
+ // The method of importing worker.js is optional. If using CDN, you don't need to import from dist. If importing from dist, you need to configure it into options.cdn in the form of a resource module and blob inline. Such as `?raw`, this requires packer support. Vite supports `?raw` by default, webpack needs to configure raw-loader or asset/source.
123
122
  import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
124
123
  import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
125
124
  const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
@@ -133,30 +132,34 @@ const room = await whiteWebSdk.joinRoom({
133
132
  invisiblePlugins: [WindowManager, ApplianceMultiPlugin],
134
133
  useMultiViews: true,
135
134
  })
136
- const manager = await WindowManager.mount({ room , container:elm, chessboard: true, cursor: true, supportAppliancePlugin: true});
135
+ const manager = await WindowManager.mount({ room, container: elm, chessboard: true, cursor: true, supportAppliancePlugin: true});
137
136
  if (manager) {
138
- // await manager.switchMainViewToWriter();
139
- await ApplianceMultiPlugin.getInstance(manager,
137
+ await manager.switchMainViewToWriter();
138
+ await ApplianceMultiPlugin.getInstance(manager,
140
139
  {
141
140
  options: {
142
141
  cdn: {
143
142
  fullWorkerUrl,
144
143
  subWorkerUrl,
145
- }
144
+ },
145
+ ...
146
146
  }
147
147
  }
148
148
  );
149
149
  }
150
150
  ```
151
151
 
152
- > **Note** the css file `import '@netless/appliance-plugin/dist/style.css'` needs to be imported into the project;
152
+ > **Note** The project needs to import the CSS file `import '@netless/appliance-plugin/dist/style.css';`
153
153
 
154
- #### Single whiteboard (interconnection with white-web-sdk)
154
+ #### Single whiteboard (Direct integration with white-web-sdk)
155
155
 
156
156
  ```js
157
+
158
+ import '@netless/appliance-plugin/dist/style.css';
159
+
157
160
  import { WhiteWebSdk } from "white-web-sdk";
158
161
  import { ApplianceSinglePlugin, ApplianceSigleWrapper } from '@netless/appliance-plugin';
159
- // The method of importing worker.js is optional. If cdn is used, it does not need to be imported from dist. If dist is imported, it needs to be configured into options.cdn in the form of resource module and bolb inline. Such as '?raw', this requires packer support,vite default support '?raw',webpack needs to configure raw-loader or asset/source.
162
+ // The method of importing worker.js is optional. If using CDN, you don't need to import from dist. If importing from dist, you need to configure it into options.cdn in the form of a resource module and blob inline. Such as `?raw`, this requires packer support. Vite supports `?raw` by default, webpack needs to configure raw-loader or asset/source.
160
163
  import fullWorkerString from '@netless/appliance-plugin/dist/fullWorker.js?raw';
161
164
  import subWorkerString from '@netless/appliance-plugin/dist/subWorker.js?raw';
162
165
  const fullWorkerBlob = new Blob([fullWorkerString], {type: 'text/javascript'});
@@ -166,25 +169,26 @@ const subWorkerUrl = URL.createObjectURL(subWorkerBlob);
166
169
 
167
170
  const whiteWebSdk = new WhiteWebSdk(...)
168
171
  const room = await whiteWebSdk.joinRoom({
169
- ...
170
- invisiblePlugins: [ApplianceSinglePlugin],
171
- wrappedComponents: [ApplianceSigleWrapper]
172
+ ...
173
+ invisiblePlugins: [ApplianceSinglePlugin],
174
+ wrappedComponents: [ApplianceSigleWrapper]
172
175
  })
173
- await ApplianceSinglePlugin.getInstance(room,
176
+ await ApplianceSinglePlugin.getInstance(room,
174
177
  {
175
178
  options: {
176
179
  cdn: {
177
180
  fullWorkerUrl,
178
181
  subWorkerUrl,
179
182
  }
183
+ ...
180
184
  }
181
185
  }
182
186
  );
183
187
  ```
184
188
 
185
- > **Note** the css file `import '@netless/appliance-plugin/dist/style.css'` needs to be imported into the project;
189
+ > **Note** The project needs to import the CSS file `import '@netless/appliance-plugin/dist/style.css';`
186
190
 
187
- #### About ’?raw webpack configuration
191
+ #### About ?raw webpack configuration
188
192
 
189
193
  ```js
190
194
  module: {
@@ -203,310 +207,402 @@ module: {
203
207
  },
204
208
  ```
205
209
 
206
- ## Call introduction
207
-
208
- ### api introduction
209
-
210
- #### Optimize legacy interface
210
+ ## API Introduction
211
211
 
212
- The plugin re-implements some of the interfaces of the same name on room or Windows Manager, but internally we have re-injected them back into the original object via injectMethodToObject. No changes are required for external users. As follows:
212
+ #### Optimize Original Interfaces
213
213
 
214
+ The plugin re-implements some interfaces with the same name on room or windowmanager, but we have internally re-injected them back into the original object through `injectMethodToObject`. Therefore, external users do not need to make any changes. As follows:
214
215
  ```js
215
216
  // Internal hack
216
- injectMethodToObject(windowmanager, "undo");
217
- injectMethodToObject(windowmanager, "redo");
218
- injectMethodToObject(windowmanager, "cleanCurrentScene");
219
- injectMethodToObject(windowmanager, "insertImage");
220
- injectMethodToObject(windowmanager, "completeImageUpload");
221
- injectMethodToObject(windowmanager, "lockImage");
222
- injectMethodToObject(room, "getImagesInformation");
223
- injectMethodToObject(room, "callbacks");
224
- injectMethodToObject(room, "screenshotToCanvasAsync");
225
- injectMethodToObject(room, "getBoundingRectAsync");
226
- injectMethodToObject(room, "scenePreviewAsync");
227
- 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');
228
229
  // These we can see the call behavior through the front-end log, for example:
229
230
  // [ApplianceMultiPlugin] setMemberState
230
231
  // [ApplianceMultiPlugin] cleanCurrentScene
231
232
  ```
232
-
233
233
  The following interfaces are involved:
234
234
 
235
- 1. Interface on room
236
-
237
- - `setMemberState`
238
- - `undo`
239
- - `redo`
240
- - `callbacks`
241
- - `insertImage`
242
- - `lockImage`
243
- - `completeImageUpload`
235
+ 1. Interfaces on room
236
+ - [`setMemberState`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#setmemberstate)
237
+ - [`undo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#undo)
238
+ - [`redo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#redo)
239
+ - [`callbacks`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#callbacks)
240
+ - [`insertImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#insertImage)
241
+ - [`lockImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#lockImage)
242
+ - [`completeImageUpload`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#completeImageUpload)
243
+ - `getImagesInformation`
244
+ - [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
245
+
246
+ 2. WindowManager interfaces
247
+ - [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
248
+ - [`canUndoSteps`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#canUndoSteps)
249
+ - [`canRedoSteps`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#canRedoSteps)
250
+
251
+ 3. Interfaces on WindowManager's mainView
252
+ - [`setMemberState`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#setmemberstate)
253
+ - [`undo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#undo)
254
+ - [`redo`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#redo)
255
+ - [`callbacks`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#callbacks)
256
+ - [`insertImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#insertImage)
257
+ - [`lockImage`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#lockImage)
258
+ - [`completeImageUpload`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#completeImageUpload)
244
259
  - `getImagesInformation`
245
- - `cleanCurrentScene`
260
+ - [`cleanCurrentScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#cleanCurrentScene)
261
+
262
+ 4. Custom interfaces
263
+ - `getBoundingRectAsync` - Replace interface `room.getBoundingRect`
264
+ - `screenshotToCanvasAsync` - Replace interface [room.screenshotToCanvas](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#screenshotToCanvas)
265
+ - `scenePreviewAsync` - Replace interface [room.scenePreview](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#scenePreview)
266
+ - `fillSceneSnapshotAsync` - Replace interface [room.fillSceneSnapshot](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#fillSceneSnapshot)
267
+ - `destroy` - Destroy the instance of appliance-plugin
268
+ - `addListener` - Add appliance-plugin internal event listener
269
+ - `removeListener` - Remove appliance-plugin internal event listener
270
+ - `disableDeviceInputs` - Replace interface [room.disableDeviceInputs](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableDeviceInputs)
271
+ - `disableEraseImage` - Replace interface [room.disableEraseImage](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableEraseImage) **This method only prohibits the eraser that erases the entire image from erasing images, partial eraser is invalid**
272
+ - `disableCameraTransform` - Replace interface [room.disableCameraTransform](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#disableCameraTransform) (Version >=1.1.17)
273
+ - `insertText` - Insert text at the specified position (Version >=1.1.18)
274
+ - `updateText` - Edit the content of the specified text (Version >=1.1.18)
275
+ - `blurText` - Remove text focus (Version >=1.1.19)
276
+ - `hasElements` - Check if there are elements in the specified scene (Version >=1.1.19)
277
+ - `getElements` - Get all elements in the specified scene (Version >=1.1.19)
278
+ - `stopDraw` - Stop Draw event (Version >=1.1.19)
279
+ - `setViewLocalScenePathChange` - Set the local scene path change for the whiteboard view (Version >=1.1.27)
280
+
281
+ 5. Incompatible interfaces
282
+ - [`exportScene`](https://doc.shengwang.cn/api-ref/whiteboard/javascript/interfaces/room#exportScene) - After appliance-plugin is enabled, notes cannot be exported in room mode
283
+ - [Server-side screenshot](https://doc.shengwang.cn/doc/whiteboard/restful/fastboard-sdk/restful-wb/operations/post-v5-rooms-uuid-screenshots) - After appliance-plugin is enabled, notes cannot be obtained by calling server-side screenshot, but need to use `screenshotToCanvasAsync` to obtain the screenshot
284
+
285
+ #### New Features
286
+ ##### Laser Pen Tool (Version >=1.1.1)
287
+ ```js
288
+ import { EStrokeType, ApplianceNames } from '@netless/appliance-plugin';
289
+ room.setMemberState({currentApplianceName: ApplianceNames.laserPen, strokeType: EStrokeType.Normal});
290
+ ```
291
+ ![Image](https://github.com/user-attachments/assets/3cd10c3a-b17b-4c01-b9d4-868c69116d96)
292
+
293
+ ##### Extended Tools (Version >=1.1.1)
294
+ On the original [whiteboard tools](https://doc.shengwang.cn/api-ref/whiteboard/javascript/globals.html#memberstate) type, some extended function attributes have been added, as follows:
295
+
296
+ ```js
297
+ export enum EStrokeType {
298
+ /** Solid line */
299
+ Normal = 'Normal',
300
+ /** Line with pen edge */
301
+ Stroke = 'Stroke',
302
+ /** Dotted line */
303
+ Dotted = 'Dotted',
304
+ /** Long dotted line */
305
+ LongDotted = 'LongDotted'
306
+ };
307
+ export type ExtendMemberState = {
308
+ /** The tool selected by the current user */
309
+ currentApplianceName: ApplianceNames;
310
+ /** Whether to enable pen edge */
311
+ strokeType?: EStrokeType;
312
+ /** Whether to delete the entire line segment */
313
+ isLine?: boolean;
314
+ /** Stroke transparency */
315
+ strokeOpacity?: number;
316
+ /** Whether to enable laser pointer */
317
+ useLaserPen?: boolean;
318
+ /** Laser pointer holding time, second */
319
+ duration?: number;
320
+ /** Fill style */
321
+ fillColor?: Color;
322
+ /** Fill transparency */
323
+ fillOpacity?: number;
324
+ /** The specific type of graph to draw when using ``shape`` tool */
325
+ shapeType?: ShapeType;
326
+ /** Number of polygon vertices */
327
+ vertices?:number;
328
+ /** Inner vertex step length of polygon */
329
+ innerVerticeStep?:number;
330
+ /** Ratio of inner vertex radius to outer vertex radius of polygon */
331
+ innerRatio?: number;
332
+ /** Text transparency */
333
+ textOpacity?: number;
334
+ /** Text background color */
335
+ textBgColor?: Color;
336
+ /** Text background color transparency */
337
+ textBgOpacity?: number;
338
+ /** Placement */
339
+ placement?: SpeechBalloonPlacement;
340
+ };
341
+ import { ExtendMemberState, ApplianceNames } from '@netless/appliance-plugin';
342
+ /** Set tool state */
343
+ room.setMemberState({ ... } as ExtendMemberState);
344
+ manager.mainView.setMemberState({ ... } as ExtendMemberState);
345
+ appliance.setMemberState({ ... } as ExtendMemberState);
346
+ ```
347
+ 1. Set stroke type:
348
+ ```js
349
+ // Solid line
350
+ setMemberState({strokeType: EStrokeType.Normal });
351
+ // Line with pen edge
352
+ setMemberState({strokeType: EStrokeType.Stroke });
353
+ // Dotted line
354
+ setMemberState({strokeType: EStrokeType.Dotted });
355
+ // Long dotted line
356
+ setMemberState({strokeType: EStrokeType.LongDotted });
357
+ ```
358
+ ![Image](https://github.com/user-attachments/assets/fabe4ea7-db42-4c31-a751-10df4dd82807)
246
359
 
247
- 2. windowmanager upper interface
360
+ 2. Set stroke and shape border opacity (marker):
361
+ ```js
362
+ setMemberState({strokeOpacity: 0.5 });
363
+ ```
364
+ ![Image](https://github.com/user-attachments/assets/1aac265d-9643-4858-bcc6-a43af94ed73e)
248
365
 
249
- - `cleanCurrentScene`
366
+ 3. Set text color, opacity, background color, and opacity
367
+ ```js
368
+ setMemberState({textOpacity: 0.5, textBgOpacity: 0.5, textBgColor:[0, 0, 0]});
369
+ ```
370
+ ![Image](https://github.com/user-attachments/assets/b59a9864-8f3f-4700-abee-2ccbe264cc86)
250
371
 
251
- 3. The mainview interface of windowmanager
372
+ 4. Set shape fill color and opacity
373
+ ```js
374
+ setMemberState({fillOpacity: 0.5, fillColor:[0, 0, 0]});
375
+ ```
376
+ ![Image](https://github.com/user-attachments/assets/468b930c-3db0-4355-87be-6b55af764799)
252
377
 
253
- - `setMemberState`
254
- - `undo`
255
- - `redo`
256
- - `callbacks`
257
- - `insertImage`
258
- - `lockImage`
259
- - `completeImageUpload`
260
- - `getImagesInformation`
261
- - `cleanCurrentScene`
262
-
263
- 4. Customize
264
-
265
- - `getBoundingRectAsync` Replace the api `room.getBoundingRect`
266
- - `screenshotToCanvasAsync` Replace the api `room.screenshotToCanvas`
267
- - `scenePreviewAsync` Replace the api `room.scenePreview`
268
- - `destroy` Destroy the instance of appliance-plugin
269
- - `addListener` add appliance plugin Listener
270
- - `removeListener` remove appliance plugin Listener
271
- - `disableDeviceInputs` Replace the api `room.disableDeviceInputs`
272
- - `disableEraseImage` Replace the api `room.disableEraseImage` **This method only suppert when currentApplianceName is `eraser`**
273
- - `disableCameraTransform` Replace the api `room.disableCameraTransform` (Version >=1.1.17)
274
- - `insertText` Insert text at the specified position (Version >=1.1.18)
275
- - `updateText` Update the content of the specified text (Version >=1.1.18)
276
- - `blurText` Remove text focus (Version >=1.1.19)
277
- - `hasElements` Check if there are elements in the specified scene (Version >=1.1.19)
278
- - `getElements` Get all elements in the specified scene (Version >=1.1.19)
279
- - `stopDraw` Stop draw event (Version >=1.1.19)
280
- - `setViewLocalScenePathChange` Set the local scene path change for the whiteboard view (Version >=1.1.27)
281
-
282
- 5.Incompatible
283
-
284
- - `exportScene` When the appliance-plugin is enabled, notes cannot be exported in room mode
285
- - Server-side screenshot, after the appliance-plugin is turned on, notes cannot be obtained by calling server-side screenshot, but need to use `screenshotToCanvasAsync` to obtain the screenshot
286
-
287
- #### New features
288
-
289
- 1. laserPen teaching aids (Version >=1.1.1)
290
- ```js
291
- import { EStrokeType, ApplianceNames } from "@netless/appliance-plugin";
292
- room.setMemberState({
293
- currentApplianceName: ApplianceNames.laserPen,
294
- strokeType: EStrokeType.Normal,
295
- });
296
- ```
297
- ![Image](https://github.com/user-attachments/assets/3cd10c3a-b17b-4c01-b9d4-868c69116d96)
298
- 2. Extended Teaching AIDS (Version >=1.1.1)
299
-
300
- ```js
301
- export enum EStrokeType {
302
- /** Solid line */
303
- Normal = 'Normal',
304
- /** Line with pen edge */
305
- Stroke = 'Stroke',
306
- /** Dotted line */
307
- Dotted = 'Dotted',
308
- /** Long dotted line */
309
- LongDotted = 'LongDotted'
310
- };
311
- export type ExtendMemberState = {
312
- /** The teaching AIDS selected by the current user */
313
- currentApplianceName: ApplianceNames;
314
- /** Whether to open the pen tip */
315
- strokeType? : EStrokeType;
316
- /** Whether to delete the entire line segment */
317
- isLine? : boolean;
318
- /** Wireframe transparency */
319
- strokeOpacity? : number;
320
- /** Whether to turn on laser pointer */
321
- useLaserPen? : boolean;
322
- /** Laser pointer holding time, second */
323
- duration? : number;
324
- /** Fill style */
325
- fillColor? : Color;
326
- /** Fill transparency */
327
- fillOpacity? : number;
328
- /** The specific type of graph to draw when using shape */
329
- shapeType? : ShapeType;
330
- /** Number of polygon vertices */
331
- vertices? :number;
332
- /** Length of the inner vertex of the polygon */
333
- innerVerticeStep? :number;
334
- /** Ratio of the radius of the inner vertex of the polygon to the outer vertex */
335
- innerRatio? : number;
336
- /** Text transparency */
337
- textOpacity? : number;
338
- /** Text background color */
339
- textBgColor? : Color;
340
- /** Text background color transparency */
341
- textBgOpacity? : number;
342
- /** Location */
343
- placement? : SpeechBalloonPlacement;
344
- };
345
- import { ExtendMemberState, ApplianceNames } from '@netless/appliance-plugin';
346
- /** Set the state of teaching AIDS */
347
- room.setMemberState({ ... } as ExtendMemberState);
348
- manager.mainView.setMemberState({ ... } as ExtendMemberState);
349
- appliance.setMemberState({ ... } as ExtendMemberState);
350
- ```
351
-
352
- - Set stroke type:
353
-
354
- ```js
355
- // Solid line
356
- setMemberState({ strokeType: EStrokeType.Normal });
357
- // Line with pen edge
358
- setMemberState({ strokeType: EStrokeType.Stroke });
359
- // Dotted line
360
- setMemberState({ strokeType: EStrokeType.Dotted });
361
- // Long dotted line
362
- setMemberState({ strokeType: EStrokeType.LongDotted });
363
- ```
364
-
365
- ![Image](https://github.com/user-attachments/assets/fabe4ea7-db42-4c31-a751-10df4dd82807)
366
- - Set stroke and shape border opacity (marker):
367
-
368
- ```js
369
- setMemberState({ strokeOpacity: 0.5 });
370
- ```
371
-
372
- ![Image](https://github.com/user-attachments/assets/1aac265d-9643-4858-bcc6-a43af94ed73e)
373
- - Set text color, text opacity, text background color, text background opacity
374
-
375
- ```js
376
- setMemberState({
377
- textOpacity: 0.5,
378
- textBgOpacity: 0.5,
379
- textBgColor: [0, 0, 0],
380
- });
381
- ```
382
-
383
- ![Image](https://github.com/user-attachments/assets/b59a9864-8f3f-4700-abee-2ccbe264cc86)
384
- - Set shape fill color and fill opacity
385
-
386
- ```js
387
- setMemberState({ fillOpacity: 0.5, fillColor: [0, 0, 0] });
388
- ```
389
-
390
- ![Image](https://github.com/user-attachments/assets/468b930c-3db0-4355-87be-6b55af764799)
391
- - Custom regular polygon
392
-
393
- ```js
394
- // regular pentagon
395
- setMemberState({
396
- currentApplianceName: ApplianceNames.shape,
397
- shapeType: ShapeType.Polygon,
398
- vertices: 5,
399
- });
400
- ```
401
-
402
- ![Image](https://github.com/user-attachments/assets/f34540f5-d779-42f9-bb8a-91250fcfe4e1)
403
- - Custom star shape
404
-
405
- ```js
406
- // fat hexagonal star
407
- setMemberState({
408
- currentApplianceName: ApplianceNames.shape,
409
- shapeType: ShapeType.Star,
410
- vertices: 12,
411
- innerVerticeStep: 2,
412
- innerRatio: 0.8,
413
- });
414
- ```
415
-
416
- ![Image](https://github.com/user-attachments/assets/49215362-722a-47d3-998f-cc933a2b5126)
417
- - Customize the placement of the speechballoon
418
-
419
- ```js
420
- // The dialog box in the lower left corner
421
- setMemberState({
422
- currentApplianceName: ApplianceNames.shape,
423
- shapeType: ShapeType.SpeechBalloon,
424
- placement: "bottomLeft",
425
- });
426
- ```
427
-
428
- ![Image](https://github.com/user-attachments/assets/6d52dedf-ca21-406d-a353-d801273b98bf)
429
-
430
- 3. Split screen display Elements (little whiteboard featrue), need to combine [`@netless/app-little-white-board`](https://github.com/netless-io/app-little-white-board) (Version >=1.1.3)
431
- ![Image](https://github.com/user-attachments/assets/20810ea6-7d85-4e72-b75f-185599fffaf8)
432
- 4. Text editing APIs (Version >=1.1.18)
433
- ```js
434
- /** Insert text at the specified position
435
- * @param x The x coordinate of the left edge midpoint of the first character in the world coordinate system
436
- * @param y The y coordinate of the left edge midpoint of the first character in the world coordinate system
437
- * @param textContent Initial text content, empty if not provided
438
- * @returns The identifier of the text
439
- */
440
- insertText(x: number, y: number, textContent?: string): string | undefined;
441
-
442
- /** Update the content of the specified text
443
- * @param identifier The identifier of the text, returned by insertText()
444
- * @param textContent The new content of the text
445
- */
446
- updateText(identifier: string, textContent: string): void;
447
-
448
- /** Remove text focus */
449
- blurText(): void;
450
- ```
451
- 5. Element query APIs (Version >=1.1.19)
452
- ```js
453
- /** Check if there are elements in the specified scene
454
- * @param scenePath Scene path, defaults to the currently focused scene
455
- * @param filter Filter condition
456
- * @returns Whether elements exist
457
- */
458
- hasElements(
459
- scenePath?: string,
460
- filter?: (toolsType: EToolsKey) => boolean,
461
- ): boolean;
462
-
463
- /** Get all elements in the specified scene
464
- * @param scenePath Scene path, defaults to the currently focused scene
465
- * @param filter Filter condition
466
- * @returns All elements
467
- */
468
- getElements(
469
- scenePath?: string,
470
- filter?: (toolsType: EToolsKey) => boolean,
471
- ): BaseCollectorReducerAction[];
472
- ```
473
- 6. Minimap function (Version >=1.1.6)
474
- ```js
475
- /** Create a minimap
476
- * @param viewId ID of the whiteboard under windowManager. The ID of the main whiteboard is mainView, and the ID of other whiteboards is the appID of addApp() return
477
- * @param div Small map DOM container
478
- */
479
- createMiniMap(viewId: string, div: HTMLElement): Promise<void>;
480
- /** Destroy minimap */
481
- destroyMiniMap(viewId: string): Promise<void>;
482
- ```
483
- ![Image](https://github.com/user-attachments/assets/8888dc2f-ba66-4807-aa12-16530b3b8a3c)
484
- 7. Filter Elements (Version >=1.1.6)
485
- `js
486
- /** Filter Elements
487
- * @param viewId ID of the whiteboard under windowManager. The ID of the main whiteboard is mainView, and the ID of other whiteboards is the appID of addApp() return
488
- * @param filter filter condition
489
- * render: Whether notes can be rendered, [uid1, uid2,...] Or true. true, that is, both render, [uid1, uid2,...] The collection of user Uids rendered for the specified
490
- * hide: Note is hidden, [uid1, uid2,...] Or true. true, that is to hide, [uid1, uid2,...] To specify a hidden user uid collection
491
- * clear: Whether notes can be cleared, [uid1, uid2,...] Or true. true, that is, can be cleared, [uid1, uid2,...] Specifies a collection of user Uids that can be cleared
492
- * @param isSync Whether to synchronize data to other users. The default value is true, that is, the data will be synchronized to other users
493
- */
494
- filterRenderByUid(viewId: string, filter: { render?: _ArrayTrue, hide?: _ArrayTrue, clear?: _ArrayTrue}, isSync?:boolean): void;
495
- /** Filter Elements
496
- * @param viewId ID of the whiteboard under windowManager. The ID of the main whiteboard is mainView, and the ID of other whiteboards is the appID of addApp() return
497
- * @param isSync Whether to synchronize data to other users. The default value is true, that is, the data will be synchronized to other users. Keep it the same as the filterRenderByUid setting
498
- */
499
- cancelFilterRender(viewId: string, isSync?:boolean): void;
500
- `
378
+ 5. Custom regular polygon
379
+ ```js
380
+ // Regular pentagon
381
+ setMemberState({currentApplianceName: ApplianceNames.shape, shapeType: ShapeType.Polygon, vertices: 5});
382
+ ```
383
+ ![Image](https://github.com/user-attachments/assets/f34540f5-d779-42f9-bb8a-91250fcfe4e1)
384
+
385
+ 6. Custom star shape
386
+ ```js
387
+ // Fat hexagonal star
388
+ setMemberState({currentApplianceName: ApplianceNames.shape, shapeType: ShapeType.Star, vertices: 12, innerVerticeStep: 2, innerRatio: 0.8});
389
+ ```
390
+ ![Image](https://github.com/user-attachments/assets/49215362-722a-47d3-998f-cc933a2b5126)
391
+
392
+ 7. Custom speech balloon placement
393
+ ```js
394
+ // Speech balloon in the lower left corner
395
+ setMemberState({currentApplianceName: ApplianceNames.shape, shapeType: ShapeType.SpeechBalloon, placement: 'bottomLeft'});
396
+ ```
397
+ ![Image](https://github.com/user-attachments/assets/6d52dedf-ca21-406d-a353-d801273b98bf)
398
+
399
+ ##### Split screen display notes (little whiteboard feature), need to combine [`@netless/app-little-white-board`](https://github.com/netless-io/app-little-white-board) (Version >=1.1.3)
400
+ ![Image](https://github.com/user-attachments/assets/20810ea6-7d85-4e72-b75f-185599fffaf8)
401
+
402
+ ##### Minimap function (Version >=1.1.6)
403
+ ```js
404
+ /** Create a minimap
405
+ * @param viewId ID of the whiteboard under multi-whiteboard, the main whiteboard ID is `mainView`, other whiteboard IDs are the appID returned by addApp()
406
+ * @param div Minimap DOM container
407
+ */
408
+ createMiniMap(viewId: string, div: HTMLElement): Promise<void>;
409
+ /** Destroy minimap */
410
+ destroyMiniMap(viewId: string): Promise<boolean>;
411
+ ```
412
+ ![Image](https://github.com/user-attachments/assets/8888dc2f-ba66-4807-aa12-16530b3b8a3c)
413
+
414
+ ##### Text editing API (Version >=1.1.18)
415
+ ```js
416
+ /** Insert text at the specified position
417
+ * @param x The x coordinate of the left edge midpoint of the first character in the world coordinate system
418
+ * @param y The y coordinate of the left edge midpoint of the first character in the world coordinate system
419
+ * @param textContent Initial text content, empty if not provided
420
+ * @returns The identifier of the text
421
+ */
422
+ insertText(x: number, y: number, textContent?: string): string | undefined;
423
+
424
+ /** Edit the content of the specified text
425
+ * @param identifier The identifier of the text, returned by insertText()
426
+ * @param textContent The new content of the text
427
+ */
428
+ updateText(identifier: string, textContent: string): void;
429
+
430
+ /** Remove text focus */
431
+ blurText(): void;
432
+ ```
433
+
434
+ ##### Element query API (Version >=1.1.19)
435
+ ```js
436
+ /** Check if there are elements in the specified scene
437
+ * @param scenePath Scene path, defaults to the currently focused scene
438
+ * @param filter Filter condition
439
+ * @returns Whether elements exist
440
+ */
441
+ hasElements(
442
+ scenePath?: string,
443
+ filter?: (toolsType: EToolsKey) => boolean,
444
+ ): boolean;
445
+
446
+ /** Get all elements in the specified scene
447
+ * @param scenePath Scene path, defaults to the currently focused scene
448
+ * @param filter Filter condition
449
+ * @returns All elements
450
+ */
451
+ getElements(
452
+ scenePath?: string,
453
+ filter?: (toolsType: EToolsKey) => boolean,
454
+ ): BaseCollectorReducerAction[];
455
+ ```
456
+
457
+ ##### Filter notes (Version >=1.1.6)
458
+ ```js
459
+ /** Filter notes
460
+ * @param viewId ID of the whiteboard under multi-whiteboard, the main whiteboard ID is `mainView`, other whiteboard IDs are the appID returned by addApp()
461
+ * @param filter Filter condition
462
+ * render: Whether notes can be rendered, [uid1, uid2, ...] or true. true means all will be rendered; [uid1, uid2, ...] is the specified set of user uids to render
463
+ * hide: Whether notes are hidden, [uid1, uid2, ...] or true. true means all will be hidden; [uid1, uid2, ...] is the specified set of user uids to hide
464
+ * clear: Whether notes can be erased, [uid1, uid2, ...] or true. true means all can be erased; [uid1, uid2, ...] is the specified set of user uids that can be erased
465
+ * @param isSync Whether to synchronize to the whiteboard room, default is true, meaning the setting will be synchronized to all users
466
+ */
467
+ filterRenderByUid(viewId: string, filter: { render?: _ArrayTrue, hide?: _ArrayTrue, clear?: _ArrayTrue}, isSync?:boolean): void;
468
+ /** Cancel filter notes
469
+ * @param viewId ID of the whiteboard under multi-whiteboard, the main whiteboard ID is `mainView`, other whiteboard IDs are the appID returned by addApp()
470
+ * @param isSync Whether to synchronize to the whiteboard room, default is true, meaning it will be synchronized to other users. Please keep it consistent with the filterRenderByUid setting
471
+ */
472
+ cancelFilterRender(viewId: string, isSync?:boolean): void;
473
+ ```
501
474
  ![Image](https://github.com/user-attachments/assets/7952ee1d-4f9c-4e86-802a-bac8e4ae6a51)
502
- 8. Set view local scene path change (Version >=1.1.27)
503
- ```js
504
- /** Set the local scene path change for the whiteboard view
505
- * @param viewId ID of the whiteboard under windowManager. The ID of the main whiteboard is mainView, and the ID of other whiteboards is the appID of addApp() return
506
- * @param scenePath The scene path to set
507
- */
508
- setViewLocalScenePathChange(viewId: string, scenePath: string): Promise<void>;
509
- ```
475
+
476
+ ##### Set whiteboard local scene path change (Version >=1.1.27)
477
+ ```js
478
+ /** Set whiteboard local scene path change
479
+ * @param viewId ID of the whiteboard under multi-whiteboard, the main whiteboard ID is `mainView`, other whiteboard IDs are the appID returned by addApp()
480
+ * @param scenePath The scene path to set
481
+ */
482
+ setViewLocalScenePathChange(viewId: string, scenePath: string): Promise<void>;
483
+ ```
484
+
485
+ ##### ExtrasOption custom tool configuration
486
+ 1. Custom stroke styles
487
+ - Short dotted line style
488
+ ```ts
489
+ export type DottedOpt = {
490
+ /** Dotted line endpoint style, square: flat, round: round, default is round */
491
+ lineCap: "square" | "round";
492
+ /** Dotted line, single segment length, default is 1, meaning single segment length is 1 */
493
+ segment: number;
494
+ /** Dotted line, single segment gap, default is 2, meaning single segment gap is 2 * thickness */
495
+ gap: number;
496
+ };
497
+ /** Short dotted line style */
498
+ dottedStroke: {
499
+ lineCap: "round",
500
+ segment: 1,
501
+ gap: 2,
502
+ },
503
+ ```
504
+ ![Image](https://github.com/user-attachments/assets/5dc7e2bf-c285-45f0-89d2-849b4792dc7e)
505
+ - Long dotted line style
506
+ ```ts
507
+ export type LongDottedOpt = {
508
+ /** Long dotted line endpoint style, square: flat, round: round, default is round */
509
+ lineCap: "square" | "round";
510
+ /** Long dotted line, single segment length, default is 1, meaning single segment length is 1 * thickness */
511
+ segment: number;
512
+ /** Long dotted line, single segment gap, default is 2, meaning single segment gap is 2 * thickness */
513
+ gap: number;
514
+ };
515
+ /** Long dotted line style */
516
+ longDottedStroke: {
517
+ lineCap: "round",
518
+ segment: 2,
519
+ gap: 3,
520
+ },
521
+ ```
522
+ ![Image](https://github.com/user-attachments/assets/a305c1a1-b366-444a-ace6-3e0ecbf5ad19)
523
+ - Normal stroke style
524
+ ```ts
525
+ export type NormalOpt = {
526
+ /** Endpoint style, square: flat, round: round, default is round */
527
+ lineCap: "square" | "round";
528
+ };
529
+ /** Normal stroke style */
530
+ normalStroke: {
531
+ lineCap: "round",
532
+ }
533
+ ```
534
+ ![Image](https://github.com/user-attachments/assets/23979f81-057a-408f-8302-de228ef00b4f)
535
+
536
+ 2. Text custom styles
537
+ ```ts
538
+ export type TextEditorOpt = {
539
+ /** Whether to show float bar */
540
+ showFloatBar?: boolean;
541
+ /** Whether can switch by selector tool */
542
+ canSelectorSwitch?: boolean;
543
+ /** Whether right boundary auto wrap */
544
+ rightBoundBreak?: boolean;
545
+ /** Extended font list */
546
+ extendFontFaces?: { fontFamily: string; src: string }[];
547
+ /** Font loading timeout, unit: milliseconds */
548
+ loadFontFacesTimeout?: number;
549
+ };
550
+ // For example: set unified font library
551
+ textEditor: {
552
+ showFloatBar: false,
553
+ canSelectorSwitch: false,
554
+ rightBoundBreak: true,
555
+ extendFontFaces: [
556
+ {
557
+ fontFamily: "Noto Sans SC",
558
+ src: "https://fonts.gstatic.com/s/opensans/v44/memvYaGs126MiZpBA-UvWbX2vVnXBbObj2OVTS-mu0SC55I.woff2",
559
+ },
560
+ ],
561
+ loadFontFacesTimeout: 20000,
562
+ },
563
+ ```
564
+ Need to combine CSS style implementation
565
+ ```css
566
+ @font-face {
567
+ font-family: "Noto Sans SC";
568
+ src: url("https://fonts.gstatic.com/s/opensans/v44/memvYaGs126MiZpBA-UvWbX2vVnXBbObj2OVTS-mu0SC55I.woff2")
569
+ format("woff2");
570
+ font-display: swap;
571
+ }
572
+ html {
573
+ font-family: "Noto Sans SC";
574
+ }
575
+ ```
576
+
577
+ ##### Handwriting graphics automatic association function:`autoDraw`, need to combine [@netless/appliance-extend-auto-draw-plugin](https://www.npmjs.com/package/@netless/appliance-extend-auto-draw-plugin)
578
+ ```js
579
+ export interface AutoDrawOptions {
580
+ /** API key for accessing all OpenRouter models */
581
+ apiKey?: string;
582
+ /** Custom model to use */
583
+ customModel?: string;
584
+ /** Container for rendering icons */
585
+ container: HTMLDivElement;
586
+ /** Delay time for rendering icons, default is 2000ms */
587
+ delay?: number;
588
+ /**
589
+ * Upload file to OSS server and return URL address, if returns undefined then this feature will not be used
590
+ * @param file File object
591
+ * @returns Image URL string
592
+ */
593
+ uploadFile?: (file: File) => Promise<string | undefined>;
594
+ }
595
+ import { ApplianceMultiPlugin } from '@netless/appliance-plugin';
596
+ import { AutoDrawPlugin } from '@netless/appliance-extend-auto-draw-plugin';
597
+ const plugin = await ApplianceMultiPlugin.getInstance(...);
598
+ const autoDrawPlugin = new AutoDrawPlugin({
599
+ container: topBarDiv,
600
+ delay: 2000
601
+ });
602
+ plugin.usePlugin(autoDrawPlugin);
603
+ ```
604
+ ![Image](https://github.com/user-attachments/assets/c388691c-ae72-44ec-bbb7-e92c3a73c9c7)
605
+
510
606
  <!-- 9. Handwriting graphics automatic association function: 'autoDraw' (version >=1.1.7)
511
607
  ```js
512
608
  export type AutoDrawOptions = {
@@ -528,60 +624,69 @@ The following interfaces are involved:
528
624
  ```
529
625
  ![Image](https://github.com/user-attachments/assets/c388691c-ae72-44ec-bbb7-e92c3a73c9c7) -->
530
626
 
531
- ### Configure parameters
532
-
533
- `getInstance(wm: WindowManager, adaptor: ApplianceAdaptor)`
534
-
535
- - wm: WindowManager\room\player. In multi-window mode, you pass WindowManager, and in single-window mode, you pass room or player(whiteboard playback mode).
536
- - adaptor: configures the adapter.
537
- - `options: AppliancePluginOptions`; The cdn addresses of both workers must be configured.
538
- ```js
627
+ ### Configuration Parameters
628
+ `getInstance(wm: WindowManager | Room | Player, adaptor: ApplianceAdaptor)`
629
+ - `wm`: `WindowManager | Room | Player`. In multi-window mode, pass `WindowManager`, in single-window mode, pass `Room` or `Player` (whiteboard playback mode).
630
+ - `adaptor`: Configuration adapter.
631
+ - `options: AppliancePluginOptions` - Must be configured, where `cdn` is required.
632
+ ```js
539
633
  export type AppliancePluginOptions = {
540
- /** cdn Configuration item */
634
+ /** CDN configuration item */
541
635
  cdn: CdnOpt;
542
- /** Extended configuration items */
636
+ /** Additional configuration items */
543
637
  extras?: ExtrasOptions;
638
+ };
639
+ export type CdnOpt = {
640
+ /** Full worker URL address, thread for drawing complete data */
641
+ fullWorkerUrl?: string;
642
+ /** Sub worker URL address, thread for drawing one frame of data */
643
+ subWorkerUrl?: string;
644
+ };
645
+ export type ExtrasOptions = {
646
+ /** Whether to use simple mode, default value is ``false``
647
+ * true: Simple mode:
648
+ 1. Drawing will use single worker, bezier smoothing cannot be used during drawing.
649
+ 2. Remove some new features: minimap, pointerPen (laser pen), autoDraw plugin.
650
+ */
651
+ useSimple: boolean;
652
+ /** Whether to use worker, default value is ``auto``
653
+ * auto: Automatically select (use webWorker if browser supports offscreenCanvas, otherwise use main thread)
654
+ * mainThread: Use main thread, canvas drawing data.
655
+ */
656
+ useWorker?: UseWorkerType;
657
+ /** Synchronization data configuration item */
658
+ syncOpt?: SyncOpt;
659
+ /** Canvas configuration item */
660
+ canvasOpt?: CanvasOpt;
661
+ /** Pointer configuration item */
662
+ cursor?: CursorOpt;
663
+ /** Canvas cache configuration item */
664
+ bufferSize?: BufferSizeOpt;
665
+ /** Bezier optimization configuration item */
666
+ bezier?: BezierOpt;
667
+ /** Partial eraser configuration item */
668
+ pencilEraser?: PencilEraserOpt;
669
+ /** Stroke width range configuration item */
670
+ strokeWidth?: StrokeWidthOpt,
671
+ /** Text editor configuration item */
672
+ textEditor?: TextEditorOpt;
673
+ /** Undo redo configuration item */
674
+ undoRedo?: {
675
+ /** Whether to enable global undo redo, default value is false (Version >=1.1.27) */
676
+ enableGlobal?: boolean;
677
+ /** Maximum stack length for undo redo, default value is 20 */
678
+ maxStackLength?: number;
679
+ };
544
680
  }
545
- ```
546
-
547
- Extended configuration items (`ExtrasOptions`):
548
- ```js
549
- export type ExtrasOptions = {
550
- /** Use simple mode, default false (Version >=1.1.22) */
551
- useSimple?: boolean;
552
- /** Text editor configuration */
553
- textEditor?: {
554
- /** Whether to show float bar */
555
- showFloatBar?: boolean;
556
- /** Whether can switch by selector tool */
557
- canSelectorSwitch?: boolean;
558
- /** Whether right boundary auto wrap */
559
- rightBoundBreak?: boolean;
560
- /** Extended font list (Version >=1.1.22) */
561
- extendFontFaces?: { fontFamily: string; src: string }[];
562
- /** Font loading timeout, unit: milliseconds */
563
- loadFontFacesTimeout?: number;
564
- };
565
- /** Undo redo configuration */
566
- undoRedo?: {
567
- /** Whether to enable global undo redo, default false (Version >=1.1.27) */
568
- enableGlobal?: boolean;
569
- /** Maximum stack length for undo redo, default 20 */
570
- maxStackLength?: number;
571
- };
572
- // ... other configuration items
573
- };
574
- ```
575
- - `cursorAdapter? : CursorAdapter`; This parameter is optional. In single whiteboard mode, customize the mouse style.
576
- - `logger?: Logger`; This parameter is optional. Configure the log printer object. The default output is on the local console. If logs need to be uploaded to the specified server, you need to manually configure the configuration.
577
- > If you need to upload the log to the whiteboard log server, configure the `room.logger` to this item。
578
-
579
- ### Front-end debugging introduction
580
-
581
- During the interconnection process, if you want to understand and track the internal status of the plug-in, you can view the internal data through the following console commands.
681
+ ```
682
+ - `cursorAdapter?: CursorAdapter` - Optional, in single whiteboard mode, configure custom mouse style.
683
+ - `logger?: Logger` - Optional, configure log printer object. If not provided, defaults to local console output. If logs need to be uploaded to a specified server, manual configuration is required.
684
+ > If you need to upload to the whiteboard log server, you can configure `room.logger` to this item.
582
685
 
686
+ ### Front-end Debugging
687
+ During the integration process, if you want to understand and track the internal status of the plugin, you can view internal data through the following console commands.
583
688
  ```js
584
- const applianPlugin = await ApplianceSinglePlugin.getInstance(...)
585
- applianPlugin.CurrentManager // can see the package version number, internal state, etc
586
- applianPlugin.CurrentManager.ConsoleWorkerInfo () // can check information to draw on the worker
689
+ const appliancePlugin = await ApplianceSinglePlugin.getInstance(...)
690
+ appliancePlugin.currentManager // Can view package version number, internal status, etc.
691
+ appliancePlugin.currentManager.consoleWorkerInfo() // Can view drawing information on worker
587
692
  ```