@netless/app-presentation 0.1.9-beta.7 → 0.1.9

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-zh.md ADDED
@@ -0,0 +1,173 @@
1
+ # @netless/app-presentation
2
+
3
+ 一个 [Netless App](https://github.com/netless-io/netless-app),用于将多张图片作为演示文稿幻灯片展示。
4
+
5
+ ## 安装
6
+
7
+ <pre>npm add <strong>@netless/app-presentation</strong></pre>
8
+
9
+ ## 使用方法
10
+
11
+ ```js
12
+ import { register } from "@netless/fastboard"
13
+ import { install } from "@netless/app-presentation"
14
+
15
+ install(register, {
16
+ as: 'DocsViewer',
17
+ appOptions: {
18
+ // 启用滚动条功能
19
+ useScrollbar: true,
20
+ // 启用裁剪视图功能,只显示页面内容区域
21
+ useClipView: true,
22
+ // 滚动条事件回调
23
+ scrollbarEventCallback: {
24
+ onScrollCameraUpdated: (appid, originScale, scale) => {
25
+ console.log('相机缩放已更新', appid, scale)
26
+ },
27
+ onScrollbarDragEnd: () => {
28
+ console.log('滚动条拖拽已结束')
29
+ }
30
+ }
31
+ }
32
+ })
33
+ ```
34
+
35
+ ### 将应用插入房间
36
+
37
+ 如果你以 `{ as: 'DocsViewer' }` 的方式安装了这个应用,请调用 [`fastboard.insertDocs()`](https://github.com/netless-io/fastboard#insert-pdf-ppt-and-pptx)。
38
+
39
+ <details><summary>否则&hellip;</summary>
40
+
41
+ ```js
42
+ // 假设你已经获得了演示文稿页面的数据结构
43
+ const data = [
44
+ // [preview] 字段是可选的
45
+ { width: 1024, height: 768, url: 'url/to/1.png', preview: 'url/to/1.small.png' },
46
+ ]
47
+
48
+ // 现在调用 addApp()
49
+ fastboard.manager.addApp({
50
+ kind: 'Presentation',
51
+ options: {
52
+ // 挂载白板场景的文件夹名称
53
+ // 相同的文件夹名称将防止你再次插入
54
+ scenePath: `/presentation/foo`,
55
+ // 应用窗口标题
56
+ title: 'a.pdf',
57
+ // 白板场景规范
58
+ scenes: data.map((e, i) => ({
59
+ name: String(i + 1),
60
+ ppt: {
61
+ src: e.url,
62
+ width: e.width,
63
+ height: e.height,
64
+ previewURL: e.preview
65
+ }
66
+ }))
67
+ }
68
+ })
69
+ ```
70
+
71
+ 请注意,如果你没有使用 `{ as: 'DocsViewer' }` 替换 DocsViewer 应用,
72
+ [`dispatchDocsEvent()`](https://github.com/netless-io/fastboard#control-the-pdfpptx-apps)
73
+ 函数将无法在 Presentation 应用上工作。这是因为该函数只处理类型为 `DocsViewer` 或 `Slide` 的应用。
74
+
75
+ </details>
76
+
77
+ ### 应用选项
78
+
79
+ #### `useScrollbar`
80
+ 启用滚动条功能,提供水平和垂直滚动条用于导航和查看演示文稿。
81
+
82
+ ```js
83
+ install(register, {
84
+ as: 'DocsViewer',
85
+ appOptions: {
86
+ useScrollbar: true,
87
+ scrollbarEventCallback: {
88
+ onScrollCameraUpdated: (appid, originScale, scale) => {
89
+ // 当相机缩放更新时触发
90
+ },
91
+ onScrollbarDragEnd: () => {
92
+ // 当滚动条拖拽结束时触发
93
+ }
94
+ }
95
+ }
96
+ })
97
+ ```
98
+
99
+ #### `useClipView`
100
+ 启用裁剪视图功能,只显示页面内容区域,隐藏白板区域外的内容。
101
+
102
+ ```js
103
+ install(register, {
104
+ as: 'DocsViewer',
105
+ appOptions: {
106
+ useClipView: true
107
+ }
108
+ })
109
+ ```
110
+
111
+ ### 应用结果 API
112
+
113
+ #### `screenshotCurrentPageAsync(context, width?, height?)`
114
+ 异步截图当前页面到 Canvas 上下文。支持自定义宽度和高度。
115
+
116
+ ```js
117
+ const app = fastboard.manager.queryOne(appId)
118
+ if (app && app.kind === 'DocsViewer') {
119
+ const controller = app.appResult
120
+ const canvas = document.createElement('canvas')
121
+ const { width, height } = controller.getPageSize()
122
+ canvas.width = width
123
+ canvas.height = height
124
+ const ctx = canvas.getContext('2d')
125
+ if (ctx) {
126
+ await controller.screenshotCurrentPageAsync(ctx, width, height)
127
+ // 使用 canvas 进行后续操作,如导出图片
128
+ canvas.toBlob((blob) => {
129
+ if (!blob) {
130
+ alert("context.toBlob() 失败!")
131
+ return
132
+ }
133
+ const url = URL.createObjectURL(blob)
134
+ const a = document.createElement('a')
135
+ a.href = url
136
+ a.download = 'screenshot.png'
137
+ a.click()
138
+ })
139
+ }
140
+ }
141
+ ```
142
+
143
+ #### `getPageSize()`
144
+ 获取当前页面的尺寸(宽度和高度)。
145
+
146
+ ```js
147
+ const app = fastboard.manager.queryOne(appId)
148
+ if (app && app.kind === 'DocsViewer') {
149
+ const controller = app.appResult
150
+ const { width, height } = controller.getPageSize()
151
+ console.log(`当前页面尺寸: ${width}x${height}`)
152
+ }
153
+ ```
154
+
155
+ ## 开发
156
+
157
+ 参见 [编写 Netless App](https://github.com/netless-io/fastboard/blob/main/docs/en/app.md)。
158
+
159
+ 如果只想开发 UI 部分,运行:
160
+
161
+ ```bash
162
+ $ pnpm build
163
+ $ pnpm dev
164
+ ```
165
+
166
+ 然后访问 http://localhost:5173/ 在本地查看应用。
167
+
168
+ 要在真实的白板房间中开发,请添加一个包含房间 uuid 和 token 的 .env.local 文件,
169
+ 然后访问 http://localhost:5173/e2e/。
170
+
171
+ ## 许可证
172
+
173
+ MIT @ [netless](https://github.com/netless-io)
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # @netless/app-presentation
2
2
 
3
+ [中文](https://github.com/netless-io/netless-app-presentation/blob/main/README-zh.md)
4
+
3
5
  A [Netless App](https://github.com/netless-io/netless-app) that display multiple images as presentation slides.
4
6
 
5
7
  ## Install
@@ -12,7 +14,24 @@ A [Netless App](https://github.com/netless-io/netless-app) that display multiple
12
14
  import { register } from "@netless/fastboard"
13
15
  import { install } from "@netless/app-presentation"
14
16
 
15
- install(register, { as: 'DocsViewer' })
17
+ install(register, {
18
+ as: 'DocsViewer',
19
+ appOptions: {
20
+ // Enable scrollbar feature
21
+ useScrollbar: true,
22
+ // Enable clip view feature, only show page content area
23
+ useClipView: true,
24
+ // Scrollbar event callbacks
25
+ scrollbarEventCallback: {
26
+ onScrollCameraUpdated: (appid, originScale, scale) => {
27
+ console.log('Camera scale updated', appid, scale)
28
+ },
29
+ onScrollbarDragEnd: () => {
30
+ console.log('Scrollbar drag ended')
31
+ }
32
+ }
33
+ }
34
+ })
16
35
  ```
17
36
 
18
37
  ### Insert This App Into Room
@@ -59,6 +78,80 @@ handles app whose kind is `DocsViewer` or `Slide`.
59
78
 
60
79
  </details>
61
80
 
81
+ ### App Options
82
+
83
+ #### `useScrollbar`
84
+ Enable scrollbar feature, providing horizontal and vertical scrollbars for navigation and viewing presentations.
85
+
86
+ ```js
87
+ install(register, {
88
+ as: 'DocsViewer',
89
+ appOptions: {
90
+ useScrollbar: true,
91
+ scrollbarEventCallback: {
92
+ onScrollCameraUpdated: (appid, originScale, scale) => {
93
+ // Triggered when camera scale is updated
94
+ },
95
+ onScrollbarDragEnd: () => {
96
+ // Triggered when scrollbar drag ends
97
+ }
98
+ }
99
+ }
100
+ })
101
+ ```
102
+
103
+ #### `useClipView`
104
+ Enable clip view feature, only show page content area, hide content outside the whiteboard area.
105
+
106
+ ```js
107
+ install(register, {
108
+ as: 'DocsViewer',
109
+ appOptions: {
110
+ useClipView: true
111
+ }
112
+ })
113
+ ```
114
+
115
+ ### App Result API
116
+
117
+ #### `screenshotCurrentPageAsync(context, width?, height?)`
118
+ Asynchronously screenshot the current page to Canvas context. Supports custom width and height.
119
+
120
+ ```js
121
+ const app = fastboard.manager.queryOne(appId)
122
+ if (app && app.kind === 'DocsViewer') {
123
+ const controller = app.appResult
124
+ const canvas = document.createElement('canvas')
125
+ const { width, height } = controller.getPageSize()
126
+ canvas.width = width
127
+ canvas.height = height
128
+ const ctx = canvas.getContext('2d')
129
+ if (ctx) {
130
+ await controller.screenshotCurrentPageAsync(ctx, width, height)
131
+ // Use canvas for subsequent operations, such as exporting images
132
+ canvas.toBlob((blob) => {
133
+ const url = URL.createObjectURL(blob)
134
+ const a = document.createElement('a')
135
+ a.href = url
136
+ a.download = 'screenshot.png'
137
+ a.click()
138
+ })
139
+ }
140
+ }
141
+ ```
142
+
143
+ #### `getPageSize()`
144
+ Get the size (width and height) of the current page.
145
+
146
+ ```js
147
+ const app = fastboard.manager.queryOne(appId)
148
+ if (app && app.kind === 'DocsViewer') {
149
+ const controller = app.appResult
150
+ const { width, height } = controller.getPageSize()
151
+ console.log(`Current page size: ${width}x${height}`)
152
+ }
153
+ ```
154
+
62
155
  ## Develop
63
156
 
64
157
  See [Write you a Netless App](https://github.com/netless-io/fastboard/blob/main/docs/en/app.md).
@@ -6923,7 +6923,7 @@ var NetlessAppPresentation = (function (exports) {
6923
6923
  (_b = (_a = this.option.scrollbarEventCallback) == null ? void 0 : _a.onScrollbarDragEnd) == null ? void 0 : _b.call(_a);
6924
6924
  };
6925
6925
  this.moveCamera = (camera) => {
6926
- const { centerX, centerY } = camera;
6926
+ const { centerX, centerY, scale } = camera;
6927
6927
  const cacheCamera = this.view.camera;
6928
6928
  const _camera = {};
6929
6929
  if ((0, import_lodash.isNumber)(centerX)) {
@@ -6946,6 +6946,14 @@ var NetlessAppPresentation = (function (exports) {
6946
6946
  }
6947
6947
  _camera.centerY = newCenterY;
6948
6948
  }
6949
+ if ((0, import_lodash.isNumber)(scale)) {
6950
+ let newScale = scale;
6951
+ const originScale = this.option.getOriginScale();
6952
+ if (scale < originScale) {
6953
+ newScale = originScale;
6954
+ }
6955
+ _camera.scale = newScale;
6956
+ }
6949
6957
  this.view.moveCamera(__spreadProps(__spreadValues({}, _camera), {
6950
6958
  animationMode: "immediately"
6951
6959
  }));
@@ -7294,7 +7302,7 @@ var NetlessAppPresentation = (function (exports) {
7294
7302
  };
7295
7303
  const box = context.getBox();
7296
7304
  const app = dispose2.add(createPresentation(box, pages, jumpPage, pageIndex$, view, options.thumbnail, options.useClipView));
7297
- app.contentDOM.dataset.appPresentationVersion = "0.1.9-beta.7";
7305
+ app.contentDOM.dataset.appPresentationVersion = "0.1.9";
7298
7306
  app.scaleDocsToFit = scaleDocsToFit;
7299
7307
  app.log = log;
7300
7308
  if (options.justDocsViewReadonly) {
@@ -7613,7 +7621,7 @@ var NetlessAppPresentation = (function (exports) {
7613
7621
  };
7614
7622
 
7615
7623
  // src/index.ts
7616
- var version = "0.1.9-beta.7";
7624
+ var version = "0.1.9";
7617
7625
  /*! Bundled license information:
7618
7626
 
7619
7627
  lodash/lodash.js:
package/dist/index.js CHANGED
@@ -6924,7 +6924,7 @@ var Scrollbar = class {
6924
6924
  (_b = (_a = this.option.scrollbarEventCallback) == null ? void 0 : _a.onScrollbarDragEnd) == null ? void 0 : _b.call(_a);
6925
6925
  };
6926
6926
  this.moveCamera = (camera) => {
6927
- const { centerX, centerY } = camera;
6927
+ const { centerX, centerY, scale } = camera;
6928
6928
  const cacheCamera = this.view.camera;
6929
6929
  const _camera = {};
6930
6930
  if ((0, import_lodash.isNumber)(centerX)) {
@@ -6947,6 +6947,14 @@ var Scrollbar = class {
6947
6947
  }
6948
6948
  _camera.centerY = newCenterY;
6949
6949
  }
6950
+ if ((0, import_lodash.isNumber)(scale)) {
6951
+ let newScale = scale;
6952
+ const originScale = this.option.getOriginScale();
6953
+ if (scale < originScale) {
6954
+ newScale = originScale;
6955
+ }
6956
+ _camera.scale = newScale;
6957
+ }
6950
6958
  this.view.moveCamera(__spreadProps(__spreadValues({}, _camera), {
6951
6959
  animationMode: "immediately"
6952
6960
  }));
@@ -7295,7 +7303,7 @@ var NetlessAppPresentation = {
7295
7303
  };
7296
7304
  const box = context.getBox();
7297
7305
  const app = dispose2.add(createPresentation(box, pages, jumpPage, pageIndex$, view, options.thumbnail, options.useClipView));
7298
- app.contentDOM.dataset.appPresentationVersion = "0.1.9-beta.7";
7306
+ app.contentDOM.dataset.appPresentationVersion = "0.1.9";
7299
7307
  app.scaleDocsToFit = scaleDocsToFit;
7300
7308
  app.log = log;
7301
7309
  if (options.justDocsViewReadonly) {
@@ -7614,7 +7622,7 @@ var install = (register, options = {}) => {
7614
7622
  };
7615
7623
 
7616
7624
  // src/index.ts
7617
- var version = "0.1.9-beta.7";
7625
+ var version = "0.1.9";
7618
7626
  /*! Bundled license information:
7619
7627
 
7620
7628
  lodash/lodash.js: