@embedpdf/plugin-scroll 1.0.10 → 1.0.12

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.
Files changed (53) hide show
  1. package/dist/index.cjs +2 -651
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +1 -200
  4. package/dist/index.js +43 -67
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/actions.d.ts +27 -0
  7. package/dist/lib/index.d.ts +9 -0
  8. package/dist/lib/manifest.d.ts +4 -0
  9. package/dist/lib/reducer.d.ts +6 -0
  10. package/dist/lib/scroll-plugin.d.ts +45 -0
  11. package/dist/lib/selectors.d.ts +2 -0
  12. package/dist/lib/strategies/base-strategy.d.ts +35 -0
  13. package/dist/lib/strategies/horizontal-strategy.d.ts +14 -0
  14. package/dist/lib/strategies/vertical-strategy.d.ts +14 -0
  15. package/dist/lib/types/virtual-item.d.ts +21 -0
  16. package/dist/lib/types.d.ts +112 -0
  17. package/dist/preact/adapter.d.ts +4 -0
  18. package/dist/preact/core.d.ts +1 -0
  19. package/dist/preact/index.cjs +2 -176
  20. package/dist/preact/index.cjs.map +1 -1
  21. package/dist/preact/index.d.ts +1 -53
  22. package/dist/preact/index.js +17 -17
  23. package/dist/preact/index.js.map +1 -1
  24. package/dist/react/adapter.d.ts +2 -0
  25. package/dist/react/core.d.ts +1 -0
  26. package/dist/react/index.cjs +2 -176
  27. package/dist/react/index.cjs.map +1 -1
  28. package/dist/react/index.d.ts +1 -52
  29. package/dist/react/index.js +16 -17
  30. package/dist/react/index.js.map +1 -1
  31. package/dist/shared-preact/components/index.d.ts +1 -0
  32. package/dist/shared-preact/components/scroller.d.ts +14 -0
  33. package/dist/shared-preact/hooks/index.d.ts +1 -0
  34. package/dist/shared-preact/hooks/use-scroll.d.ts +32 -0
  35. package/dist/shared-preact/index.d.ts +2 -0
  36. package/dist/shared-react/components/index.d.ts +1 -0
  37. package/dist/shared-react/components/scroller.d.ts +14 -0
  38. package/dist/shared-react/hooks/index.d.ts +1 -0
  39. package/dist/shared-react/hooks/use-scroll.d.ts +32 -0
  40. package/dist/shared-react/index.d.ts +2 -0
  41. package/dist/vue/components/index.d.ts +1 -0
  42. package/dist/vue/components/scroller.vue.d.ts +28 -0
  43. package/dist/vue/hooks/index.d.ts +1 -0
  44. package/dist/vue/hooks/use-scroll.d.ts +11 -0
  45. package/dist/vue/index.cjs +2 -0
  46. package/dist/vue/index.cjs.map +1 -0
  47. package/dist/vue/index.d.ts +2 -0
  48. package/dist/vue/index.js +136 -0
  49. package/dist/vue/index.js.map +1 -0
  50. package/package.json +22 -13
  51. package/dist/index.d.cts +0 -200
  52. package/dist/preact/index.d.cts +0 -53
  53. package/dist/react/index.d.cts +0 -52
package/dist/index.cjs CHANGED
@@ -1,651 +1,2 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- SCROLL_PLUGIN_ID: () => SCROLL_PLUGIN_ID,
24
- ScrollPlugin: () => ScrollPlugin,
25
- ScrollPluginPackage: () => ScrollPluginPackage,
26
- ScrollStrategy: () => ScrollStrategy,
27
- manifest: () => manifest
28
- });
29
- module.exports = __toCommonJS(index_exports);
30
-
31
- // src/lib/scroll-plugin.ts
32
- var import_core = require("@embedpdf/core");
33
- var import_models2 = require("@embedpdf/models");
34
-
35
- // src/lib/types.ts
36
- var ScrollStrategy = /* @__PURE__ */ ((ScrollStrategy2) => {
37
- ScrollStrategy2["Vertical"] = "vertical";
38
- ScrollStrategy2["Horizontal"] = "horizontal";
39
- return ScrollStrategy2;
40
- })(ScrollStrategy || {});
41
-
42
- // src/lib/strategies/base-strategy.ts
43
- var import_models = require("@embedpdf/models");
44
- var BaseScrollStrategy = class {
45
- constructor(config) {
46
- this.pageGap = config.pageGap ?? 20;
47
- this.viewportGap = config.viewportGap ?? 20;
48
- this.bufferSize = config.bufferSize ?? 2;
49
- }
50
- getVisibleRange(viewport, virtualItems, scale) {
51
- const scrollOffset = this.getScrollOffset(viewport);
52
- const clientSize = this.getClientSize(viewport);
53
- const viewportStart = scrollOffset;
54
- const viewportEnd = scrollOffset + clientSize;
55
- let startIndex = 0;
56
- while (startIndex < virtualItems.length && (virtualItems[startIndex].offset + virtualItems[startIndex].height) * scale <= viewportStart) {
57
- startIndex++;
58
- }
59
- let endIndex = startIndex;
60
- while (endIndex < virtualItems.length && virtualItems[endIndex].offset * scale <= viewportEnd) {
61
- endIndex++;
62
- }
63
- return {
64
- start: Math.max(0, startIndex - this.bufferSize),
65
- end: Math.min(virtualItems.length - 1, endIndex + this.bufferSize - 1)
66
- };
67
- }
68
- handleScroll(viewport, virtualItems, scale) {
69
- const range = this.getVisibleRange(viewport, virtualItems, scale);
70
- const visibleItems = virtualItems.slice(range.start, range.end + 1);
71
- const pageVisibilityMetrics = this.calculatePageVisibility(visibleItems, viewport, scale);
72
- const visiblePages = pageVisibilityMetrics.map((m) => m.pageNumber);
73
- const renderedPageIndexes = virtualItems.slice(range.start, range.end + 1).flatMap((item) => item.index);
74
- const currentPage = this.determineCurrentPage(pageVisibilityMetrics);
75
- const first = virtualItems[range.start];
76
- const last = virtualItems[range.end];
77
- const startSpacing = first ? first.offset * scale : 0;
78
- const endSpacing = last ? (virtualItems[virtualItems.length - 1].offset + // end of content
79
- virtualItems[virtualItems.length - 1].height) * scale - // minus
80
- (last.offset + last.height) * scale : 0;
81
- return {
82
- currentPage,
83
- visiblePages,
84
- pageVisibilityMetrics,
85
- renderedPageIndexes,
86
- scrollOffset: { x: viewport.scrollLeft, y: viewport.scrollTop },
87
- startSpacing,
88
- endSpacing
89
- };
90
- }
91
- calculatePageVisibility(virtualItems, viewport, scale) {
92
- const visibilityMetrics = [];
93
- virtualItems.forEach((item) => {
94
- item.pageLayouts.forEach((page) => {
95
- const itemX = item.x * scale;
96
- const itemY = item.y * scale;
97
- const pageX = itemX + page.x * scale;
98
- const pageY = itemY + page.y * scale;
99
- const pageWidth = page.rotatedWidth * scale;
100
- const pageHeight = page.rotatedHeight * scale;
101
- const viewportLeft = viewport.scrollLeft;
102
- const viewportTop = viewport.scrollTop;
103
- const viewportRight = viewportLeft + viewport.clientWidth;
104
- const viewportBottom = viewportTop + viewport.clientHeight;
105
- const intersectionLeft = Math.max(pageX, viewportLeft);
106
- const intersectionTop = Math.max(pageY, viewportTop);
107
- const intersectionRight = Math.min(pageX + pageWidth, viewportRight);
108
- const intersectionBottom = Math.min(pageY + pageHeight, viewportBottom);
109
- if (intersectionLeft < intersectionRight && intersectionTop < intersectionBottom) {
110
- const visibleWidth = intersectionRight - intersectionLeft;
111
- const visibleHeight = intersectionBottom - intersectionTop;
112
- const totalArea = pageWidth * pageHeight;
113
- const visibleArea = visibleWidth * visibleHeight;
114
- visibilityMetrics.push({
115
- pageNumber: page.pageNumber,
116
- viewportX: intersectionLeft - viewportLeft,
117
- viewportY: intersectionTop - viewportTop,
118
- visiblePercentage: visibleArea / totalArea * 100,
119
- original: {
120
- pageX: (intersectionLeft - pageX) / scale,
121
- pageY: (intersectionTop - pageY) / scale,
122
- visibleWidth: visibleWidth / scale,
123
- visibleHeight: visibleHeight / scale,
124
- scale: 1
125
- },
126
- scaled: {
127
- pageX: intersectionLeft - pageX,
128
- pageY: intersectionTop - pageY,
129
- visibleWidth,
130
- visibleHeight,
131
- scale
132
- }
133
- });
134
- }
135
- });
136
- });
137
- return visibilityMetrics;
138
- }
139
- determineCurrentPage(visibilityMetrics) {
140
- if (visibilityMetrics.length === 0) return 1;
141
- const maxVisibility = Math.max(...visibilityMetrics.map((m) => m.visiblePercentage));
142
- const mostVisiblePages = visibilityMetrics.filter((m) => m.visiblePercentage === maxVisibility);
143
- return mostVisiblePages.length === 1 ? mostVisiblePages[0].pageNumber : mostVisiblePages.sort((a, b) => a.pageNumber - b.pageNumber)[0].pageNumber;
144
- }
145
- getRectLocationForPage(pageNumber, virtualItems) {
146
- const item = virtualItems.find((item2) => item2.pageNumbers.includes(pageNumber));
147
- if (!item) return null;
148
- const pageLayout = item.pageLayouts.find((layout) => layout.pageNumber === pageNumber);
149
- if (!pageLayout) return null;
150
- return {
151
- origin: {
152
- x: item.x + pageLayout.x,
153
- y: item.y + pageLayout.y
154
- },
155
- size: {
156
- width: pageLayout.width,
157
- height: pageLayout.height
158
- }
159
- };
160
- }
161
- getScrollPositionForPage(pageNumber, virtualItems, scale, rotation, pageCoordinates) {
162
- const pageRect = this.getRectLocationForPage(pageNumber, virtualItems);
163
- if (!pageRect) return null;
164
- const scaledBasePosition = (0, import_models.scalePosition)(pageRect.origin, scale);
165
- if (pageCoordinates) {
166
- const rotatedSize = (0, import_models.transformPosition)(
167
- {
168
- width: pageRect.size.width,
169
- height: pageRect.size.height
170
- },
171
- {
172
- x: pageCoordinates.x,
173
- y: pageCoordinates.y
174
- },
175
- rotation,
176
- scale
177
- );
178
- return {
179
- x: scaledBasePosition.x + rotatedSize.x + this.viewportGap,
180
- y: scaledBasePosition.y + rotatedSize.y + this.viewportGap
181
- };
182
- }
183
- return {
184
- x: scaledBasePosition.x + this.viewportGap,
185
- y: scaledBasePosition.y + this.viewportGap
186
- };
187
- }
188
- getRectPositionForPage(pageNumber, virtualItems, scale, rotation, rect) {
189
- const pageRect = this.getRectLocationForPage(pageNumber, virtualItems);
190
- if (!pageRect) return null;
191
- const scaledBasePosition = (0, import_models.scalePosition)(pageRect.origin, scale);
192
- const rotatedSize = (0, import_models.transformRect)(
193
- {
194
- width: pageRect.size.width,
195
- height: pageRect.size.height
196
- },
197
- rect,
198
- rotation,
199
- scale
200
- );
201
- return {
202
- origin: {
203
- x: scaledBasePosition.x + rotatedSize.origin.x,
204
- y: scaledBasePosition.y + rotatedSize.origin.y
205
- },
206
- size: rotatedSize.size
207
- };
208
- }
209
- };
210
-
211
- // src/lib/strategies/vertical-strategy.ts
212
- var VerticalScrollStrategy = class extends BaseScrollStrategy {
213
- constructor(config) {
214
- super(config);
215
- }
216
- createVirtualItems(pdfPageObject) {
217
- let yOffset = 0;
218
- return pdfPageObject.map((pagesInSpread, index) => {
219
- let pageX = 0;
220
- const pageLayouts = pagesInSpread.map((page) => {
221
- const layout = {
222
- pageNumber: page.index + 1,
223
- pageIndex: page.index,
224
- x: pageX,
225
- y: 0,
226
- width: page.size.width,
227
- height: page.size.height,
228
- rotatedWidth: page.rotatedSize.width,
229
- rotatedHeight: page.rotatedSize.height
230
- };
231
- pageX += page.rotatedSize.width + this.pageGap;
232
- return layout;
233
- });
234
- const width = pagesInSpread.reduce(
235
- (sum, page, i) => sum + page.rotatedSize.width + (i < pagesInSpread.length - 1 ? this.pageGap : 0),
236
- 0
237
- );
238
- const height = Math.max(...pagesInSpread.map((p) => p.rotatedSize.height));
239
- const item = {
240
- id: `item-${index}`,
241
- x: 0,
242
- y: yOffset,
243
- offset: yOffset,
244
- width,
245
- height,
246
- pageLayouts,
247
- pageNumbers: pagesInSpread.map((p) => p.index + 1),
248
- index
249
- };
250
- yOffset += height + this.pageGap;
251
- return item;
252
- });
253
- }
254
- getTotalContentSize(virtualItems) {
255
- if (virtualItems.length === 0) return { width: 0, height: 0 };
256
- const maxWidth = Math.max(...virtualItems.map((item) => item.width));
257
- const totalHeight = virtualItems[virtualItems.length - 1].y + virtualItems[virtualItems.length - 1].height;
258
- return {
259
- width: maxWidth,
260
- height: totalHeight
261
- };
262
- }
263
- getScrollOffset(viewport) {
264
- return viewport.scrollTop;
265
- }
266
- getClientSize(viewport) {
267
- return viewport.clientHeight;
268
- }
269
- };
270
-
271
- // src/lib/strategies/horizontal-strategy.ts
272
- var HorizontalScrollStrategy = class extends BaseScrollStrategy {
273
- constructor(config) {
274
- super(config);
275
- }
276
- createVirtualItems(pdfPageObject) {
277
- let xOffset = 0;
278
- return pdfPageObject.map((pagesInSpread, index) => {
279
- let pageX = 0;
280
- const pageLayouts = pagesInSpread.map((page) => {
281
- const layout = {
282
- pageNumber: page.index + 1,
283
- pageIndex: page.index,
284
- x: pageX,
285
- y: 0,
286
- width: page.size.width,
287
- height: page.size.height,
288
- rotatedWidth: page.rotatedSize.width,
289
- rotatedHeight: page.rotatedSize.height
290
- };
291
- pageX += page.rotatedSize.width + this.pageGap;
292
- return layout;
293
- });
294
- const width = pagesInSpread.reduce(
295
- (sum, page, i) => sum + page.rotatedSize.width + (i < pagesInSpread.length - 1 ? this.pageGap : 0),
296
- 0
297
- );
298
- const height = Math.max(...pagesInSpread.map((p) => p.rotatedSize.height));
299
- const item = {
300
- id: `item-${index}`,
301
- x: xOffset,
302
- y: 0,
303
- offset: xOffset,
304
- width,
305
- height,
306
- pageLayouts,
307
- pageNumbers: pagesInSpread.map((p) => p.index + 1),
308
- index
309
- };
310
- xOffset += width + this.pageGap;
311
- return item;
312
- });
313
- }
314
- getTotalContentSize(virtualItems) {
315
- if (virtualItems.length === 0) return { width: 0, height: 0 };
316
- const totalWidth = virtualItems[virtualItems.length - 1].x + virtualItems[virtualItems.length - 1].width;
317
- const maxHeight = Math.max(...virtualItems.map((item) => item.height));
318
- return {
319
- width: totalWidth,
320
- height: maxHeight
321
- };
322
- }
323
- getScrollOffset(viewport) {
324
- return viewport.scrollLeft;
325
- }
326
- getClientSize(viewport) {
327
- return viewport.clientWidth;
328
- }
329
- };
330
-
331
- // src/lib/actions.ts
332
- var UPDATE_SCROLL_STATE = "UPDATE_SCROLL_STATE";
333
- var SET_DESIRED_SCROLL_POSITION = "SET_DESIRED_SCROLL_POSITION";
334
- var UPDATE_TOTAL_PAGES = "UPDATE_TOTAL_PAGES";
335
- function updateScrollState(payload) {
336
- return { type: UPDATE_SCROLL_STATE, payload };
337
- }
338
- function updateTotalPages(payload) {
339
- return { type: UPDATE_TOTAL_PAGES, payload };
340
- }
341
-
342
- // src/lib/selectors.ts
343
- var getScrollerLayout = (state, scale) => {
344
- return {
345
- startSpacing: state.startSpacing,
346
- endSpacing: state.endSpacing,
347
- totalWidth: state.totalContentSize.width * scale,
348
- totalHeight: state.totalContentSize.height * scale,
349
- pageGap: state.pageGap * scale,
350
- strategy: state.strategy,
351
- items: state.renderedPageIndexes.map((idx) => {
352
- return {
353
- ...state.virtualItems[idx],
354
- pageLayouts: state.virtualItems[idx].pageLayouts.map((layout) => {
355
- return {
356
- ...layout,
357
- rotatedWidth: layout.rotatedWidth * scale,
358
- rotatedHeight: layout.rotatedHeight * scale,
359
- width: layout.width * scale,
360
- height: layout.height * scale
361
- };
362
- })
363
- };
364
- })
365
- };
366
- };
367
-
368
- // src/lib/scroll-plugin.ts
369
- var ScrollPlugin = class extends import_core.BasePlugin {
370
- constructor(id, registry, config) {
371
- super(id, registry);
372
- this.id = id;
373
- this.config = config;
374
- this.currentScale = 1;
375
- this.currentRotation = import_models2.Rotation.Degree0;
376
- this.currentPage = 1;
377
- this.layout$ = (0, import_core.createBehaviorEmitter)();
378
- this.scroll$ = (0, import_core.createBehaviorEmitter)();
379
- this.state$ = (0, import_core.createBehaviorEmitter)();
380
- this.scrollerLayout$ = (0, import_core.createBehaviorEmitter)();
381
- this.pageChange$ = (0, import_core.createBehaviorEmitter)();
382
- this.viewport = this.registry.getPlugin("viewport").provides();
383
- this.strategyConfig = {
384
- pageGap: this.config?.pageGap ?? 10,
385
- viewportGap: this.viewport.getViewportGap(),
386
- bufferSize: this.config?.bufferSize ?? 2
387
- };
388
- this.strategy = this.config?.strategy === "horizontal" /* Horizontal */ ? new HorizontalScrollStrategy(this.strategyConfig) : new VerticalScrollStrategy(this.strategyConfig);
389
- this.initialPage = this.config?.initialPage;
390
- this.currentScale = this.coreState.core.scale;
391
- this.currentRotation = this.coreState.core.rotation;
392
- this.viewport.onViewportChange((vp) => this.commitMetrics(this.computeMetrics(vp)), {
393
- mode: "throttle",
394
- wait: 250
395
- });
396
- this.coreStore.onAction(import_core.SET_DOCUMENT, (_action, state) => {
397
- const totalPages = state.core.pages.length;
398
- this.dispatch(updateTotalPages(totalPages));
399
- this.pageChange$.emit({ pageNumber: this.currentPage, totalPages });
400
- this.refreshAll((0, import_core.getPagesWithRotatedSize)(state.core), this.viewport.getMetrics());
401
- });
402
- this.coreStore.onAction(
403
- import_core.SET_ROTATION,
404
- (_action, state) => this.refreshAll((0, import_core.getPagesWithRotatedSize)(state.core), this.viewport.getMetrics())
405
- );
406
- this.coreStore.onAction(
407
- import_core.SET_PAGES,
408
- (_action, state) => this.refreshAll((0, import_core.getPagesWithRotatedSize)(state.core), this.viewport.getMetrics())
409
- );
410
- }
411
- /* ------------------------------------------------------------------ */
412
- /* ᴄᴏᴍᴘᴜᴛᴇʀs */
413
- /* ------------------------------------------------------------------ */
414
- computeLayout(pages) {
415
- const virtualItems = this.strategy.createVirtualItems(pages);
416
- const totalContentSize = this.strategy.getTotalContentSize(virtualItems);
417
- return { virtualItems, totalContentSize };
418
- }
419
- computeMetrics(vp, items = this.state.virtualItems) {
420
- return this.strategy.handleScroll(vp, items, this.currentScale);
421
- }
422
- /* ------------------------------------------------------------------ */
423
- /* ᴄᴏᴍᴍɪᴛ (single source of truth) */
424
- /* ------------------------------------------------------------------ */
425
- commit(stateDelta, emit) {
426
- this.dispatch(updateScrollState(stateDelta));
427
- if (emit?.layout) this.layout$.emit(emit.layout);
428
- if (emit?.metrics) {
429
- this.scroll$.emit(emit.metrics);
430
- if (emit.metrics.currentPage !== this.currentPage) {
431
- this.currentPage = emit.metrics.currentPage;
432
- this.pageChange$.emit({ pageNumber: this.currentPage, totalPages: this.state.totalPages });
433
- }
434
- }
435
- this.scrollerLayout$.emit(this.getScrollerLayoutFromState());
436
- }
437
- /* convenience wrappers */
438
- commitMetrics(metrics) {
439
- this.commit(metrics, { metrics });
440
- }
441
- /* full re-compute after page-spread or initialisation */
442
- refreshAll(pages, vp) {
443
- const layout = this.computeLayout(pages);
444
- const metrics = this.computeMetrics(vp, layout.virtualItems);
445
- this.commit({ ...layout, ...metrics }, { layout, metrics });
446
- }
447
- getVirtualItemsFromState() {
448
- return this.state.virtualItems || [];
449
- }
450
- getScrollerLayoutFromState() {
451
- const scale = this.coreState.core.scale;
452
- return getScrollerLayout(this.state, scale);
453
- }
454
- pushScrollLayout() {
455
- this.scrollerLayout$.emit(this.getScrollerLayoutFromState());
456
- }
457
- onStoreUpdated(_prevState, _newState) {
458
- this.pushScrollLayout();
459
- }
460
- onCoreStoreUpdated(prevState, newState) {
461
- if (prevState.core.scale !== newState.core.scale) {
462
- this.currentScale = newState.core.scale;
463
- this.commitMetrics(this.computeMetrics(this.viewport.getMetrics()));
464
- }
465
- if (prevState.core.rotation !== newState.core.rotation) {
466
- this.currentRotation = newState.core.rotation;
467
- }
468
- }
469
- /**
470
- * Change the scroll strategy at runtime (e.g., vertical <-> horizontal)
471
- * @param newStrategy ScrollStrategy.Horizontal or ScrollStrategy.Vertical
472
- */
473
- setScrollStrategy(newStrategy) {
474
- if (newStrategy === "horizontal" /* Horizontal */ && this.strategy instanceof HorizontalScrollStrategy || newStrategy === "vertical" /* Vertical */ && this.strategy instanceof VerticalScrollStrategy) {
475
- return;
476
- }
477
- this.strategy = newStrategy === "horizontal" /* Horizontal */ ? new HorizontalScrollStrategy(this.strategyConfig) : new VerticalScrollStrategy(this.strategyConfig);
478
- this.dispatch(
479
- updateScrollState({
480
- strategy: newStrategy
481
- })
482
- );
483
- const pages = (0, import_core.getPagesWithRotatedSize)(this.coreState.core);
484
- this.refreshAll(pages, this.viewport.getMetrics());
485
- }
486
- buildCapability() {
487
- return {
488
- onStateChange: this.state$.on,
489
- onLayoutChange: this.layout$.on,
490
- onScroll: this.scroll$.on,
491
- onPageChange: this.pageChange$.on,
492
- onScrollerData: this.scrollerLayout$.on,
493
- getCurrentPage: () => this.currentPage,
494
- getTotalPages: () => this.state.totalPages,
495
- scrollToPage: (options) => {
496
- const { pageNumber, behavior = "smooth", pageCoordinates, center = false } = options;
497
- const virtualItems = this.getVirtualItemsFromState();
498
- const position = this.strategy.getScrollPositionForPage(
499
- pageNumber,
500
- virtualItems,
501
- this.currentScale,
502
- this.currentRotation,
503
- pageCoordinates
504
- );
505
- if (position) {
506
- this.viewport.scrollTo({ ...position, behavior, center });
507
- }
508
- },
509
- scrollToNextPage: (behavior = "smooth") => {
510
- const virtualItems = this.getVirtualItemsFromState();
511
- const currentItemIndex = virtualItems.findIndex(
512
- (item) => item.pageNumbers.includes(this.currentPage)
513
- );
514
- if (currentItemIndex >= 0 && currentItemIndex < virtualItems.length - 1) {
515
- const nextItem = virtualItems[currentItemIndex + 1];
516
- const position = this.strategy.getScrollPositionForPage(
517
- nextItem.pageNumbers[0],
518
- virtualItems,
519
- this.currentScale,
520
- this.currentRotation
521
- );
522
- if (position) {
523
- this.viewport.scrollTo({ ...position, behavior });
524
- }
525
- }
526
- },
527
- scrollToPreviousPage: (behavior = "smooth") => {
528
- const virtualItems = this.getVirtualItemsFromState();
529
- const currentItemIndex = virtualItems.findIndex(
530
- (item) => item.pageNumbers.includes(this.currentPage)
531
- );
532
- if (currentItemIndex > 0) {
533
- const prevItem = virtualItems[currentItemIndex - 1];
534
- const position = this.strategy.getScrollPositionForPage(
535
- prevItem.pageNumbers[0],
536
- virtualItems,
537
- this.currentScale,
538
- this.currentRotation
539
- );
540
- if (position) {
541
- this.viewport.scrollTo({ ...position, behavior });
542
- }
543
- }
544
- },
545
- getMetrics: this.getMetrics.bind(this),
546
- getLayout: this.getLayout.bind(this),
547
- getRectPositionForPage: this.getRectPositionForPage.bind(this),
548
- getPageGap: () => this.state.pageGap,
549
- getScrollerLayout: () => this.getScrollerLayoutFromState(),
550
- setScrollStrategy: (strategy) => this.setScrollStrategy(strategy)
551
- };
552
- }
553
- getMetrics(viewport) {
554
- const metrics = viewport || this.viewport.getMetrics();
555
- const virtualItems = this.getVirtualItemsFromState();
556
- return this.strategy.handleScroll(metrics, virtualItems, this.currentScale);
557
- }
558
- getLayout() {
559
- return {
560
- virtualItems: this.state.virtualItems,
561
- totalContentSize: this.state.totalContentSize
562
- };
563
- }
564
- getRectPositionForPage(pageIndex, rect, scale, rotation) {
565
- return this.strategy.getRectPositionForPage(
566
- pageIndex + 1,
567
- this.state.virtualItems,
568
- scale ?? this.currentScale,
569
- rotation ?? this.currentRotation,
570
- rect
571
- );
572
- }
573
- async initialize() {
574
- }
575
- async destroy() {
576
- this.layout$.clear();
577
- this.scroll$.clear();
578
- this.pageChange$.clear();
579
- this.state$.clear();
580
- super.destroy();
581
- }
582
- };
583
- ScrollPlugin.id = "scroll";
584
-
585
- // src/lib/manifest.ts
586
- var SCROLL_PLUGIN_ID = "scroll";
587
- var manifest = {
588
- id: SCROLL_PLUGIN_ID,
589
- name: "Scroll Plugin",
590
- version: "1.0.0",
591
- provides: ["scroll"],
592
- requires: ["viewport"],
593
- optional: [],
594
- defaultConfig: {
595
- enabled: true,
596
- pageGap: 10
597
- }
598
- };
599
-
600
- // src/lib/reducer.ts
601
- var import_core2 = require("@embedpdf/core");
602
- var defaultScrollMetrics = {
603
- currentPage: 1,
604
- visiblePages: [],
605
- pageVisibilityMetrics: [],
606
- renderedPageIndexes: [],
607
- scrollOffset: { x: 0, y: 0 },
608
- startSpacing: 0,
609
- endSpacing: 0
610
- };
611
- var initialState = (coreState, config) => ({
612
- virtualItems: [],
613
- totalPages: coreState.pages.length,
614
- totalContentSize: { width: 0, height: 0 },
615
- desiredScrollPosition: { x: 0, y: 0 },
616
- strategy: config.strategy ?? "vertical" /* Vertical */,
617
- pageGap: config.pageGap ?? 10,
618
- scale: coreState.scale,
619
- ...defaultScrollMetrics
620
- });
621
- var scrollReducer = (state, action) => {
622
- switch (action.type) {
623
- case UPDATE_TOTAL_PAGES:
624
- return { ...state, totalPages: action.payload };
625
- case import_core2.SET_SCALE:
626
- return { ...state, scale: action.payload };
627
- case UPDATE_SCROLL_STATE:
628
- return { ...state, ...action.payload };
629
- case SET_DESIRED_SCROLL_POSITION:
630
- return { ...state, desiredScrollPosition: action.payload };
631
- default:
632
- return state;
633
- }
634
- };
635
-
636
- // src/lib/index.ts
637
- var ScrollPluginPackage = {
638
- manifest,
639
- create: (registry, _engine, config) => new ScrollPlugin(SCROLL_PLUGIN_ID, registry, config),
640
- reducer: scrollReducer,
641
- initialState: (coreState, config) => initialState(coreState, config)
642
- };
643
- // Annotate the CommonJS export names for ESM import in node:
644
- 0 && (module.exports = {
645
- SCROLL_PLUGIN_ID,
646
- ScrollPlugin,
647
- ScrollPluginPackage,
648
- ScrollStrategy,
649
- manifest
650
- });
651
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@embedpdf/core"),e=require("@embedpdf/models");var i=(t=>(t.Vertical="vertical",t.Horizontal="horizontal",t))(i||{});class r{constructor(t){this.pageGap=t.pageGap??20,this.viewportGap=t.viewportGap??20,this.bufferSize=t.bufferSize??2}getVisibleRange(t,e,i){const r=this.getScrollOffset(t),a=r,s=r+this.getClientSize(t);let o=0;for(;o<e.length&&(e[o].offset+e[o].height)*i<=a;)o++;let n=o;for(;n<e.length&&e[n].offset*i<=s;)n++;return{start:Math.max(0,o-this.bufferSize),end:Math.min(e.length-1,n+this.bufferSize-1)}}handleScroll(t,e,i){const r=this.getVisibleRange(t,e,i),a=e.slice(r.start,r.end+1),s=this.calculatePageVisibility(a,t,i),o=s.map((t=>t.pageNumber)),n=e.slice(r.start,r.end+1).flatMap((t=>t.index)),h=this.determineCurrentPage(s),l=e[r.start],g=e[r.end],c=l?l.offset*i:0,u=g?(e[e.length-1].offset+e[e.length-1].height)*i-(g.offset+g.height)*i:0;return{currentPage:h,visiblePages:o,pageVisibilityMetrics:s,renderedPageIndexes:n,scrollOffset:{x:t.scrollLeft,y:t.scrollTop},startSpacing:c,endSpacing:u}}calculatePageVisibility(t,e,i){const r=[];return t.forEach((t=>{t.pageLayouts.forEach((a=>{const s=t.x*i,o=t.y*i,n=s+a.x*i,h=o+a.y*i,l=a.rotatedWidth*i,g=a.rotatedHeight*i,c=e.scrollLeft,u=e.scrollTop,p=c+e.clientWidth,d=u+e.clientHeight,m=Math.max(n,c),y=Math.max(h,u),S=Math.min(n+l,p),f=Math.min(h+g,d);if(m<S&&y<f){const t=S-m,e=f-y,s=l*g,o=t*e;r.push({pageNumber:a.pageNumber,viewportX:m-c,viewportY:y-u,visiblePercentage:o/s*100,original:{pageX:(m-n)/i,pageY:(y-h)/i,visibleWidth:t/i,visibleHeight:e/i,scale:1},scaled:{pageX:m-n,pageY:y-h,visibleWidth:t,visibleHeight:e,scale:i}})}}))})),r}determineCurrentPage(t){if(0===t.length)return 1;const e=Math.max(...t.map((t=>t.visiblePercentage))),i=t.filter((t=>t.visiblePercentage===e));return 1===i.length?i[0].pageNumber:i.sort(((t,e)=>t.pageNumber-e.pageNumber))[0].pageNumber}getRectLocationForPage(t,e){const i=e.find((e=>e.pageNumbers.includes(t)));if(!i)return null;const r=i.pageLayouts.find((e=>e.pageNumber===t));return r?{origin:{x:i.x+r.x,y:i.y+r.y},size:{width:r.width,height:r.height}}:null}getScrollPositionForPage(t,i,r,a,s){const o=this.getRectLocationForPage(t,i);if(!o)return null;const n=e.scalePosition(o.origin,r);if(s){const t=e.transformPosition({width:o.size.width,height:o.size.height},{x:s.x,y:s.y},a,r);return{x:n.x+t.x+this.viewportGap,y:n.y+t.y+this.viewportGap}}return{x:n.x+this.viewportGap,y:n.y+this.viewportGap}}getRectPositionForPage(t,i,r,a,s){const o=this.getRectLocationForPage(t,i);if(!o)return null;const n=e.scalePosition(o.origin,r),h=e.transformRect({width:o.size.width,height:o.size.height},s,a,r);return{origin:{x:n.x+h.origin.x,y:n.y+h.origin.y},size:h.size}}}class a extends r{constructor(t){super(t)}createVirtualItems(t){let e=0;return t.map(((t,i)=>{let r=0;const a=t.map((t=>{const e={pageNumber:t.index+1,pageIndex:t.index,x:r,y:0,width:t.size.width,height:t.size.height,rotatedWidth:t.rotatedSize.width,rotatedHeight:t.rotatedSize.height};return r+=t.rotatedSize.width+this.pageGap,e})),s=t.reduce(((e,i,r)=>e+i.rotatedSize.width+(r<t.length-1?this.pageGap:0)),0),o=Math.max(...t.map((t=>t.rotatedSize.height))),n={id:`item-${i}`,x:0,y:e,offset:e,width:s,height:o,pageLayouts:a,pageNumbers:t.map((t=>t.index+1)),index:i};return e+=o+this.pageGap,n}))}getTotalContentSize(t){if(0===t.length)return{width:0,height:0};return{width:Math.max(...t.map((t=>t.width))),height:t[t.length-1].y+t[t.length-1].height}}getScrollOffset(t){return t.scrollTop}getClientSize(t){return t.clientHeight}}class s extends r{constructor(t){super(t)}createVirtualItems(t){let e=0;return t.map(((t,i)=>{let r=0;const a=t.map((t=>{const e={pageNumber:t.index+1,pageIndex:t.index,x:r,y:0,width:t.size.width,height:t.size.height,rotatedWidth:t.rotatedSize.width,rotatedHeight:t.rotatedSize.height};return r+=t.rotatedSize.width+this.pageGap,e})),s=t.reduce(((e,i,r)=>e+i.rotatedSize.width+(r<t.length-1?this.pageGap:0)),0),o=Math.max(...t.map((t=>t.rotatedSize.height))),n={id:`item-${i}`,x:e,y:0,offset:e,width:s,height:o,pageLayouts:a,pageNumbers:t.map((t=>t.index+1)),index:i};return e+=s+this.pageGap,n}))}getTotalContentSize(t){if(0===t.length)return{width:0,height:0};return{width:t[t.length-1].x+t[t.length-1].width,height:Math.max(...t.map((t=>t.height)))}}getScrollOffset(t){return t.scrollLeft}getClientSize(t){return t.clientWidth}}const o="UPDATE_SCROLL_STATE",n="UPDATE_TOTAL_PAGES";function h(t){return{type:o,payload:t}}const l=class extends t.BasePlugin{constructor(r,o,h){var l,g,c,u;super(r,o),this.id=r,this.config=h,this.currentScale=1,this.currentRotation=e.Rotation.Degree0,this.currentPage=1,this.layoutReady=!1,this.layout$=t.createBehaviorEmitter(),this.scroll$=t.createBehaviorEmitter(),this.state$=t.createBehaviorEmitter(),this.scrollerLayout$=t.createBehaviorEmitter(),this.pageChange$=t.createBehaviorEmitter(),this.layoutReady$=t.createBehaviorEmitter(),this.viewport=this.registry.getPlugin("viewport").provides(),this.strategyConfig={pageGap:(null==(l=this.config)?void 0:l.pageGap)??10,viewportGap:this.viewport.getViewportGap(),bufferSize:(null==(g=this.config)?void 0:g.bufferSize)??2},this.strategy=(null==(c=this.config)?void 0:c.strategy)===i.Horizontal?new s(this.strategyConfig):new a(this.strategyConfig),this.initialPage=null==(u=this.config)?void 0:u.initialPage,this.currentScale=this.coreState.core.scale,this.currentRotation=this.coreState.core.rotation,this.viewport.onViewportChange((t=>this.commitMetrics(this.computeMetrics(t))),{mode:"throttle",wait:250}),this.coreStore.onAction(t.SET_DOCUMENT,((e,i)=>{const r=i.core.pages.length;this.dispatch({type:n,payload:r}),this.pageChange$.emit({pageNumber:this.currentPage,totalPages:r}),this.refreshAll(t.getPagesWithRotatedSize(i.core),this.viewport.getMetrics())})),this.coreStore.onAction(t.SET_ROTATION,((e,i)=>this.refreshAll(t.getPagesWithRotatedSize(i.core),this.viewport.getMetrics()))),this.coreStore.onAction(t.SET_PAGES,((e,i)=>this.refreshAll(t.getPagesWithRotatedSize(i.core),this.viewport.getMetrics())))}computeLayout(t){const e=this.strategy.createVirtualItems(t);return{virtualItems:e,totalContentSize:this.strategy.getTotalContentSize(e)}}computeMetrics(t,e=this.state.virtualItems){return this.strategy.handleScroll(t,e,this.currentScale)}commit(t,e){this.dispatch(h(t)),(null==e?void 0:e.layout)&&this.layout$.emit(e.layout),(null==e?void 0:e.metrics)&&(this.scroll$.emit(e.metrics),e.metrics.currentPage!==this.currentPage&&(this.currentPage=e.metrics.currentPage,this.pageChange$.emit({pageNumber:this.currentPage,totalPages:this.state.totalPages}))),this.scrollerLayout$.emit(this.getScrollerLayoutFromState())}commitMetrics(t){this.commit(t,{metrics:t})}refreshAll(t,e){const i=this.computeLayout(t),r=this.computeMetrics(e,i.virtualItems);this.commit({...i,...r},{layout:i,metrics:r})}getVirtualItemsFromState(){return this.state.virtualItems||[]}getScrollerLayoutFromState(){const t=this.coreState.core.scale;return((t,e)=>({startSpacing:t.startSpacing,endSpacing:t.endSpacing,totalWidth:t.totalContentSize.width*e,totalHeight:t.totalContentSize.height*e,pageGap:t.pageGap*e,strategy:t.strategy,items:t.renderedPageIndexes.map((i=>({...t.virtualItems[i],pageLayouts:t.virtualItems[i].pageLayouts.map((t=>({...t,rotatedWidth:t.rotatedWidth*e,rotatedHeight:t.rotatedHeight*e,width:t.width*e,height:t.height*e})))})))}))(this.state,t)}pushScrollLayout(){this.scrollerLayout$.emit(this.getScrollerLayoutFromState())}onStoreUpdated(t,e){this.pushScrollLayout()}onCoreStoreUpdated(t,e){t.core.scale!==e.core.scale&&(this.currentScale=e.core.scale,this.commitMetrics(this.computeMetrics(this.viewport.getMetrics()))),t.core.rotation!==e.core.rotation&&(this.currentRotation=e.core.rotation)}setScrollStrategy(e){if(e===i.Horizontal&&this.strategy instanceof s||e===i.Vertical&&this.strategy instanceof a)return;this.strategy=e===i.Horizontal?new s(this.strategyConfig):new a(this.strategyConfig),this.dispatch(h({strategy:e}));const r=t.getPagesWithRotatedSize(this.coreState.core);this.refreshAll(r,this.viewport.getMetrics())}setLayoutReady(){this.layoutReady||(this.layoutReady=!0,this.layoutReady$.emit(!0))}buildCapability(){return{onStateChange:this.state$.on,onLayoutChange:this.layout$.on,onScroll:this.scroll$.on,onPageChange:this.pageChange$.on,onScrollerData:this.scrollerLayout$.on,onLayoutReady:this.layoutReady$.on,getCurrentPage:()=>this.currentPage,getTotalPages:()=>this.state.totalPages,scrollToPage:t=>{const{pageNumber:e,behavior:i="smooth",pageCoordinates:r,center:a=!1}=t,s=this.getVirtualItemsFromState(),o=this.strategy.getScrollPositionForPage(e,s,this.currentScale,this.currentRotation,r);o&&this.viewport.scrollTo({...o,behavior:i,center:a})},scrollToNextPage:(t="smooth")=>{const e=this.getVirtualItemsFromState(),i=e.findIndex((t=>t.pageNumbers.includes(this.currentPage)));if(i>=0&&i<e.length-1){const r=e[i+1],a=this.strategy.getScrollPositionForPage(r.pageNumbers[0],e,this.currentScale,this.currentRotation);a&&this.viewport.scrollTo({...a,behavior:t})}},scrollToPreviousPage:(t="smooth")=>{const e=this.getVirtualItemsFromState(),i=e.findIndex((t=>t.pageNumbers.includes(this.currentPage)));if(i>0){const r=e[i-1],a=this.strategy.getScrollPositionForPage(r.pageNumbers[0],e,this.currentScale,this.currentRotation);a&&this.viewport.scrollTo({...a,behavior:t})}},getMetrics:this.getMetrics.bind(this),getLayout:this.getLayout.bind(this),getRectPositionForPage:this.getRectPositionForPage.bind(this),getPageGap:()=>this.state.pageGap,getScrollerLayout:()=>this.getScrollerLayoutFromState(),setScrollStrategy:t=>this.setScrollStrategy(t)}}getMetrics(t){const e=t||this.viewport.getMetrics(),i=this.getVirtualItemsFromState();return this.strategy.handleScroll(e,i,this.currentScale)}getLayout(){return{virtualItems:this.state.virtualItems,totalContentSize:this.state.totalContentSize}}getRectPositionForPage(t,e,i,r){return this.strategy.getRectPositionForPage(t+1,this.state.virtualItems,i??this.currentScale,r??this.currentRotation,e)}async initialize(){}async destroy(){this.layout$.clear(),this.scroll$.clear(),this.pageChange$.clear(),this.state$.clear(),this.scrollerLayout$.clear(),this.layoutReady$.clear(),super.destroy()}};l.id="scroll";let g=l;const c="scroll",u={id:c,name:"Scroll Plugin",version:"1.0.0",provides:["scroll"],requires:["viewport"],optional:[],defaultConfig:{enabled:!0,pageGap:10}},p={currentPage:1,visiblePages:[],pageVisibilityMetrics:[],renderedPageIndexes:[],scrollOffset:{x:0,y:0},startSpacing:0,endSpacing:0},d={manifest:u,create:(t,e,i)=>new g(c,t,i),reducer:(e,i)=>{switch(i.type){case n:return{...e,totalPages:i.payload};case t.SET_SCALE:return{...e,scale:i.payload};case o:return{...e,...i.payload};case"SET_DESIRED_SCROLL_POSITION":return{...e,desiredScrollPosition:i.payload};default:return e}},initialState:(t,e)=>((t,e)=>({virtualItems:[],totalPages:t.pages.length,totalContentSize:{width:0,height:0},desiredScrollPosition:{x:0,y:0},strategy:e.strategy??i.Vertical,pageGap:e.pageGap??10,scale:t.scale,...p}))(t,e)};exports.SCROLL_PLUGIN_ID=c,exports.ScrollPlugin=g,exports.ScrollPluginPackage=d,exports.ScrollStrategy=i,exports.manifest=u;
2
+ //# sourceMappingURL=index.cjs.map