@embedpdf/plugin-scroll 1.0.0

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