@embedpdf/plugin-zoom 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 (49) hide show
  1. package/dist/hammer-Bs-QCG8V.cjs +7 -0
  2. package/dist/hammer-Bs-QCG8V.cjs.map +1 -0
  3. package/dist/hammer-e1aXHboh.js +1810 -0
  4. package/dist/hammer-e1aXHboh.js.map +1 -0
  5. package/dist/index.cjs +2 -481
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.ts +1 -147
  8. package/dist/index.js +43 -59
  9. package/dist/index.js.map +1 -1
  10. package/dist/lib/actions.d.ts +20 -0
  11. package/dist/lib/index.d.ts +10 -0
  12. package/dist/lib/manifest.d.ts +4 -0
  13. package/dist/lib/reducer.d.ts +5 -0
  14. package/dist/lib/types.d.ts +84 -0
  15. package/dist/lib/zoom-plugin.d.ts +38 -0
  16. package/dist/preact/adapter.d.ts +5 -0
  17. package/dist/preact/core.d.ts +1 -0
  18. package/dist/preact/index.cjs +2 -262
  19. package/dist/preact/index.cjs.map +1 -1
  20. package/dist/preact/index.d.ts +1 -54
  21. package/dist/preact/index.js +29 -34
  22. package/dist/preact/index.js.map +1 -1
  23. package/dist/preact/interaction-manager.d.ts +1 -0
  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 -262
  27. package/dist/react/index.cjs.map +1 -1
  28. package/dist/react/index.d.ts +1 -53
  29. package/dist/react/index.js +28 -34
  30. package/dist/react/index.js.map +1 -1
  31. package/dist/react/interaction-manager.d.ts +1 -0
  32. package/dist/shared-preact/components/index.d.ts +2 -0
  33. package/dist/shared-preact/components/marquee-zoom.d.ts +21 -0
  34. package/dist/shared-preact/components/pinch-wrapper.d.ts +7 -0
  35. package/dist/shared-preact/hooks/index.d.ts +2 -0
  36. package/dist/shared-preact/hooks/use-pinch-zoom.d.ts +3 -0
  37. package/dist/shared-preact/hooks/use-zoom.d.ts +15 -0
  38. package/dist/shared-preact/index.d.ts +2 -0
  39. package/dist/shared-react/components/index.d.ts +2 -0
  40. package/dist/shared-react/components/marquee-zoom.d.ts +21 -0
  41. package/dist/shared-react/components/pinch-wrapper.d.ts +7 -0
  42. package/dist/shared-react/hooks/index.d.ts +2 -0
  43. package/dist/shared-react/hooks/use-pinch-zoom.d.ts +3 -0
  44. package/dist/shared-react/hooks/use-zoom.d.ts +15 -0
  45. package/dist/shared-react/index.d.ts +2 -0
  46. package/package.json +18 -17
  47. package/dist/index.d.cts +0 -147
  48. package/dist/preact/index.d.cts +0 -54
  49. package/dist/react/index.d.cts +0 -53
package/dist/index.d.ts CHANGED
@@ -1,147 +1 @@
1
- import { BasePluginConfig, EventHook, Action, BasePlugin, PluginRegistry, PluginManifest, PluginPackage } from '@embedpdf/core';
2
- import { Rect } from '@embedpdf/models';
3
- import { ViewportMetrics } from '@embedpdf/plugin-viewport';
4
-
5
- declare enum ZoomMode {
6
- Automatic = "automatic",
7
- FitPage = "fit-page",
8
- FitWidth = "fit-width"
9
- }
10
- type ZoomLevel = ZoomMode | number;
11
- interface Point {
12
- vx: number;
13
- vy: number;
14
- }
15
- interface ZoomChangeEvent {
16
- /** old and new *actual* scale factors */
17
- oldZoom: number;
18
- newZoom: number;
19
- /** level used to obtain the newZoom (number | mode) */
20
- level: ZoomLevel;
21
- /** viewport point kept under the finger / mouse‑wheel focus */
22
- center: Point;
23
- /** where the viewport should scroll to after the scale change */
24
- desiredScrollLeft: number;
25
- desiredScrollTop: number;
26
- /** metrics at the moment the zoom was requested */
27
- viewport: ViewportMetrics;
28
- }
29
- interface ZoomCapability {
30
- /** subscribe – returns the unsubscribe function */
31
- onZoomChange: EventHook<ZoomChangeEvent>;
32
- /** subscribe – returns the unsubscribe function */
33
- onStateChange: EventHook<ZoomState>;
34
- /** absolute requests -------------------------------------------------- */
35
- requestZoom(level: ZoomLevel, center?: Point): void;
36
- /** relative requests -------------------------------------------------- */
37
- requestZoomBy(delta: number, center?: Point): void;
38
- /** absolute requests -------------------------------------------------- */
39
- zoomIn(): void;
40
- zoomOut(): void;
41
- zoomToArea(pageIndex: number, rect: Rect): void;
42
- /** zoom in on an area -------------------------------------------------- */
43
- enableMarqueeZoom(): void;
44
- disableMarqueeZoom(): void;
45
- toggleMarqueeZoom(): void;
46
- isMarqueeZoomActive(): boolean;
47
- getState(): ZoomState;
48
- getPresets(): ZoomPreset[];
49
- }
50
- interface ZoomRangeStep {
51
- min: number;
52
- max: number;
53
- step: number;
54
- }
55
- interface ZoomPreset {
56
- name: string;
57
- value: ZoomLevel;
58
- icon?: string;
59
- }
60
- interface ZoomPluginConfig extends BasePluginConfig {
61
- defaultZoomLevel: ZoomLevel;
62
- minZoom?: number;
63
- maxZoom?: number;
64
- zoomStep?: number;
65
- zoomRanges?: ZoomRangeStep[];
66
- presets?: ZoomPreset[];
67
- }
68
- interface ZoomState {
69
- zoomLevel: ZoomLevel;
70
- currentZoomLevel: number;
71
- }
72
- declare enum VerticalZoomFocus {
73
- Center = 0,
74
- Top = 1
75
- }
76
- interface ZoomRequest {
77
- level: ZoomLevel;
78
- delta?: number;
79
- center?: Point;
80
- focus?: VerticalZoomFocus;
81
- /** Scroll so that the focal point ends up …
82
- * ▸ `"keep"` (default) at the same viewport coords
83
- * ▸ `"center"` centred in the viewport */
84
- align?: 'keep' | 'center';
85
- }
86
-
87
- declare const SET_ZOOM_LEVEL = "SET_ZOOM_LEVEL";
88
- declare const SET_INITIAL_ZOOM_LEVEL = "SET_INITIAL_ZOOM_LEVEL";
89
- interface SetZoomLevelAction extends Action {
90
- type: typeof SET_ZOOM_LEVEL;
91
- payload: {
92
- zoomLevel: ZoomLevel;
93
- currentZoomLevel: number;
94
- };
95
- }
96
- interface SetInitialZoomLevelAction extends Action {
97
- type: typeof SET_INITIAL_ZOOM_LEVEL;
98
- payload: {
99
- zoomLevel: ZoomLevel;
100
- };
101
- }
102
- type ZoomAction = SetZoomLevelAction | SetInitialZoomLevelAction;
103
-
104
- declare const initialState: ZoomState;
105
-
106
- declare class ZoomPlugin extends BasePlugin<ZoomPluginConfig, ZoomCapability, ZoomState, ZoomAction> {
107
- static readonly id: "zoom";
108
- private readonly zoom$;
109
- private readonly state$;
110
- private readonly viewport;
111
- private readonly viewportPlugin;
112
- private readonly scroll;
113
- private readonly interactionManager;
114
- private readonly presets;
115
- private readonly zoomRanges;
116
- private readonly minZoom;
117
- private readonly maxZoom;
118
- private readonly zoomStep;
119
- constructor(id: string, registry: PluginRegistry, cfg: ZoomPluginConfig);
120
- protected buildCapability(): ZoomCapability;
121
- initialize(): Promise<void>;
122
- destroy(): Promise<void>;
123
- /**
124
- * Sort ranges once, make sure they are sane
125
- */
126
- private normalizeRanges;
127
- /** pick the step that applies to a given numeric zoom */
128
- private stepFor;
129
- /** clamp + round helper reused later */
130
- private toZoom;
131
- private handleRequest;
132
- /** numeric zoom for Automatic / FitPage / FitWidth */
133
- private computeZoomForMode;
134
- /** where to scroll so that *focus* stays stable after scaling */
135
- private computeScrollForZoomChange;
136
- private handleZoomToArea;
137
- /** recalculates Automatic / Fit* when viewport or pages change */
138
- private recalcAuto;
139
- onStoreUpdated(_prevState: ZoomState, newState: ZoomState): void;
140
- }
141
-
142
- declare const ZOOM_PLUGIN_ID = "zoom";
143
- declare const manifest: PluginManifest<ZoomPluginConfig>;
144
-
145
- declare const ZoomPluginPackage: PluginPackage<ZoomPlugin, ZoomPluginConfig, ZoomState, ZoomAction>;
146
-
147
- export { type Point, VerticalZoomFocus, ZOOM_PLUGIN_ID, type ZoomCapability, type ZoomChangeEvent, type ZoomLevel, ZoomMode, ZoomPlugin, type ZoomPluginConfig, ZoomPluginPackage, type ZoomPreset, type ZoomRangeStep, type ZoomRequest, type ZoomState, initialState, manifest };
1
+ export * from './lib';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- // src/lib/types.ts
1
+ import { BasePlugin, createEmitter, createBehaviorEmitter, SET_ROTATION, SET_PAGES, SET_DOCUMENT, clamp, setScale, getPagesWithRotatedSize } from "@embedpdf/core";
2
+ import { rotateRect } from "@embedpdf/models";
2
3
  var ZoomMode = /* @__PURE__ */ ((ZoomMode2) => {
3
4
  ZoomMode2["Automatic"] = "automatic";
4
5
  ZoomMode2["FitPage"] = "fit-page";
@@ -10,10 +11,8 @@ var VerticalZoomFocus = /* @__PURE__ */ ((VerticalZoomFocus2) => {
10
11
  VerticalZoomFocus2[VerticalZoomFocus2["Top"] = 1] = "Top";
11
12
  return VerticalZoomFocus2;
12
13
  })(VerticalZoomFocus || {});
13
-
14
- // src/lib/manifest.ts
15
- var ZOOM_PLUGIN_ID = "zoom";
16
- var manifest = {
14
+ const ZOOM_PLUGIN_ID = "zoom";
15
+ const manifest = {
17
16
  id: ZOOM_PLUGIN_ID,
18
17
  name: "Zoom Plugin",
19
18
  version: "1.0.0",
@@ -22,7 +21,7 @@ var manifest = {
22
21
  optional: ["interaction-manager"],
23
22
  defaultConfig: {
24
23
  enabled: true,
25
- defaultZoomLevel: "automatic" /* Automatic */,
24
+ defaultZoomLevel: ZoomMode.Automatic,
26
25
  minZoom: 0.2,
27
26
  maxZoom: 60,
28
27
  zoomStep: 0.1,
@@ -71,15 +70,15 @@ var manifest = {
71
70
  presets: [
72
71
  {
73
72
  name: "Fit Page",
74
- value: "fit-page" /* FitPage */
73
+ value: ZoomMode.FitPage
75
74
  },
76
75
  {
77
76
  name: "Fit Width",
78
- value: "fit-width" /* FitWidth */
77
+ value: ZoomMode.FitWidth
79
78
  },
80
79
  {
81
80
  name: "Automatic",
82
- value: "automatic" /* Automatic */
81
+ value: ZoomMode.Automatic
83
82
  },
84
83
  {
85
84
  name: "25%",
@@ -120,10 +119,8 @@ var manifest = {
120
119
  ]
121
120
  }
122
121
  };
123
-
124
- // src/lib/actions.ts
125
- var SET_ZOOM_LEVEL = "SET_ZOOM_LEVEL";
126
- var SET_INITIAL_ZOOM_LEVEL = "SET_INITIAL_ZOOM_LEVEL";
122
+ const SET_ZOOM_LEVEL = "SET_ZOOM_LEVEL";
123
+ const SET_INITIAL_ZOOM_LEVEL = "SET_INITIAL_ZOOM_LEVEL";
127
124
  function setZoomLevel(zoomLevel, currentZoomLevel) {
128
125
  return {
129
126
  type: SET_ZOOM_LEVEL,
@@ -136,13 +133,11 @@ function setInitialZoomLevel(zoomLevel) {
136
133
  payload: { zoomLevel }
137
134
  };
138
135
  }
139
-
140
- // src/lib/reducer.ts
141
- var initialState = {
142
- zoomLevel: "automatic" /* Automatic */,
136
+ const initialState = {
137
+ zoomLevel: ZoomMode.Automatic,
143
138
  currentZoomLevel: 1
144
139
  };
145
- var zoomReducer = (state = initialState, action) => {
140
+ const zoomReducer = (state = initialState, action) => {
146
141
  switch (action.type) {
147
142
  case SET_ZOOM_LEVEL:
148
143
  return {
@@ -159,48 +154,32 @@ var zoomReducer = (state = initialState, action) => {
159
154
  return state;
160
155
  }
161
156
  };
162
-
163
- // src/lib/zoom-plugin.ts
164
- import {
165
- BasePlugin,
166
- createEmitter,
167
- clamp,
168
- setScale,
169
- SET_PAGES,
170
- SET_DOCUMENT,
171
- getPagesWithRotatedSize,
172
- SET_ROTATION,
173
- createBehaviorEmitter
174
- } from "@embedpdf/core";
175
- import { rotateRect } from "@embedpdf/models";
176
- var ZoomPlugin = class extends BasePlugin {
157
+ const _ZoomPlugin = class _ZoomPlugin extends BasePlugin {
177
158
  /* ------------------------------------------------------------------ */
178
159
  constructor(id, registry, cfg) {
160
+ var _a;
179
161
  super(id, registry);
180
- /* ------------------------------------------------------------------ */
181
- /* internals */
182
- /* ------------------------------------------------------------------ */
183
162
  this.zoom$ = createEmitter();
184
163
  this.state$ = createBehaviorEmitter();
185
164
  this.viewportPlugin = registry.getPlugin("viewport");
186
165
  this.viewport = this.viewportPlugin.provides();
187
166
  this.scroll = registry.getPlugin("scroll").provides();
188
167
  const interactionManager = registry.getPlugin("interaction-manager");
189
- this.interactionManager = interactionManager?.provides() ?? null;
168
+ this.interactionManager = (interactionManager == null ? void 0 : interactionManager.provides()) ?? null;
190
169
  this.minZoom = cfg.minZoom ?? 0.25;
191
170
  this.maxZoom = cfg.maxZoom ?? 10;
192
171
  this.zoomStep = cfg.zoomStep ?? 0.1;
193
172
  this.presets = cfg.presets ?? [];
194
173
  this.zoomRanges = this.normalizeRanges(cfg.zoomRanges ?? []);
195
174
  this.dispatch(setInitialZoomLevel(cfg.defaultZoomLevel));
196
- this.viewport.onViewportResize(() => this.recalcAuto(1 /* Top */), {
175
+ this.viewport.onViewportResize(() => this.recalcAuto(VerticalZoomFocus.Top), {
197
176
  mode: "debounce",
198
177
  wait: 150
199
178
  });
200
- this.coreStore.onAction(SET_ROTATION, () => this.recalcAuto(1 /* Top */));
201
- this.coreStore.onAction(SET_PAGES, () => this.recalcAuto(1 /* Top */));
202
- this.coreStore.onAction(SET_DOCUMENT, () => this.recalcAuto(1 /* Top */));
203
- this.interactionManager?.registerMode({
179
+ this.coreStore.onAction(SET_ROTATION, () => this.recalcAuto(VerticalZoomFocus.Top));
180
+ this.coreStore.onAction(SET_PAGES, () => this.recalcAuto(VerticalZoomFocus.Top));
181
+ this.coreStore.onAction(SET_DOCUMENT, () => this.recalcAuto(VerticalZoomFocus.Top));
182
+ (_a = this.interactionManager) == null ? void 0 : _a.registerMode({
204
183
  id: "marqueeZoom",
205
184
  scope: "page",
206
185
  exclusive: true,
@@ -231,19 +210,25 @@ var ZoomPlugin = class extends BasePlugin {
231
210
  return this.handleRequest({ level: target, center: c });
232
211
  },
233
212
  enableMarqueeZoom: () => {
234
- this.interactionManager?.activate("marqueeZoom");
213
+ var _a;
214
+ (_a = this.interactionManager) == null ? void 0 : _a.activate("marqueeZoom");
235
215
  },
236
216
  disableMarqueeZoom: () => {
237
- this.interactionManager?.activate("default");
217
+ var _a;
218
+ (_a = this.interactionManager) == null ? void 0 : _a.activate("default");
238
219
  },
239
220
  toggleMarqueeZoom: () => {
240
- if (this.interactionManager?.getActiveMode() === "marqueeZoom") {
241
- this.interactionManager?.activate("default");
221
+ var _a, _b, _c;
222
+ if (((_a = this.interactionManager) == null ? void 0 : _a.getActiveMode()) === "marqueeZoom") {
223
+ (_b = this.interactionManager) == null ? void 0 : _b.activate("default");
242
224
  } else {
243
- this.interactionManager?.activate("marqueeZoom");
225
+ (_c = this.interactionManager) == null ? void 0 : _c.activate("marqueeZoom");
244
226
  }
245
227
  },
246
- isMarqueeZoomActive: () => this.interactionManager?.getActiveMode() === "marqueeZoom",
228
+ isMarqueeZoomActive: () => {
229
+ var _a;
230
+ return ((_a = this.interactionManager) == null ? void 0 : _a.getActiveMode()) === "marqueeZoom";
231
+ },
247
232
  getState: () => this.state,
248
233
  getPresets: () => this.presets
249
234
  };
@@ -278,7 +263,7 @@ var ZoomPlugin = class extends BasePlugin {
278
263
  level,
279
264
  delta = 0,
280
265
  center,
281
- focus = 0 /* Center */,
266
+ focus = VerticalZoomFocus.Center,
282
267
  align = "keep"
283
268
  }) {
284
269
  const metrics = this.viewport.getMetrics();
@@ -294,7 +279,7 @@ var ZoomPlugin = class extends BasePlugin {
294
279
  const newZoom = Math.floor(exactZoom * 100) / 100;
295
280
  const focusPoint = center ?? {
296
281
  vx: metrics.clientWidth / 2,
297
- vy: focus === 1 /* Top */ ? 0 : metrics.clientHeight / 2
282
+ vy: focus === VerticalZoomFocus.Top ? 0 : metrics.clientHeight / 2
298
283
  };
299
284
  const { desiredScrollLeft, desiredScrollTop } = this.computeScrollForZoomChange(
300
285
  metrics,
@@ -353,11 +338,11 @@ var ZoomPlugin = class extends BasePlugin {
353
338
  maxContentH = Math.max(maxContentH, contentH);
354
339
  });
355
340
  switch (mode) {
356
- case "fit-width" /* FitWidth */:
341
+ case ZoomMode.FitWidth:
357
342
  return availableWidth / maxContentW;
358
- case "fit-page" /* FitPage */:
343
+ case ZoomMode.FitPage:
359
344
  return Math.min(availableWidth / maxContentW, availableHeight / maxContentH);
360
- case "automatic" /* Automatic */:
345
+ case ZoomMode.Automatic:
361
346
  return Math.min(availableWidth / maxContentW, 1);
362
347
  /* istanbul ignore next */
363
348
  default:
@@ -430,17 +415,16 @@ var ZoomPlugin = class extends BasePlugin {
430
415
  /** recalculates Automatic / Fit* when viewport or pages change */
431
416
  recalcAuto(focus) {
432
417
  const s = this.state;
433
- if (s.zoomLevel === "automatic" /* Automatic */ || s.zoomLevel === "fit-page" /* FitPage */ || s.zoomLevel === "fit-width" /* FitWidth */)
418
+ if (s.zoomLevel === ZoomMode.Automatic || s.zoomLevel === ZoomMode.FitPage || s.zoomLevel === ZoomMode.FitWidth)
434
419
  this.handleRequest({ level: s.zoomLevel, focus });
435
420
  }
436
421
  onStoreUpdated(_prevState, newState) {
437
422
  this.state$.emit(newState);
438
423
  }
439
424
  };
440
- ZoomPlugin.id = "zoom";
441
-
442
- // src/lib/index.ts
443
- var ZoomPluginPackage = {
425
+ _ZoomPlugin.id = "zoom";
426
+ let ZoomPlugin = _ZoomPlugin;
427
+ const ZoomPluginPackage = {
444
428
  manifest,
445
429
  create: (registry, _engine, config) => new ZoomPlugin(ZOOM_PLUGIN_ID, registry, config),
446
430
  reducer: zoomReducer,
@@ -455,4 +439,4 @@ export {
455
439
  initialState,
456
440
  manifest
457
441
  };
458
- //# sourceMappingURL=index.js.map
442
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/types.ts","../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/zoom-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePluginConfig, EventHook } from '@embedpdf/core';\nimport { Rect } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\n\n/* ------------------------------------------------------------------ */\n/* public */\n/* ------------------------------------------------------------------ */\n\nexport enum ZoomMode {\n Automatic = 'automatic',\n FitPage = 'fit-page',\n FitWidth = 'fit-width',\n}\n\nexport type ZoomLevel = ZoomMode | number;\n\nexport interface Point {\n vx: number;\n vy: number;\n}\n\nexport interface ZoomChangeEvent {\n /** old and new *actual* scale factors */\n oldZoom: number;\n newZoom: number;\n\n /** level used to obtain the newZoom (number | mode) */\n level: ZoomLevel;\n\n /** viewport point kept under the finger / mouse‑wheel focus */\n center: Point;\n\n /** where the viewport should scroll to after the scale change */\n desiredScrollLeft: number;\n desiredScrollTop: number;\n\n /** metrics at the moment the zoom was requested */\n viewport: ViewportMetrics;\n}\n\nexport interface ZoomCapability {\n /** subscribe – returns the unsubscribe function */\n onZoomChange: EventHook<ZoomChangeEvent>;\n /** subscribe – returns the unsubscribe function */\n onStateChange: EventHook<ZoomState>;\n\n /** absolute requests -------------------------------------------------- */\n requestZoom(level: ZoomLevel, center?: Point): void;\n /** relative requests -------------------------------------------------- */\n requestZoomBy(delta: number, center?: Point): void;\n\n /** absolute requests -------------------------------------------------- */\n zoomIn(): void;\n zoomOut(): void;\n\n zoomToArea(pageIndex: number, rect: Rect): void;\n\n /** zoom in on an area -------------------------------------------------- */\n enableMarqueeZoom(): void;\n disableMarqueeZoom(): void;\n toggleMarqueeZoom(): void;\n isMarqueeZoomActive(): boolean;\n\n getState(): ZoomState;\n getPresets(): ZoomPreset[];\n}\n\n/* ------------------------------------------------------------------ */\n/* config / store */\n/* ------------------------------------------------------------------ */\n\nexport interface ZoomRangeStep {\n min: number;\n max: number;\n step: number;\n}\n\nexport interface ZoomPreset {\n name: string;\n value: ZoomLevel;\n icon?: string;\n}\n\nexport interface ZoomPluginConfig extends BasePluginConfig {\n defaultZoomLevel: ZoomLevel;\n minZoom?: number;\n maxZoom?: number;\n zoomStep?: number;\n zoomRanges?: ZoomRangeStep[]; // Define different step sizes for different zoom ranges\n presets?: ZoomPreset[]; // Preset zoom options for dropdown\n}\n\nexport interface ZoomState {\n zoomLevel: ZoomLevel; // last **requested** level\n currentZoomLevel: number; // actual numeric factor\n}\n\nexport enum VerticalZoomFocus {\n Center,\n Top,\n}\n\nexport interface ZoomRequest {\n level: ZoomLevel;\n delta?: number;\n center?: Point;\n focus?: VerticalZoomFocus;\n /** Scroll so that the focal point ends up …\n * ▸ `\"keep\"` (default) at the same viewport coords\n * ▸ `\"center\"` centred in the viewport */\n align?: 'keep' | 'center';\n}\n","import { PluginManifest } from '@embedpdf/core';\n\nimport { ZoomMode, ZoomPluginConfig } from './types';\n\nexport const ZOOM_PLUGIN_ID = 'zoom';\n\nexport const manifest: PluginManifest<ZoomPluginConfig> = {\n id: ZOOM_PLUGIN_ID,\n name: 'Zoom Plugin',\n version: '1.0.0',\n provides: ['zoom'],\n requires: ['viewport', 'scroll'],\n optional: ['interaction-manager'],\n defaultConfig: {\n enabled: true,\n defaultZoomLevel: ZoomMode.Automatic,\n minZoom: 0.2,\n maxZoom: 60,\n zoomStep: 0.1,\n zoomRanges: [\n {\n min: 0.2,\n max: 0.5,\n step: 0.05,\n },\n {\n min: 0.5,\n max: 1.0,\n step: 0.1,\n },\n {\n min: 1.0,\n max: 2.0,\n step: 0.2,\n },\n {\n min: 2.0,\n max: 4.0,\n step: 0.4,\n },\n {\n min: 4.0,\n max: 10.0,\n step: 0.8,\n },\n {\n min: 10.0,\n max: 20.0,\n step: 1.6,\n },\n {\n min: 20.0,\n max: 40.0,\n step: 3.2,\n },\n {\n min: 40.0,\n max: 60.0,\n step: 6.4,\n },\n ],\n presets: [\n {\n name: 'Fit Page',\n value: ZoomMode.FitPage,\n },\n {\n name: 'Fit Width',\n value: ZoomMode.FitWidth,\n },\n {\n name: 'Automatic',\n value: ZoomMode.Automatic,\n },\n {\n name: '25%',\n value: 0.25,\n },\n {\n name: '50%',\n value: 0.5,\n },\n {\n name: '100%',\n value: 1,\n },\n {\n name: '125%',\n value: 1.25,\n },\n {\n name: '150%',\n value: 1.5,\n },\n {\n name: '200%',\n value: 2,\n },\n {\n name: '400%',\n value: 4,\n },\n {\n name: '800%',\n value: 8,\n },\n {\n name: '1600%',\n value: 16,\n },\n ],\n },\n};\n","import { Action } from '@embedpdf/core';\n\nimport { ZoomLevel } from './types';\n\n// Action Types\nexport const SET_ZOOM_LEVEL = 'SET_ZOOM_LEVEL';\nexport const SET_INITIAL_ZOOM_LEVEL = 'SET_INITIAL_ZOOM_LEVEL';\n\n// Action Interfaces\nexport interface SetZoomLevelAction extends Action {\n type: typeof SET_ZOOM_LEVEL;\n payload: {\n zoomLevel: ZoomLevel;\n currentZoomLevel: number;\n };\n}\n\nexport interface SetInitialZoomLevelAction extends Action {\n type: typeof SET_INITIAL_ZOOM_LEVEL;\n payload: {\n zoomLevel: ZoomLevel;\n };\n}\n\n// Union Type for All Actions\nexport type ZoomAction = SetZoomLevelAction | SetInitialZoomLevelAction;\n\n// Action Creators\nexport function setZoomLevel(zoomLevel: ZoomLevel, currentZoomLevel: number): SetZoomLevelAction {\n return {\n type: SET_ZOOM_LEVEL,\n payload: { zoomLevel, currentZoomLevel },\n };\n}\n\nexport function setInitialZoomLevel(zoomLevel: ZoomLevel): SetInitialZoomLevelAction {\n return {\n type: SET_INITIAL_ZOOM_LEVEL,\n payload: { zoomLevel },\n };\n}\n","import { Reducer } from '@embedpdf/core';\n\nimport { SET_INITIAL_ZOOM_LEVEL, SET_ZOOM_LEVEL, ZoomAction } from './actions';\nimport { ZoomState, ZoomMode } from './types';\n\nexport const initialState: ZoomState = {\n zoomLevel: ZoomMode.Automatic,\n currentZoomLevel: 1,\n};\n\nexport const zoomReducer: Reducer<ZoomState, ZoomAction> = (state = initialState, action) => {\n switch (action.type) {\n case SET_ZOOM_LEVEL:\n return {\n ...state,\n zoomLevel: action.payload.zoomLevel,\n currentZoomLevel: action.payload.currentZoomLevel,\n };\n case SET_INITIAL_ZOOM_LEVEL:\n return {\n ...state,\n zoomLevel: action.payload.zoomLevel,\n };\n default:\n return state;\n }\n};\n","import {\n BasePlugin,\n PluginRegistry,\n createEmitter,\n clamp,\n setScale,\n SET_PAGES,\n SET_DOCUMENT,\n getPagesWithRotatedSize,\n SET_ROTATION,\n createBehaviorEmitter,\n} from '@embedpdf/core';\nimport { ScrollPlugin, ScrollCapability } from '@embedpdf/plugin-scroll';\nimport { ViewportPlugin, ViewportCapability, ViewportMetrics } from '@embedpdf/plugin-viewport';\n\nimport { setInitialZoomLevel, setZoomLevel, ZoomAction } from './actions';\nimport {\n ZoomPluginConfig,\n ZoomState,\n ZoomMode,\n Point,\n ZoomChangeEvent,\n ZoomCapability,\n ZoomPreset,\n ZoomRangeStep,\n VerticalZoomFocus,\n ZoomRequest,\n} from './types';\nimport {\n InteractionManagerCapability,\n InteractionManagerPlugin,\n} from '@embedpdf/plugin-interaction-manager';\nimport { Rect, rotateRect } from '@embedpdf/models';\n\nexport class ZoomPlugin extends BasePlugin<\n ZoomPluginConfig,\n ZoomCapability,\n ZoomState,\n ZoomAction\n> {\n static readonly id = 'zoom' as const;\n /* ------------------------------------------------------------------ */\n /* internals */\n /* ------------------------------------------------------------------ */\n private readonly zoom$ = createEmitter<ZoomChangeEvent>();\n private readonly state$ = createBehaviorEmitter<ZoomState>();\n private readonly viewport: ViewportCapability;\n private readonly viewportPlugin: ViewportPlugin;\n private readonly scroll: ScrollCapability;\n private readonly interactionManager: InteractionManagerCapability | null;\n private readonly presets: ZoomPreset[];\n private readonly zoomRanges: ZoomRangeStep[];\n\n private readonly minZoom: number;\n private readonly maxZoom: number;\n private readonly zoomStep: number;\n\n /* ------------------------------------------------------------------ */\n constructor(id: string, registry: PluginRegistry, cfg: ZoomPluginConfig) {\n super(id, registry);\n\n this.viewportPlugin = registry.getPlugin<ViewportPlugin>('viewport')!;\n this.viewport = this.viewportPlugin.provides();\n this.scroll = registry.getPlugin<ScrollPlugin>('scroll')!.provides();\n const interactionManager = registry.getPlugin<InteractionManagerPlugin>('interaction-manager');\n this.interactionManager = interactionManager?.provides() ?? null;\n this.minZoom = cfg.minZoom ?? 0.25;\n this.maxZoom = cfg.maxZoom ?? 10;\n this.zoomStep = cfg.zoomStep ?? 0.1;\n this.presets = cfg.presets ?? [];\n this.zoomRanges = this.normalizeRanges(cfg.zoomRanges ?? []);\n this.dispatch(setInitialZoomLevel(cfg.defaultZoomLevel));\n /* keep \"automatic\" modes up to date -------------------------------- */\n this.viewport.onViewportResize(() => this.recalcAuto(VerticalZoomFocus.Top), {\n mode: 'debounce',\n wait: 150,\n });\n this.coreStore.onAction(SET_ROTATION, () => this.recalcAuto(VerticalZoomFocus.Top));\n this.coreStore.onAction(SET_PAGES, () => this.recalcAuto(VerticalZoomFocus.Top));\n this.coreStore.onAction(SET_DOCUMENT, () => this.recalcAuto(VerticalZoomFocus.Top));\n this.interactionManager?.registerMode({\n id: 'marqueeZoom',\n scope: 'page',\n exclusive: true,\n cursor: 'zoom-in',\n });\n this.resetReady();\n }\n\n /* ------------------------------------------------------------------ */\n /* capability */\n /* ------------------------------------------------------------------ */\n protected buildCapability(): ZoomCapability {\n return {\n onZoomChange: this.zoom$.on,\n onStateChange: this.state$.on,\n zoomIn: () => {\n const cur = this.state.currentZoomLevel;\n return this.handleRequest({ level: cur, delta: this.stepFor(cur) });\n },\n zoomOut: () => {\n const cur = this.state.currentZoomLevel;\n return this.handleRequest({ level: cur, delta: -this.stepFor(cur) });\n },\n zoomToArea: (pageIndex, rect) => this.handleZoomToArea(pageIndex, rect),\n requestZoom: (level, c) => this.handleRequest({ level, center: c }),\n requestZoomBy: (d, c) => {\n const cur = this.state.currentZoomLevel;\n const target = this.toZoom(cur + d);\n return this.handleRequest({ level: target, center: c });\n },\n enableMarqueeZoom: () => {\n this.interactionManager?.activate('marqueeZoom');\n },\n disableMarqueeZoom: () => {\n this.interactionManager?.activate('default');\n },\n toggleMarqueeZoom: () => {\n if (this.interactionManager?.getActiveMode() === 'marqueeZoom') {\n this.interactionManager?.activate('default');\n } else {\n this.interactionManager?.activate('marqueeZoom');\n }\n },\n isMarqueeZoomActive: () => this.interactionManager?.getActiveMode() === 'marqueeZoom',\n getState: () => this.state,\n getPresets: () => this.presets,\n };\n }\n\n /* ------------------------------------------------------------------ */\n /* plugin life‑cycle */\n /* ------------------------------------------------------------------ */\n async initialize(): Promise<void> {\n /* apply the initial zoom */\n }\n\n async destroy() {\n this.zoom$.clear();\n }\n\n /**\n * Sort ranges once, make sure they are sane\n */\n private normalizeRanges(ranges: ZoomRangeStep[]): ZoomRangeStep[] {\n return [...ranges]\n .filter((r) => r.step > 0 && r.max > r.min) // basic sanity\n .sort((a, b) => a.min - b.min);\n }\n\n /** pick the step that applies to a given numeric zoom */\n private stepFor(zoom: number): number {\n const r = this.zoomRanges.find((r) => zoom >= r.min && zoom < r.max);\n return r ? r.step : this.zoomStep; // fallback\n }\n\n /** clamp + round helper reused later */\n private toZoom(v: number) {\n return parseFloat(clamp(v, this.minZoom, this.maxZoom).toFixed(2));\n }\n\n /* ------------------------------------------------------------------ */\n /* main entry – handles **every** zoom request */\n /* ------------------------------------------------------------------ */\n private handleRequest({\n level,\n delta = 0,\n center,\n focus = VerticalZoomFocus.Center,\n align = 'keep',\n }: ZoomRequest) {\n const metrics = this.viewport.getMetrics();\n const oldZoom = this.state.currentZoomLevel;\n\n if (metrics.clientWidth === 0 || metrics.clientHeight === 0) {\n return;\n }\n\n /* ------------------------------------------------------------------ */\n /* step 1 – resolve the **target numeric zoom** */\n /* ------------------------------------------------------------------ */\n const base = typeof level === 'number' ? level : this.computeZoomForMode(level, metrics);\n\n if (base === false) {\n return;\n }\n const exactZoom = clamp(base + delta, this.minZoom, this.maxZoom);\n const newZoom = Math.floor(exactZoom * 100) / 100;\n\n /* ------------------------------------------------------------------ */\n /* step 2 – figure out the viewport point we should keep under focus */\n /* ------------------------------------------------------------------ */\n const focusPoint: Point = center ?? {\n vx: metrics.clientWidth / 2,\n vy: focus === VerticalZoomFocus.Top ? 0 : metrics.clientHeight / 2,\n };\n\n /* ------------------------------------------------------------------ */\n /* step 3 – translate that into desired scroll offsets */\n /* ------------------------------------------------------------------ */\n const { desiredScrollLeft, desiredScrollTop } = this.computeScrollForZoomChange(\n metrics,\n oldZoom,\n newZoom,\n focusPoint,\n align,\n );\n\n /* ------------------------------------------------------------------ */\n /* step 4 – dispatch + notify */\n /* ------------------------------------------------------------------ */\n\n if (!isNaN(desiredScrollLeft) && !isNaN(desiredScrollTop)) {\n this.viewportPlugin.setViewportScrollMetrics({\n scrollLeft: desiredScrollLeft,\n scrollTop: desiredScrollTop,\n });\n }\n\n this.dispatch(setZoomLevel(typeof level === 'number' ? newZoom : level, newZoom));\n this.dispatchCoreAction(setScale(newZoom));\n this.markReady();\n\n this.viewport.scrollTo({\n x: desiredScrollLeft,\n y: desiredScrollTop,\n behavior: 'instant',\n });\n\n const evt: ZoomChangeEvent = {\n oldZoom,\n newZoom,\n level,\n center: focusPoint,\n desiredScrollLeft,\n desiredScrollTop,\n viewport: metrics,\n };\n\n this.zoom$.emit(evt);\n }\n\n /* ------------------------------------------------------------------ */\n /* helpers */\n /* ------------------------------------------------------------------ */\n\n /** numeric zoom for Automatic / FitPage / FitWidth */\n private computeZoomForMode(mode: ZoomMode, vp: ViewportMetrics): number | false {\n const spreads = getPagesWithRotatedSize(this.coreState.core);\n if (!spreads.length) return false;\n\n const pgGap = this.scroll.getPageGap();\n const vpGap = this.viewport.getViewportGap();\n\n if (vp.clientWidth === 0 || vp.clientHeight === 0) {\n return false;\n }\n\n // Available space after accounting for fixed viewport gaps\n const availableWidth = vp.clientWidth - 2 * vpGap;\n const availableHeight = vp.clientHeight - 2 * vpGap;\n\n if (availableWidth <= 0 || availableHeight <= 0) {\n return false;\n }\n\n let maxContentW = 0,\n maxContentH = 0;\n\n spreads.forEach((spread) => {\n // Only include scalable content (pages + page gaps), not viewport gaps\n const contentW = spread.reduce((s, p, i) => s + p.rotatedSize.width + (i ? pgGap : 0), 0);\n const contentH = Math.max(...spread.map((p) => p.rotatedSize.height));\n maxContentW = Math.max(maxContentW, contentW);\n maxContentH = Math.max(maxContentH, contentH);\n });\n\n switch (mode) {\n case ZoomMode.FitWidth:\n return availableWidth / maxContentW;\n case ZoomMode.FitPage:\n return Math.min(availableWidth / maxContentW, availableHeight / maxContentH);\n case ZoomMode.Automatic:\n return Math.min(availableWidth / maxContentW, 1);\n /* istanbul ignore next */\n default:\n return 1;\n }\n }\n\n /** where to scroll so that *focus* stays stable after scaling */\n private computeScrollForZoomChange(\n vp: ViewportMetrics,\n oldZoom: number,\n newZoom: number,\n focus: Point,\n align: 'keep' | 'center' = 'keep',\n ) {\n /* unscaled content size ------------------------------------------- */\n const layout = this.scroll.getLayout();\n const vpGap = this.viewport.getViewportGap();\n\n const contentW = layout.totalContentSize.width;\n const contentH = layout.totalContentSize.height;\n\n // Available space for content (excluding fixed viewport gaps)\n const availableWidth = vp.clientWidth - 2 * vpGap;\n const availableHeight = vp.clientHeight - 2 * vpGap;\n\n /* helper: offset if content is narrower than available space ------- */\n const off = (availableSpace: number, cw: number, zoom: number) =>\n cw * zoom < availableSpace ? (availableSpace - cw * zoom) / 2 : 0;\n\n const offXold = off(availableWidth, contentW, oldZoom);\n const offYold = off(availableHeight, contentH, oldZoom);\n\n const offXnew = off(availableWidth, contentW, newZoom);\n const offYnew = off(availableHeight, contentH, newZoom);\n\n /* content coords of the focal point -------------------------------- */\n // Adjust focus point to account for vpGap and centering offset\n const cx = (vp.scrollLeft + focus.vx - vpGap - offXold) / oldZoom;\n const cy = (vp.scrollTop + focus.vy - vpGap - offYold) / oldZoom;\n\n /* new scroll so that (cx,cy) appears under focus again ------------- */\n const baseLeft = cx * newZoom + vpGap + offXnew;\n const baseTop = cy * newZoom + vpGap + offYnew;\n\n const desiredScrollLeft =\n align === 'center' ? baseLeft - vp.clientWidth / 2 : baseLeft - focus.vx;\n const desiredScrollTop =\n align === 'center' ? baseTop - vp.clientHeight / 2 : baseTop - focus.vy;\n\n return {\n desiredScrollLeft: Math.max(0, desiredScrollLeft),\n desiredScrollTop: Math.max(0, desiredScrollTop),\n };\n }\n\n private handleZoomToArea(pageIndex: number, rect: Rect) {\n /* -------------------------------------------------- */\n /* 0 – rotation that applies to this page */\n /* -------------------------------------------------- */\n const rotation = this.coreState.core.rotation;\n\n /* -------------------------------------------------- */\n /* viewport + layout basics */\n /* -------------------------------------------------- */\n const vp = this.viewport.getMetrics();\n const vpGap = this.viewport.getViewportGap();\n const oldZ = this.state.currentZoomLevel;\n\n const availableW = vp.clientWidth - 2 * vpGap;\n const availableH = vp.clientHeight - 2 * vpGap;\n\n const layout = this.scroll.getLayout();\n\n /* which virtual item holds the page? */\n const vItem = layout.virtualItems.find((it) =>\n it.pageLayouts.some((p) => p.pageIndex === pageIndex),\n );\n if (!vItem) return;\n\n /* the page layout inside that virtual item */\n const pageRel = vItem.pageLayouts.find((p) => p.pageIndex === pageIndex)!;\n\n /* -------------------------------------------------- */\n /* 1 – rect → rotated‑page space */\n /* -------------------------------------------------- */\n const rotatedRect = rotateRect(\n {\n width: pageRel.width,\n height: pageRel.height,\n },\n rect,\n rotation,\n );\n\n /* -------------------------------------------------- */\n /* 2 – numeric zoom so the rect fits */\n /* -------------------------------------------------- */\n const targetZoom = this.toZoom(\n Math.min(availableW / rotatedRect.size.width, availableH / rotatedRect.size.height),\n );\n\n /* -------------------------------------------------- */\n /* 3 – centre of that rect in *content* coordinates */\n /* -------------------------------------------------- */\n const pageAbsX = vItem.x + pageRel.x;\n const pageAbsY = vItem.y + pageRel.y;\n\n const cxContent = pageAbsX + rotatedRect.origin.x + rotatedRect.size.width / 2;\n const cyContent = pageAbsY + rotatedRect.origin.y + rotatedRect.size.height / 2;\n\n /* -------------------------------------------------- */\n /* 4 – centre in *viewport* coords before zoom */\n /* -------------------------------------------------- */\n const off = (avail: number, cw: number, z: number) =>\n cw * z < avail ? (avail - cw * z) / 2 : 0;\n\n const offXold = off(availableW, layout.totalContentSize.width, oldZ);\n const offYold = off(availableH, layout.totalContentSize.height, oldZ);\n\n const centerVX = vpGap + offXold + cxContent * oldZ - vp.scrollLeft;\n const centerVY = vpGap + offYold + cyContent * oldZ - vp.scrollTop;\n\n /* -------------------------------------------------- */\n /* 5 – hand off to the generic zoom handler */\n /* -------------------------------------------------- */\n this.handleRequest({\n level: targetZoom,\n center: { vx: centerVX, vy: centerVY },\n align: 'center',\n });\n }\n\n /** recalculates Automatic / Fit* when viewport or pages change */\n private recalcAuto(focus?: VerticalZoomFocus) {\n const s = this.state;\n if (\n s.zoomLevel === ZoomMode.Automatic ||\n s.zoomLevel === ZoomMode.FitPage ||\n s.zoomLevel === ZoomMode.FitWidth\n )\n this.handleRequest({ level: s.zoomLevel, focus });\n }\n\n override onStoreUpdated(_prevState: ZoomState, newState: ZoomState): void {\n this.state$.emit(newState);\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { ZoomAction } from './actions';\nimport { manifest, ZOOM_PLUGIN_ID } from './manifest';\nimport { zoomReducer, initialState } from './reducer';\nimport { ZoomPluginConfig, ZoomState } from './types';\nimport { ZoomPlugin } from './zoom-plugin';\n\nexport const ZoomPluginPackage: PluginPackage<ZoomPlugin, ZoomPluginConfig, ZoomState, ZoomAction> =\n {\n manifest,\n create: (registry, _engine, config) => new ZoomPlugin(ZOOM_PLUGIN_ID, registry, config),\n reducer: zoomReducer,\n initialState,\n };\n\nexport * from './zoom-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"mappings":"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","names":["ZoomMode","VerticalZoomFocus","r"]}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/types.ts","../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/zoom-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePluginConfig, EventHook } from '@embedpdf/core';\nimport { Rect } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\n\n/* ------------------------------------------------------------------ */\n/* public */\n/* ------------------------------------------------------------------ */\n\nexport enum ZoomMode {\n Automatic = 'automatic',\n FitPage = 'fit-page',\n FitWidth = 'fit-width',\n}\n\nexport type ZoomLevel = ZoomMode | number;\n\nexport interface Point {\n vx: number;\n vy: number;\n}\n\nexport interface ZoomChangeEvent {\n /** old and new *actual* scale factors */\n oldZoom: number;\n newZoom: number;\n\n /** level used to obtain the newZoom (number | mode) */\n level: ZoomLevel;\n\n /** viewport point kept under the finger / mouse‑wheel focus */\n center: Point;\n\n /** where the viewport should scroll to after the scale change */\n desiredScrollLeft: number;\n desiredScrollTop: number;\n\n /** metrics at the moment the zoom was requested */\n viewport: ViewportMetrics;\n}\n\nexport interface ZoomCapability {\n /** subscribe – returns the unsubscribe function */\n onZoomChange: EventHook<ZoomChangeEvent>;\n /** subscribe – returns the unsubscribe function */\n onStateChange: EventHook<ZoomState>;\n\n /** absolute requests -------------------------------------------------- */\n requestZoom(level: ZoomLevel, center?: Point): void;\n /** relative requests -------------------------------------------------- */\n requestZoomBy(delta: number, center?: Point): void;\n\n /** absolute requests -------------------------------------------------- */\n zoomIn(): void;\n zoomOut(): void;\n\n zoomToArea(pageIndex: number, rect: Rect): void;\n\n /** zoom in on an area -------------------------------------------------- */\n enableMarqueeZoom(): void;\n disableMarqueeZoom(): void;\n toggleMarqueeZoom(): void;\n isMarqueeZoomActive(): boolean;\n\n getState(): ZoomState;\n getPresets(): ZoomPreset[];\n}\n\n/* ------------------------------------------------------------------ */\n/* config / store */\n/* ------------------------------------------------------------------ */\n\nexport interface ZoomRangeStep {\n min: number;\n max: number;\n step: number;\n}\n\nexport interface ZoomPreset {\n name: string;\n value: ZoomLevel;\n icon?: string;\n}\n\nexport interface ZoomPluginConfig extends BasePluginConfig {\n defaultZoomLevel: ZoomLevel;\n minZoom?: number;\n maxZoom?: number;\n zoomStep?: number;\n zoomRanges?: ZoomRangeStep[]; // Define different step sizes for different zoom ranges\n presets?: ZoomPreset[]; // Preset zoom options for dropdown\n}\n\nexport interface ZoomState {\n zoomLevel: ZoomLevel; // last **requested** level\n currentZoomLevel: number; // actual numeric factor\n}\n\nexport enum VerticalZoomFocus {\n Center,\n Top,\n}\n\nexport interface ZoomRequest {\n level: ZoomLevel;\n delta?: number;\n center?: Point;\n focus?: VerticalZoomFocus;\n /** Scroll so that the focal point ends up …\n * ▸ `\"keep\"` (default) at the same viewport coords\n * ▸ `\"center\"` centred in the viewport */\n align?: 'keep' | 'center';\n}\n","import { PluginManifest } from '@embedpdf/core';\n\nimport { ZoomMode, ZoomPluginConfig } from './types';\n\nexport const ZOOM_PLUGIN_ID = 'zoom';\n\nexport const manifest: PluginManifest<ZoomPluginConfig> = {\n id: ZOOM_PLUGIN_ID,\n name: 'Zoom Plugin',\n version: '1.0.0',\n provides: ['zoom'],\n requires: ['viewport', 'scroll'],\n optional: ['interaction-manager'],\n defaultConfig: {\n enabled: true,\n defaultZoomLevel: ZoomMode.Automatic,\n minZoom: 0.2,\n maxZoom: 60,\n zoomStep: 0.1,\n zoomRanges: [\n {\n min: 0.2,\n max: 0.5,\n step: 0.05,\n },\n {\n min: 0.5,\n max: 1.0,\n step: 0.1,\n },\n {\n min: 1.0,\n max: 2.0,\n step: 0.2,\n },\n {\n min: 2.0,\n max: 4.0,\n step: 0.4,\n },\n {\n min: 4.0,\n max: 10.0,\n step: 0.8,\n },\n {\n min: 10.0,\n max: 20.0,\n step: 1.6,\n },\n {\n min: 20.0,\n max: 40.0,\n step: 3.2,\n },\n {\n min: 40.0,\n max: 60.0,\n step: 6.4,\n },\n ],\n presets: [\n {\n name: 'Fit Page',\n value: ZoomMode.FitPage,\n },\n {\n name: 'Fit Width',\n value: ZoomMode.FitWidth,\n },\n {\n name: 'Automatic',\n value: ZoomMode.Automatic,\n },\n {\n name: '25%',\n value: 0.25,\n },\n {\n name: '50%',\n value: 0.5,\n },\n {\n name: '100%',\n value: 1,\n },\n {\n name: '125%',\n value: 1.25,\n },\n {\n name: '150%',\n value: 1.5,\n },\n {\n name: '200%',\n value: 2,\n },\n {\n name: '400%',\n value: 4,\n },\n {\n name: '800%',\n value: 8,\n },\n {\n name: '1600%',\n value: 16,\n },\n ],\n },\n};\n","import { Action } from '@embedpdf/core';\n\nimport { ZoomLevel } from './types';\n\n// Action Types\nexport const SET_ZOOM_LEVEL = 'SET_ZOOM_LEVEL';\nexport const SET_INITIAL_ZOOM_LEVEL = 'SET_INITIAL_ZOOM_LEVEL';\n\n// Action Interfaces\nexport interface SetZoomLevelAction extends Action {\n type: typeof SET_ZOOM_LEVEL;\n payload: {\n zoomLevel: ZoomLevel;\n currentZoomLevel: number;\n };\n}\n\nexport interface SetInitialZoomLevelAction extends Action {\n type: typeof SET_INITIAL_ZOOM_LEVEL;\n payload: {\n zoomLevel: ZoomLevel;\n };\n}\n\n// Union Type for All Actions\nexport type ZoomAction = SetZoomLevelAction | SetInitialZoomLevelAction;\n\n// Action Creators\nexport function setZoomLevel(zoomLevel: ZoomLevel, currentZoomLevel: number): SetZoomLevelAction {\n return {\n type: SET_ZOOM_LEVEL,\n payload: { zoomLevel, currentZoomLevel },\n };\n}\n\nexport function setInitialZoomLevel(zoomLevel: ZoomLevel): SetInitialZoomLevelAction {\n return {\n type: SET_INITIAL_ZOOM_LEVEL,\n payload: { zoomLevel },\n };\n}\n","import { Reducer } from '@embedpdf/core';\n\nimport { SET_INITIAL_ZOOM_LEVEL, SET_ZOOM_LEVEL, ZoomAction } from './actions';\nimport { ZoomState, ZoomMode } from './types';\n\nexport const initialState: ZoomState = {\n zoomLevel: ZoomMode.Automatic,\n currentZoomLevel: 1,\n};\n\nexport const zoomReducer: Reducer<ZoomState, ZoomAction> = (state = initialState, action) => {\n switch (action.type) {\n case SET_ZOOM_LEVEL:\n return {\n ...state,\n zoomLevel: action.payload.zoomLevel,\n currentZoomLevel: action.payload.currentZoomLevel,\n };\n case SET_INITIAL_ZOOM_LEVEL:\n return {\n ...state,\n zoomLevel: action.payload.zoomLevel,\n };\n default:\n return state;\n }\n};\n","import {\n BasePlugin,\n PluginRegistry,\n createEmitter,\n clamp,\n setScale,\n SET_PAGES,\n SET_DOCUMENT,\n getPagesWithRotatedSize,\n SET_ROTATION,\n createBehaviorEmitter,\n} from '@embedpdf/core';\nimport { ScrollPlugin, ScrollCapability } from '@embedpdf/plugin-scroll';\nimport { ViewportPlugin, ViewportCapability, ViewportMetrics } from '@embedpdf/plugin-viewport';\n\nimport { setInitialZoomLevel, setZoomLevel, ZoomAction } from './actions';\nimport {\n ZoomPluginConfig,\n ZoomState,\n ZoomMode,\n Point,\n ZoomChangeEvent,\n ZoomCapability,\n ZoomPreset,\n ZoomRangeStep,\n VerticalZoomFocus,\n ZoomRequest,\n} from './types';\nimport {\n InteractionManagerCapability,\n InteractionManagerPlugin,\n} from '@embedpdf/plugin-interaction-manager';\nimport { Rect, rotateRect } from '@embedpdf/models';\n\nexport class ZoomPlugin extends BasePlugin<\n ZoomPluginConfig,\n ZoomCapability,\n ZoomState,\n ZoomAction\n> {\n static readonly id = 'zoom' as const;\n /* ------------------------------------------------------------------ */\n /* internals */\n /* ------------------------------------------------------------------ */\n private readonly zoom$ = createEmitter<ZoomChangeEvent>();\n private readonly state$ = createBehaviorEmitter<ZoomState>();\n private readonly viewport: ViewportCapability;\n private readonly viewportPlugin: ViewportPlugin;\n private readonly scroll: ScrollCapability;\n private readonly interactionManager: InteractionManagerCapability | null;\n private readonly presets: ZoomPreset[];\n private readonly zoomRanges: ZoomRangeStep[];\n\n private readonly minZoom: number;\n private readonly maxZoom: number;\n private readonly zoomStep: number;\n\n /* ------------------------------------------------------------------ */\n constructor(id: string, registry: PluginRegistry, cfg: ZoomPluginConfig) {\n super(id, registry);\n\n this.viewportPlugin = registry.getPlugin<ViewportPlugin>('viewport')!;\n this.viewport = this.viewportPlugin.provides();\n this.scroll = registry.getPlugin<ScrollPlugin>('scroll')!.provides();\n const interactionManager = registry.getPlugin<InteractionManagerPlugin>('interaction-manager');\n this.interactionManager = interactionManager?.provides() ?? null;\n this.minZoom = cfg.minZoom ?? 0.25;\n this.maxZoom = cfg.maxZoom ?? 10;\n this.zoomStep = cfg.zoomStep ?? 0.1;\n this.presets = cfg.presets ?? [];\n this.zoomRanges = this.normalizeRanges(cfg.zoomRanges ?? []);\n this.dispatch(setInitialZoomLevel(cfg.defaultZoomLevel));\n /* keep \"automatic\" modes up to date -------------------------------- */\n this.viewport.onViewportResize(() => this.recalcAuto(VerticalZoomFocus.Top), {\n mode: 'debounce',\n wait: 150,\n });\n this.coreStore.onAction(SET_ROTATION, () => this.recalcAuto(VerticalZoomFocus.Top));\n this.coreStore.onAction(SET_PAGES, () => this.recalcAuto(VerticalZoomFocus.Top));\n this.coreStore.onAction(SET_DOCUMENT, () => this.recalcAuto(VerticalZoomFocus.Top));\n this.interactionManager?.registerMode({\n id: 'marqueeZoom',\n scope: 'page',\n exclusive: true,\n cursor: 'zoom-in',\n });\n this.resetReady();\n }\n\n /* ------------------------------------------------------------------ */\n /* capability */\n /* ------------------------------------------------------------------ */\n protected buildCapability(): ZoomCapability {\n return {\n onZoomChange: this.zoom$.on,\n onStateChange: this.state$.on,\n zoomIn: () => {\n const cur = this.state.currentZoomLevel;\n return this.handleRequest({ level: cur, delta: this.stepFor(cur) });\n },\n zoomOut: () => {\n const cur = this.state.currentZoomLevel;\n return this.handleRequest({ level: cur, delta: -this.stepFor(cur) });\n },\n zoomToArea: (pageIndex, rect) => this.handleZoomToArea(pageIndex, rect),\n requestZoom: (level, c) => this.handleRequest({ level, center: c }),\n requestZoomBy: (d, c) => {\n const cur = this.state.currentZoomLevel;\n const target = this.toZoom(cur + d);\n return this.handleRequest({ level: target, center: c });\n },\n enableMarqueeZoom: () => {\n this.interactionManager?.activate('marqueeZoom');\n },\n disableMarqueeZoom: () => {\n this.interactionManager?.activate('default');\n },\n toggleMarqueeZoom: () => {\n if (this.interactionManager?.getActiveMode() === 'marqueeZoom') {\n this.interactionManager?.activate('default');\n } else {\n this.interactionManager?.activate('marqueeZoom');\n }\n },\n isMarqueeZoomActive: () => this.interactionManager?.getActiveMode() === 'marqueeZoom',\n getState: () => this.state,\n getPresets: () => this.presets,\n };\n }\n\n /* ------------------------------------------------------------------ */\n /* plugin life‑cycle */\n /* ------------------------------------------------------------------ */\n async initialize(): Promise<void> {\n /* apply the initial zoom */\n }\n\n async destroy() {\n this.zoom$.clear();\n }\n\n /**\n * Sort ranges once, make sure they are sane\n */\n private normalizeRanges(ranges: ZoomRangeStep[]): ZoomRangeStep[] {\n return [...ranges]\n .filter((r) => r.step > 0 && r.max > r.min) // basic sanity\n .sort((a, b) => a.min - b.min);\n }\n\n /** pick the step that applies to a given numeric zoom */\n private stepFor(zoom: number): number {\n const r = this.zoomRanges.find((r) => zoom >= r.min && zoom < r.max);\n return r ? r.step : this.zoomStep; // fallback\n }\n\n /** clamp + round helper reused later */\n private toZoom(v: number) {\n return parseFloat(clamp(v, this.minZoom, this.maxZoom).toFixed(2));\n }\n\n /* ------------------------------------------------------------------ */\n /* main entry – handles **every** zoom request */\n /* ------------------------------------------------------------------ */\n private handleRequest({\n level,\n delta = 0,\n center,\n focus = VerticalZoomFocus.Center,\n align = 'keep',\n }: ZoomRequest) {\n const metrics = this.viewport.getMetrics();\n const oldZoom = this.state.currentZoomLevel;\n\n if (metrics.clientWidth === 0 || metrics.clientHeight === 0) {\n return;\n }\n\n /* ------------------------------------------------------------------ */\n /* step 1 – resolve the **target numeric zoom** */\n /* ------------------------------------------------------------------ */\n const base = typeof level === 'number' ? level : this.computeZoomForMode(level, metrics);\n\n if (base === false) {\n return;\n }\n const exactZoom = clamp(base + delta, this.minZoom, this.maxZoom);\n const newZoom = Math.floor(exactZoom * 100) / 100;\n\n /* ------------------------------------------------------------------ */\n /* step 2 – figure out the viewport point we should keep under focus */\n /* ------------------------------------------------------------------ */\n const focusPoint: Point = center ?? {\n vx: metrics.clientWidth / 2,\n vy: focus === VerticalZoomFocus.Top ? 0 : metrics.clientHeight / 2,\n };\n\n /* ------------------------------------------------------------------ */\n /* step 3 – translate that into desired scroll offsets */\n /* ------------------------------------------------------------------ */\n const { desiredScrollLeft, desiredScrollTop } = this.computeScrollForZoomChange(\n metrics,\n oldZoom,\n newZoom,\n focusPoint,\n align,\n );\n\n /* ------------------------------------------------------------------ */\n /* step 4 – dispatch + notify */\n /* ------------------------------------------------------------------ */\n\n if (!isNaN(desiredScrollLeft) && !isNaN(desiredScrollTop)) {\n this.viewportPlugin.setViewportScrollMetrics({\n scrollLeft: desiredScrollLeft,\n scrollTop: desiredScrollTop,\n });\n }\n\n this.dispatch(setZoomLevel(typeof level === 'number' ? newZoom : level, newZoom));\n this.dispatchCoreAction(setScale(newZoom));\n this.markReady();\n\n this.viewport.scrollTo({\n x: desiredScrollLeft,\n y: desiredScrollTop,\n behavior: 'instant',\n });\n\n const evt: ZoomChangeEvent = {\n oldZoom,\n newZoom,\n level,\n center: focusPoint,\n desiredScrollLeft,\n desiredScrollTop,\n viewport: metrics,\n };\n\n this.zoom$.emit(evt);\n }\n\n /* ------------------------------------------------------------------ */\n /* helpers */\n /* ------------------------------------------------------------------ */\n\n /** numeric zoom for Automatic / FitPage / FitWidth */\n private computeZoomForMode(mode: ZoomMode, vp: ViewportMetrics): number | false {\n const spreads = getPagesWithRotatedSize(this.coreState.core);\n if (!spreads.length) return false;\n\n const pgGap = this.scroll.getPageGap();\n const vpGap = this.viewport.getViewportGap();\n\n if (vp.clientWidth === 0 || vp.clientHeight === 0) {\n return false;\n }\n\n // Available space after accounting for fixed viewport gaps\n const availableWidth = vp.clientWidth - 2 * vpGap;\n const availableHeight = vp.clientHeight - 2 * vpGap;\n\n if (availableWidth <= 0 || availableHeight <= 0) {\n return false;\n }\n\n let maxContentW = 0,\n maxContentH = 0;\n\n spreads.forEach((spread) => {\n // Only include scalable content (pages + page gaps), not viewport gaps\n const contentW = spread.reduce((s, p, i) => s + p.rotatedSize.width + (i ? pgGap : 0), 0);\n const contentH = Math.max(...spread.map((p) => p.rotatedSize.height));\n maxContentW = Math.max(maxContentW, contentW);\n maxContentH = Math.max(maxContentH, contentH);\n });\n\n switch (mode) {\n case ZoomMode.FitWidth:\n return availableWidth / maxContentW;\n case ZoomMode.FitPage:\n return Math.min(availableWidth / maxContentW, availableHeight / maxContentH);\n case ZoomMode.Automatic:\n return Math.min(availableWidth / maxContentW, 1);\n /* istanbul ignore next */\n default:\n return 1;\n }\n }\n\n /** where to scroll so that *focus* stays stable after scaling */\n private computeScrollForZoomChange(\n vp: ViewportMetrics,\n oldZoom: number,\n newZoom: number,\n focus: Point,\n align: 'keep' | 'center' = 'keep',\n ) {\n /* unscaled content size ------------------------------------------- */\n const layout = this.scroll.getLayout();\n const vpGap = this.viewport.getViewportGap();\n\n const contentW = layout.totalContentSize.width;\n const contentH = layout.totalContentSize.height;\n\n // Available space for content (excluding fixed viewport gaps)\n const availableWidth = vp.clientWidth - 2 * vpGap;\n const availableHeight = vp.clientHeight - 2 * vpGap;\n\n /* helper: offset if content is narrower than available space ------- */\n const off = (availableSpace: number, cw: number, zoom: number) =>\n cw * zoom < availableSpace ? (availableSpace - cw * zoom) / 2 : 0;\n\n const offXold = off(availableWidth, contentW, oldZoom);\n const offYold = off(availableHeight, contentH, oldZoom);\n\n const offXnew = off(availableWidth, contentW, newZoom);\n const offYnew = off(availableHeight, contentH, newZoom);\n\n /* content coords of the focal point -------------------------------- */\n // Adjust focus point to account for vpGap and centering offset\n const cx = (vp.scrollLeft + focus.vx - vpGap - offXold) / oldZoom;\n const cy = (vp.scrollTop + focus.vy - vpGap - offYold) / oldZoom;\n\n /* new scroll so that (cx,cy) appears under focus again ------------- */\n const baseLeft = cx * newZoom + vpGap + offXnew;\n const baseTop = cy * newZoom + vpGap + offYnew;\n\n const desiredScrollLeft =\n align === 'center' ? baseLeft - vp.clientWidth / 2 : baseLeft - focus.vx;\n const desiredScrollTop =\n align === 'center' ? baseTop - vp.clientHeight / 2 : baseTop - focus.vy;\n\n return {\n desiredScrollLeft: Math.max(0, desiredScrollLeft),\n desiredScrollTop: Math.max(0, desiredScrollTop),\n };\n }\n\n private handleZoomToArea(pageIndex: number, rect: Rect) {\n /* -------------------------------------------------- */\n /* 0 – rotation that applies to this page */\n /* -------------------------------------------------- */\n const rotation = this.coreState.core.rotation;\n\n /* -------------------------------------------------- */\n /* viewport + layout basics */\n /* -------------------------------------------------- */\n const vp = this.viewport.getMetrics();\n const vpGap = this.viewport.getViewportGap();\n const oldZ = this.state.currentZoomLevel;\n\n const availableW = vp.clientWidth - 2 * vpGap;\n const availableH = vp.clientHeight - 2 * vpGap;\n\n const layout = this.scroll.getLayout();\n\n /* which virtual item holds the page? */\n const vItem = layout.virtualItems.find((it) =>\n it.pageLayouts.some((p) => p.pageIndex === pageIndex),\n );\n if (!vItem) return;\n\n /* the page layout inside that virtual item */\n const pageRel = vItem.pageLayouts.find((p) => p.pageIndex === pageIndex)!;\n\n /* -------------------------------------------------- */\n /* 1 – rect → rotated‑page space */\n /* -------------------------------------------------- */\n const rotatedRect = rotateRect(\n {\n width: pageRel.width,\n height: pageRel.height,\n },\n rect,\n rotation,\n );\n\n /* -------------------------------------------------- */\n /* 2 – numeric zoom so the rect fits */\n /* -------------------------------------------------- */\n const targetZoom = this.toZoom(\n Math.min(availableW / rotatedRect.size.width, availableH / rotatedRect.size.height),\n );\n\n /* -------------------------------------------------- */\n /* 3 – centre of that rect in *content* coordinates */\n /* -------------------------------------------------- */\n const pageAbsX = vItem.x + pageRel.x;\n const pageAbsY = vItem.y + pageRel.y;\n\n const cxContent = pageAbsX + rotatedRect.origin.x + rotatedRect.size.width / 2;\n const cyContent = pageAbsY + rotatedRect.origin.y + rotatedRect.size.height / 2;\n\n /* -------------------------------------------------- */\n /* 4 – centre in *viewport* coords before zoom */\n /* -------------------------------------------------- */\n const off = (avail: number, cw: number, z: number) =>\n cw * z < avail ? (avail - cw * z) / 2 : 0;\n\n const offXold = off(availableW, layout.totalContentSize.width, oldZ);\n const offYold = off(availableH, layout.totalContentSize.height, oldZ);\n\n const centerVX = vpGap + offXold + cxContent * oldZ - vp.scrollLeft;\n const centerVY = vpGap + offYold + cyContent * oldZ - vp.scrollTop;\n\n /* -------------------------------------------------- */\n /* 5 – hand off to the generic zoom handler */\n /* -------------------------------------------------- */\n this.handleRequest({\n level: targetZoom,\n center: { vx: centerVX, vy: centerVY },\n align: 'center',\n });\n }\n\n /** recalculates Automatic / Fit* when viewport or pages change */\n private recalcAuto(focus?: VerticalZoomFocus) {\n const s = this.state;\n if (\n s.zoomLevel === ZoomMode.Automatic ||\n s.zoomLevel === ZoomMode.FitPage ||\n s.zoomLevel === ZoomMode.FitWidth\n )\n this.handleRequest({ level: s.zoomLevel, focus });\n }\n\n override onStoreUpdated(_prevState: ZoomState, newState: ZoomState): void {\n this.state$.emit(newState);\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { ZoomAction } from './actions';\nimport { manifest, ZOOM_PLUGIN_ID } from './manifest';\nimport { zoomReducer, initialState } from './reducer';\nimport { ZoomPluginConfig, ZoomState } from './types';\nimport { ZoomPlugin } from './zoom-plugin';\n\nexport const ZoomPluginPackage: PluginPackage<ZoomPlugin, ZoomPluginConfig, ZoomState, ZoomAction> =\n {\n manifest,\n create: (registry, _engine, config) => new ZoomPlugin(ZOOM_PLUGIN_ID, registry, config),\n reducer: zoomReducer,\n initialState,\n };\n\nexport * from './zoom-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"names":["ZoomMode","VerticalZoomFocus","r"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { Action } from '@embedpdf/core';
2
+ import { ZoomLevel } from './types';
3
+ export declare const SET_ZOOM_LEVEL = "SET_ZOOM_LEVEL";
4
+ export declare const SET_INITIAL_ZOOM_LEVEL = "SET_INITIAL_ZOOM_LEVEL";
5
+ export interface SetZoomLevelAction extends Action {
6
+ type: typeof SET_ZOOM_LEVEL;
7
+ payload: {
8
+ zoomLevel: ZoomLevel;
9
+ currentZoomLevel: number;
10
+ };
11
+ }
12
+ export interface SetInitialZoomLevelAction extends Action {
13
+ type: typeof SET_INITIAL_ZOOM_LEVEL;
14
+ payload: {
15
+ zoomLevel: ZoomLevel;
16
+ };
17
+ }
18
+ export type ZoomAction = SetZoomLevelAction | SetInitialZoomLevelAction;
19
+ export declare function setZoomLevel(zoomLevel: ZoomLevel, currentZoomLevel: number): SetZoomLevelAction;
20
+ export declare function setInitialZoomLevel(zoomLevel: ZoomLevel): SetInitialZoomLevelAction;
@@ -0,0 +1,10 @@
1
+ import { PluginPackage } from '@embedpdf/core';
2
+ import { ZoomAction } from './actions';
3
+ import { initialState } from './reducer';
4
+ import { ZoomPluginConfig, ZoomState } from './types';
5
+ import { ZoomPlugin } from './zoom-plugin';
6
+ export declare const ZoomPluginPackage: PluginPackage<ZoomPlugin, ZoomPluginConfig, ZoomState, ZoomAction>;
7
+ export * from './zoom-plugin';
8
+ export * from './types';
9
+ export * from './manifest';
10
+ export { initialState };
@@ -0,0 +1,4 @@
1
+ import { PluginManifest } from '@embedpdf/core';
2
+ import { ZoomPluginConfig } from './types';
3
+ export declare const ZOOM_PLUGIN_ID = "zoom";
4
+ export declare const manifest: PluginManifest<ZoomPluginConfig>;
@@ -0,0 +1,5 @@
1
+ import { Reducer } from '@embedpdf/core';
2
+ import { ZoomAction } from './actions';
3
+ import { ZoomState } from './types';
4
+ export declare const initialState: ZoomState;
5
+ export declare const zoomReducer: Reducer<ZoomState, ZoomAction>;