@netless/app-presentation 0.1.9-beta.2 → 0.1.9-beta.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/app-presentation",
3
- "version": "0.1.9-beta.2",
3
+ "version": "0.1.9-beta.4",
4
4
  "description": "Netless App for presentation slides (images)",
5
5
  "author": "netless",
6
6
  "license": "MIT",
@@ -33,6 +33,7 @@
33
33
  "@hyrious/esbuild-dev": "^0.10.5",
34
34
  "@netless/fastboard": "^1.0.6",
35
35
  "@netless/window-manager": "^1.0.4",
36
+ "@types/lodash": "^4.17.20",
36
37
  "@types/node": "^20.11.30",
37
38
  "@wopjs/disposable": "^0.1.5",
38
39
  "@wopjs/dom": "^0.1.3",
@@ -42,5 +43,8 @@
42
43
  "sass": "^1.72.0",
43
44
  "vanilla-lazyload": "^18.0.0",
44
45
  "vite": "^5.2.6"
46
+ },
47
+ "dependencies": {
48
+ "lodash": "^4.17.21"
45
49
  }
46
50
  }
@@ -6,7 +6,7 @@ import { listen } from '@wopjs/dom'
6
6
  import styles from './style.scss?inline'
7
7
  import { Presentation, type PresentationConfig, type PresentationPage } from "./presentation";
8
8
  import { readable, type Readable } from "./store";
9
- import { Scrollbar } from "./scrollbar";
9
+ import { Scrollbar, type ScrollbarEventCallback } from "./scrollbar";
10
10
 
11
11
  export type Logger = (...data: any[]) => void
12
12
 
@@ -45,6 +45,7 @@ export interface PresentationAppOptions {
45
45
  useScrollbar?: boolean;
46
46
  /** debounceSync is used to set the presentation debounce sync, it will be used in the presentation, and the presentation will be debounce sync when the app is initialized */
47
47
  debounceSync?: boolean;
48
+ scrollbarEventCallback?: ScrollbarEventCallback
48
49
  }
49
50
 
50
51
  export interface PresentationController {
@@ -71,6 +72,8 @@ export interface PresentationController {
71
72
  moveCamera: (camera: { centerX: number, centerY: number, scale: number }) => void;
72
73
  /** get the origin scale */
73
74
  getOriginScale: () => number;
75
+ /** get the view scale */
76
+ getScale: () =>number;
74
77
  }
75
78
 
76
79
  export { styles }
@@ -390,6 +393,10 @@ export const NetlessAppPresentation: NetlessApp<{}, {}, PresentationAppOptions,
390
393
  return Math.min(size.height / height, size.width / width);
391
394
  }
392
395
 
396
+ const getScale =() => {
397
+ return view.camera.scale
398
+ }
399
+
393
400
  const moveCamera = (camera: { centerX: number, centerY: number, scale: number }) => {
394
401
  if (context.getIsWritable()) {
395
402
  view.moveCamera({...camera, animationMode: 'immediately' as AnimationMode});
@@ -403,10 +410,12 @@ export const NetlessAppPresentation: NetlessApp<{}, {}, PresentationAppOptions,
403
410
  if (options.useScrollbar) {
404
411
  dispose.make(() => {
405
412
  scrollbar = new Scrollbar(app.contentDOM, {
413
+ appId: context.appId,
406
414
  getPageSize,
407
415
  getOriginScale,
408
416
  syncView,
409
417
  getWritable: () => context.getIsWritable(),
418
+ scrollbarEventCallback: options.scrollbarEventCallback
410
419
  }, view)
411
420
  return () => scrollbar?.destroy()
412
421
  })
@@ -538,7 +547,7 @@ export const NetlessAppPresentation: NetlessApp<{}, {}, PresentationAppOptions,
538
547
  }
539
548
  }
540
549
 
541
- const controller: PresentationController = { app, view, context, jumpPage, prevPage, nextPage, pageState, toPdf, log, setDocsViewReadonly, setReadonly, moveCamera, getOriginScale }
550
+ const controller: PresentationController = { app, view, context, jumpPage, prevPage, nextPage, pageState, toPdf, log, setDocsViewReadonly, setReadonly, moveCamera, getOriginScale, getScale }
542
551
 
543
552
  dispose.add(listen(window, 'message', (ev: MessageEvent<"@netless/_presentation_">) => {
544
553
  if (ev.data === "@netless/_presentation_") {
@@ -1,8 +1,10 @@
1
1
  import './style.scss?inline';
2
2
  import type { View, AnimationMode } from "@netless/window-manager";
3
3
  import { makeDraggable } from "./Draggable";
4
+ import { debounce } from 'lodash';
4
5
 
5
6
  export interface ScrollbarOption {
7
+ appId: string;
6
8
  readonly?: boolean;
7
9
  getPageSize: () => {
8
10
  width: number;
@@ -11,13 +13,24 @@ export interface ScrollbarOption {
11
13
  getWritable: () => boolean;
12
14
  getOriginScale: () => number;
13
15
  syncView: () => void;
16
+ scrollbarEventCallback?: ScrollbarEventCallback;
17
+ }
18
+
19
+ export interface ScrollbarEventCallback {
20
+ onScrollbarDragStart?: () => void;
21
+ onScrollbarDragEnd?: () => void;
22
+ onScrollbarDragX?: (x: number) => void;
23
+ onScrollbarDragY?: (y: number) => void;
24
+ onScrollCameraUpdated?: (appid: string, originScale: number, scale: number) => void;
14
25
  }
15
26
 
16
27
  export class Scrollbar {
17
28
  readonly namespace = "netless-app-presentation"
29
+ readonly appId: string;
18
30
  private container: HTMLElement;
19
31
  private scrollContainer: HTMLDivElement = document.createElement('div');
20
32
  private option: ScrollbarOption = {
33
+ appId: '',
21
34
  getPageSize: () => {
22
35
  return {
23
36
  width: 0,
@@ -45,6 +58,7 @@ export class Scrollbar {
45
58
  this.scrollContainer.className = this.c('scrollbar-container');
46
59
  this.container = container;
47
60
  this.option = option;
61
+ this.appId = option.appId;
48
62
  this.readonly = option.readonly || false;
49
63
  this.view = view;
50
64
  this.init();
@@ -62,7 +76,7 @@ export class Scrollbar {
62
76
  }
63
77
  }
64
78
 
65
- onCameraUpdated = () => {
79
+ onCameraUpdated = debounce(() => {
66
80
  if (this.readonly) return;
67
81
  const { scale, centerX, centerY } = this.view.camera;
68
82
  const originScale = this.option.getOriginScale();
@@ -79,7 +93,8 @@ export class Scrollbar {
79
93
  this.scrollbarY.style.display = ratio === 1 ? 'none' : 'block';
80
94
  this.scrollbarY.style.transform = `translateY(${scrollY}px)`;
81
95
  }
82
- }
96
+ this.option.scrollbarEventCallback?.onScrollCameraUpdated?.(this.appId, originScale, scale);
97
+ }, 50)
83
98
 
84
99
  onDragStart = () => {
85
100
  const camera = this.view.camera;
@@ -88,6 +103,7 @@ export class Scrollbar {
88
103
  centerY: camera.centerY,
89
104
  scale: camera.scale,
90
105
  }
106
+ this.option.scrollbarEventCallback?.onScrollbarDragStart?.();
91
107
  }
92
108
 
93
109
  getScrollXRange(camera: {scale: number}) {
@@ -128,6 +144,7 @@ export class Scrollbar {
128
144
  centerX,
129
145
  animationMode: 'immediately' as AnimationMode
130
146
  })
147
+ this.option.scrollbarEventCallback?.onScrollbarDragY?.(centerX);
131
148
  }
132
149
  }
133
150
 
@@ -146,13 +163,15 @@ export class Scrollbar {
146
163
  this.view.moveCamera({
147
164
  centerY,
148
165
  animationMode: 'immediately' as AnimationMode
149
- })
166
+ })
167
+ this.option.scrollbarEventCallback?.onScrollbarDragY?.(centerY);
150
168
  }
151
169
  }
152
170
 
153
171
  onDragEnd = () => {
154
172
  this.cameraCache = undefined
155
173
  this.option.syncView();
174
+ this.option.scrollbarEventCallback?.onScrollbarDragEnd?.();
156
175
  }
157
176
 
158
177
  private init() {
@@ -195,7 +214,7 @@ export class Scrollbar {
195
214
  this.scrollContainer.append(this.scrollbarContainerX, this.scrollbarContainerY);
196
215
  this.container.appendChild(this.scrollContainer);
197
216
  this.view.callbacks.on('onCameraUpdated', this.onCameraUpdated);
198
- this.onCameraUpdated()
217
+ this.onCameraUpdated();
199
218
  }
200
219
 
201
220
  destroy() {