@markup-canvas/core 1.1.6 → 1.2.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.
Files changed (163) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/lib/MarkupCanvas.d.ts +10 -12
  3. package/dist/lib/actions/config/getConfig.d.ts +2 -0
  4. package/dist/lib/actions/index.d.ts +3 -0
  5. package/dist/lib/actions/pan/centerContent.d.ts +2 -0
  6. package/dist/lib/actions/pan/index.d.ts +6 -0
  7. package/dist/lib/actions/pan/panDown.d.ts +2 -0
  8. package/dist/lib/actions/pan/panLeft.d.ts +2 -0
  9. package/dist/lib/actions/pan/panRight.d.ts +2 -0
  10. package/dist/lib/actions/pan/panUp.d.ts +2 -0
  11. package/dist/lib/actions/pan/scrollToPoint.d.ts +2 -0
  12. package/dist/lib/actions/transform/index.d.ts +2 -0
  13. package/dist/lib/actions/transform/resetTransform.d.ts +2 -0
  14. package/dist/lib/actions/transform/updateTransform.d.ts +2 -0
  15. package/dist/lib/actions/ui/grid/hideGrid.d.ts +2 -0
  16. package/dist/lib/actions/ui/grid/index.d.ts +4 -0
  17. package/dist/lib/actions/ui/grid/isGridVisible.d.ts +2 -0
  18. package/dist/lib/actions/ui/grid/showGrid.d.ts +2 -0
  19. package/dist/lib/actions/ui/grid/toggleGrid.d.ts +2 -0
  20. package/dist/lib/actions/ui/index.d.ts +4 -0
  21. package/dist/lib/actions/ui/rulers/areRulersVisible.d.ts +2 -0
  22. package/dist/lib/actions/ui/rulers/hideRulers.d.ts +2 -0
  23. package/dist/lib/actions/ui/rulers/index.d.ts +4 -0
  24. package/dist/lib/actions/ui/rulers/showRulers.d.ts +2 -0
  25. package/dist/lib/actions/ui/rulers/toggleRulers.d.ts +2 -0
  26. package/dist/lib/actions/ui/toggleTransition.d.ts +1 -0
  27. package/dist/lib/actions/ui/updateThemeMode.d.ts +2 -0
  28. package/dist/lib/actions/zoom/index.d.ts +6 -0
  29. package/dist/lib/actions/zoom/resetView.d.ts +2 -0
  30. package/dist/lib/actions/zoom/resetViewToCenter.d.ts +3 -0
  31. package/dist/lib/actions/zoom/setZoom.d.ts +3 -0
  32. package/dist/lib/actions/zoom/zoomIn.d.ts +3 -0
  33. package/dist/lib/actions/zoom/zoomOut.d.ts +3 -0
  34. package/dist/lib/actions/zoom/zoomToPoint.d.ts +2 -0
  35. package/dist/lib/canvas/createCanvas.d.ts +2 -2
  36. package/dist/lib/canvas/fitToScreen.d.ts +2 -0
  37. package/dist/lib/canvas/getCanvasBounds.d.ts +2 -2
  38. package/dist/lib/canvas/index.d.ts +1 -1
  39. package/dist/lib/events/emitTransformEvents.d.ts +3 -0
  40. package/dist/lib/events/keyboard/handleKeyDown.d.ts +3 -2
  41. package/dist/lib/events/keyboard/handleKeyUp.d.ts +3 -2
  42. package/dist/lib/events/keyboard/setupKeyboardEvents.d.ts +3 -2
  43. package/dist/lib/events/mouse/createMouseDragControls.d.ts +7 -0
  44. package/dist/lib/events/mouse/handleClickToZoom.d.ts +3 -2
  45. package/dist/lib/events/mouse/handleMouseDown.d.ts +3 -2
  46. package/dist/lib/events/mouse/handleMouseLeave.d.ts +3 -2
  47. package/dist/lib/events/mouse/handleMouseMove.d.ts +3 -2
  48. package/dist/lib/events/mouse/handleMouseUp.d.ts +3 -2
  49. package/dist/lib/events/mouse/setupMouseDrag.d.ts +4 -3
  50. package/dist/lib/events/mouse/setupMouseEvents.d.ts +4 -3
  51. package/dist/lib/events/touch/handleTouchMove.d.ts +3 -2
  52. package/dist/lib/events/touch/setupTouchEvents.d.ts +2 -2
  53. package/dist/lib/events/trackpad/createTrackpadPanHandler.d.ts +2 -2
  54. package/dist/lib/events/utils/getAdaptiveZoomSpeed.d.ts +2 -2
  55. package/dist/lib/events/utils/getViewportCenter.d.ts +5 -0
  56. package/dist/lib/events/utils/resetDragState.d.ts +3 -2
  57. package/dist/lib/events/utils/updateCursor.d.ts +3 -2
  58. package/dist/lib/events/wheel/handleWheel.d.ts +3 -2
  59. package/dist/lib/events/wheel/setupWheelEvents.d.ts +3 -2
  60. package/dist/lib/events/wheel/setupWheelHandler.d.ts +3 -2
  61. package/dist/lib/helpers/getVisibleArea.d.ts +7 -0
  62. package/dist/lib/helpers/index.d.ts +2 -0
  63. package/dist/lib/helpers/isPointVisible.d.ts +2 -0
  64. package/dist/lib/transform/applyZoomToCanvas.d.ts +2 -2
  65. package/dist/lib/window/bindCanvasToWindow.d.ts +3 -0
  66. package/dist/lib/window/broadcastEvent.d.ts +2 -0
  67. package/dist/lib/window/cleanupWindowBinding.d.ts +2 -0
  68. package/dist/lib/window/index.d.ts +3 -0
  69. package/dist/markup-canvas.cjs.js +715 -554
  70. package/dist/markup-canvas.esm.js +715 -554
  71. package/dist/markup-canvas.umd.js +711 -547
  72. package/dist/markup-canvas.umd.min.js +1 -1
  73. package/dist/types/canvas.d.ts +1 -47
  74. package/dist/types/config.d.ts +0 -3
  75. package/dist/types/events.d.ts +4 -1
  76. package/dist/types/index.d.ts +3 -2
  77. package/dist/types/window.d.ts +84 -0
  78. package/package.json +1 -1
  79. package/src/index.ts +1 -1
  80. package/src/lib/MarkupCanvas.ts +142 -308
  81. package/src/lib/actions/config/getConfig.ts +5 -0
  82. package/src/lib/actions/index.ts +6 -0
  83. package/src/lib/actions/pan/centerContent.ts +21 -0
  84. package/src/lib/actions/pan/index.ts +6 -0
  85. package/src/lib/actions/pan/panDown.ts +13 -0
  86. package/src/lib/actions/pan/panLeft.ts +13 -0
  87. package/src/lib/actions/pan/panRight.ts +13 -0
  88. package/src/lib/actions/pan/panUp.ts +13 -0
  89. package/src/lib/actions/pan/scrollToPoint.ts +27 -0
  90. package/src/lib/actions/transform/index.ts +2 -0
  91. package/src/lib/actions/transform/resetTransform.ts +11 -0
  92. package/src/lib/actions/transform/updateTransform.ts +9 -0
  93. package/src/lib/actions/ui/grid/hideGrid.ts +9 -0
  94. package/src/lib/actions/ui/grid/index.ts +4 -0
  95. package/src/lib/actions/ui/grid/isGridVisible.ts +8 -0
  96. package/src/lib/actions/ui/grid/showGrid.ts +9 -0
  97. package/src/lib/actions/ui/grid/toggleGrid.ts +9 -0
  98. package/src/lib/actions/ui/index.ts +4 -0
  99. package/src/lib/actions/ui/rulers/areRulersVisible.ts +8 -0
  100. package/src/lib/actions/ui/rulers/hideRulers.ts +9 -0
  101. package/src/lib/actions/ui/rulers/index.ts +4 -0
  102. package/src/lib/actions/ui/rulers/showRulers.ts +9 -0
  103. package/src/lib/actions/ui/rulers/toggleRulers.ts +14 -0
  104. package/src/lib/actions/ui/toggleTransition.ts +3 -0
  105. package/src/lib/actions/ui/updateThemeMode.ts +25 -0
  106. package/src/lib/actions/zoom/index.ts +6 -0
  107. package/src/lib/actions/zoom/resetView.ts +17 -0
  108. package/src/lib/actions/zoom/resetViewToCenter.ts +21 -0
  109. package/src/lib/actions/zoom/setZoom.ts +22 -0
  110. package/src/lib/actions/zoom/zoomIn.ts +21 -0
  111. package/src/lib/actions/zoom/zoomOut.ts +21 -0
  112. package/src/lib/actions/zoom/zoomToPoint.ts +18 -0
  113. package/src/lib/canvas/createCanvas.ts +6 -14
  114. package/src/lib/canvas/fitToScreen.ts +27 -0
  115. package/src/lib/canvas/getCanvasBounds.ts +3 -4
  116. package/src/lib/canvas/index.ts +1 -1
  117. package/src/lib/config/constants.ts +2 -6
  118. package/src/lib/config/presets/editor-preset.ts +4 -8
  119. package/src/lib/events/emitTransformEvents.ts +9 -0
  120. package/src/lib/events/keyboard/handleKeyDown.ts +3 -2
  121. package/src/lib/events/keyboard/handleKeyUp.ts +3 -2
  122. package/src/lib/events/keyboard/setupKeyboardEvents.ts +18 -38
  123. package/src/lib/events/mouse/createMouseDragControls.ts +21 -0
  124. package/src/lib/events/mouse/handleClickToZoom.ts +3 -2
  125. package/src/lib/events/mouse/handleMouseDown.ts +3 -2
  126. package/src/lib/events/mouse/handleMouseLeave.ts +3 -2
  127. package/src/lib/events/mouse/handleMouseMove.ts +3 -2
  128. package/src/lib/events/mouse/handleMouseUp.ts +3 -2
  129. package/src/lib/events/mouse/setupMouseDrag.ts +5 -4
  130. package/src/lib/events/mouse/setupMouseEvents.ts +5 -4
  131. package/src/lib/events/postMessage/setupPostMessageEvents.ts +10 -0
  132. package/src/lib/events/touch/handleTouchMove.ts +3 -2
  133. package/src/lib/events/touch/setupTouchEvents.ts +3 -2
  134. package/src/lib/events/trackpad/createTrackpadPanHandler.ts +3 -2
  135. package/src/lib/events/utils/getAdaptiveZoomSpeed.ts +2 -2
  136. package/src/lib/events/utils/getViewportCenter.ts +14 -0
  137. package/src/lib/events/utils/resetDragState.ts +3 -2
  138. package/src/lib/events/utils/updateCursor.ts +3 -2
  139. package/src/lib/events/wheel/handleWheel.ts +3 -2
  140. package/src/lib/events/wheel/setupWheelEvents.ts +3 -2
  141. package/src/lib/events/wheel/setupWheelHandler.ts +3 -2
  142. package/src/lib/helpers/getVisibleArea.ts +6 -0
  143. package/src/lib/helpers/index.ts +2 -0
  144. package/src/lib/helpers/isPointVisible.ts +7 -0
  145. package/src/lib/rulers/createRulers.ts +0 -1
  146. package/src/lib/transform/applyZoomToCanvas.ts +2 -2
  147. package/src/lib/window/bindCanvasToWindow.ts +128 -0
  148. package/src/lib/window/broadcastEvent.ts +38 -0
  149. package/src/lib/window/cleanupWindowBinding.ts +15 -0
  150. package/src/lib/window/index.ts +3 -0
  151. package/src/types/canvas.ts +1 -47
  152. package/src/types/config.ts +1 -7
  153. package/src/types/events.ts +7 -1
  154. package/src/types/index.ts +4 -2
  155. package/src/types/window.ts +77 -0
  156. package/dist/lib/canvas/config.d.ts +0 -2
  157. package/dist/lib/canvas/getCanvasMethods.d.ts +0 -12
  158. package/dist/lib/events/keyboard/setupKeyboardNavigation.d.ts +0 -2
  159. package/src/lib/canvas/config.ts +0 -29
  160. package/src/lib/canvas/getCanvasMethods.ts +0 -102
  161. package/src/lib/events/keyboard/setupKeyboardNavigation.ts +0 -115
  162. /package/dist/lib/canvas/{calcVisibleArea.d.ts → calculateVisibleArea.d.ts} +0 -0
  163. /package/src/lib/canvas/{calcVisibleArea.ts → calculateVisibleArea.ts} +0 -0
@@ -1,19 +1,23 @@
1
+ import { centerContent, panDown, panLeft, panRight, panUp, scrollToPoint } from "@/lib/actions/pan/index.js";
2
+ import { resetTransform, updateTransform } from "@/lib/actions/transform/index.js";
3
+ import { hideGrid, isGridVisible, showGrid, toggleGrid, toggleTransition, updateThemeMode } from "@/lib/actions/ui/index.js";
4
+ import { areRulersVisible, hideRulers, showRulers, toggleRulers } from "@/lib/actions/ui/rulers/index.js";
5
+ import { resetView, resetViewToCenter, setZoom, zoomIn, zoomOut, zoomToPoint } from "@/lib/actions/zoom/index.js";
6
+ import { fitToScreen } from "@/lib/canvas/fitToScreen.js";
7
+ import { getCanvasBounds } from "@/lib/canvas/getCanvasBounds.js";
1
8
  import { createCanvas } from "@/lib/canvas/index.js";
2
9
  import { createMarkupCanvasConfig } from "@/lib/config/createMarkupCanvasConfig.js";
3
10
  import { EventEmitter } from "@/lib/events/EventEmitter.js";
11
+ import { emitTransformEvents } from "@/lib/events/emitTransformEvents.js";
4
12
  import { setupKeyboardEvents, setupMouseEvents, setupPostMessageEvents, setupTouchEvents, setupWheelEvents } from "@/lib/events/index.js";
5
- import { getThemeValue, withClampedZoom, withFeatureEnabled } from "@/lib/helpers/index.js";
13
+ import { getVisibleArea, isPointVisible, withFeatureEnabled } from "@/lib/helpers/index.js";
14
+ import { canvasToContent } from "@/lib/matrix/canvasToContent.js";
15
+ import { createMatrix } from "@/lib/matrix/createMatrix.js";
6
16
  import { createRulers } from "@/lib/rulers/index.js";
7
- import { withTransition } from "@/lib/transition/withTransition.js";
8
- import type {
9
- BaseCanvas,
10
- Canvas,
11
- CanvasBounds,
12
- MarkupCanvasConfig,
13
- MarkupCanvasEvents,
14
- MouseDragControls,
15
- Transform,
16
- } from "@/types/index.js";
17
+ import { broadcastEvent } from "@/lib/window/broadcastEvent.js";
18
+ import { cleanupWindowBinding } from "@/lib/window/cleanupWindowBinding.js";
19
+ import { bindCanvasToWindow } from "@/lib/window/index.js";
20
+ import type { Canvas, CanvasBounds, MarkupCanvasConfig, MarkupCanvasEvents, MouseDragControls, Transform } from "@/types/index.js";
17
21
 
18
22
  declare global {
19
23
  interface Window {
@@ -21,15 +25,14 @@ declare global {
21
25
  }
22
26
  }
23
27
 
24
- export class MarkupCanvas implements Canvas {
25
- private baseCanvas: BaseCanvas;
26
- private cleanupFunctions: (() => void)[] = [];
28
+ export class MarkupCanvas {
29
+ private canvas: Canvas;
30
+ private cleanupCallbacks: (() => void)[] = [];
27
31
  private rulers: ReturnType<typeof createRulers> | null = null;
28
32
  private dragSetup: MouseDragControls | null = null;
29
33
  public config: Required<MarkupCanvasConfig>;
34
+ public event = new EventEmitter<MarkupCanvasEvents>();
30
35
  private _isReady = false;
31
- private listen = new EventEmitter<MarkupCanvasEvents>();
32
- private postMessageCleanup: (() => void) | null = null;
33
36
 
34
37
  constructor(container: HTMLElement, options: MarkupCanvasConfig = {}) {
35
38
  if (!container) {
@@ -43,127 +46,58 @@ export class MarkupCanvas implements Canvas {
43
46
  throw new Error("Failed to create canvas");
44
47
  }
45
48
 
46
- this.baseCanvas = canvas;
49
+ this.canvas = canvas;
47
50
 
48
- if (this.config.bindToWindow) {
49
- this.listen.setEmitInterceptor((event, data) => {
50
- this.broadcastEvent(event as string, data);
51
- });
52
- this.setupGlobalBinding();
51
+ // Always bind canvas to window
52
+ this.event.setEmitInterceptor((event, data) => {
53
+ broadcastEvent(event as string, data, this.config);
54
+ });
53
55
 
54
- // Set up postMessage listener
55
- if (this.config.enablePostMessageAPI) {
56
- this.postMessageCleanup = setupPostMessageEvents(this);
57
- }
56
+ bindCanvasToWindow(this, this.config);
57
+
58
+ // Set up postMessage listener
59
+ if (this.config.enablePostMessageAPI) {
60
+ const postMessageCleanup = setupPostMessageEvents(this);
61
+ this.cleanupCallbacks.push(postMessageCleanup);
58
62
  }
59
63
 
60
64
  this.setupEventHandlers();
61
65
  this._isReady = true;
62
66
 
63
67
  // Emit ready event
64
- this.listen.emit("ready", this);
65
- }
66
-
67
- private setupGlobalBinding(): void {
68
- if (typeof window === "undefined") {
69
- return;
70
- }
71
-
72
- const canvasName = this.config.name || "markupCanvas";
73
- const windowObj = window as unknown as Record<string, unknown>;
74
-
75
- // Bind instance to window
76
- windowObj[canvasName] = this;
77
-
78
- // Track all instances
79
- if (!windowObj.__markupCanvasInstances) {
80
- windowObj.__markupCanvasInstances = new Map();
81
- }
82
- (windowObj.__markupCanvasInstances as unknown as Map<string, MarkupCanvas>).set(canvasName, this);
83
- }
84
-
85
- private cleanupGlobalBinding(): void {
86
- if (typeof window === "undefined") {
87
- return;
88
- }
89
-
90
- const canvasName = this.config.name || "markupCanvas";
91
- const windowObj = window as unknown as Record<string, unknown>;
92
-
93
- delete windowObj[canvasName];
94
- if (windowObj.__markupCanvasInstances) {
95
- (windowObj.__markupCanvasInstances as unknown as Map<string, MarkupCanvas>).delete(canvasName);
96
- }
97
- }
98
-
99
- private broadcastEvent(event: string, data: unknown): void {
100
- if (typeof window === "undefined") {
101
- return;
102
- }
103
-
104
- // Receivers can get the instance from the window binding
105
- let broadcastData = data;
106
-
107
- if (event === "ready") {
108
- broadcastData = { ready: true };
109
- }
110
-
111
- window.postMessage(
112
- {
113
- source: "markup-canvas",
114
- event,
115
- data: broadcastData,
116
- timestamp: Date.now(),
117
- canvasName: this.config.name,
118
- },
119
- "*"
120
- );
121
-
122
- if (window.parent) {
123
- window.parent.postMessage(
124
- {
125
- source: "markup-canvas",
126
- event,
127
- data: broadcastData,
128
- timestamp: Date.now(),
129
- canvasName: this.config.name,
130
- },
131
- "*"
132
- );
133
- }
68
+ this.event.emit("ready", this);
134
69
  }
135
70
 
136
71
  private setupEventHandlers(): void {
137
72
  try {
138
- // Wheel zoom
73
+ // Wheel events
139
74
  withFeatureEnabled(this.config, "enableZoom", () => {
140
75
  const wheelCleanup = setupWheelEvents(this, this.config);
141
- this.cleanupFunctions.push(wheelCleanup);
76
+ this.cleanupCallbacks.push(wheelCleanup);
142
77
  });
143
78
 
144
- // Mouse events (drag and click-to-zoom)
145
- // Set up mouse events if either pan or click-to-zoom is enabled
79
+ // Mouse events
146
80
  if (this.config.enablePan || this.config.enableClickToZoom) {
147
81
  this.dragSetup = setupMouseEvents(this, this.config, true);
148
- this.cleanupFunctions.push(this.dragSetup.cleanup);
82
+ this.cleanupCallbacks.push(this.dragSetup.cleanup);
149
83
  }
150
84
 
151
- // Keyboard navigation
85
+ // Keyboard events
152
86
  withFeatureEnabled(this.config, "enableKeyboard", () => {
153
87
  const keyboardCleanup = setupKeyboardEvents(this, this.config);
154
- this.cleanupFunctions.push(keyboardCleanup);
88
+ this.cleanupCallbacks.push(keyboardCleanup);
155
89
  });
156
90
 
157
- // Touch events (if enabled)
91
+ // Touch events
158
92
  withFeatureEnabled(this.config, "enableTouch", () => {
159
93
  const touchCleanup = setupTouchEvents(this);
160
- this.cleanupFunctions.push(touchCleanup);
94
+ this.cleanupCallbacks.push(touchCleanup);
161
95
  });
162
96
 
163
97
  // Set up rulers and grid
164
98
  withFeatureEnabled(this.config, "enableRulers", () => {
165
- this.rulers = createRulers(this.baseCanvas, this.config);
166
- this.cleanupFunctions.push(() => {
99
+ this.rulers = createRulers(this, this.config);
100
+ this.cleanupCallbacks.push(() => {
167
101
  if (this.rulers) {
168
102
  this.rulers.destroy();
169
103
  }
@@ -176,24 +110,22 @@ export class MarkupCanvas implements Canvas {
176
110
  }
177
111
  }
178
112
 
179
- // Base canvas properties and methods
180
113
  get container(): HTMLElement {
181
- return this.baseCanvas.container;
114
+ return this.canvas.container;
182
115
  }
183
116
 
184
117
  get transformLayer(): HTMLElement {
185
- return this.baseCanvas.transformLayer;
118
+ return this.canvas.transformLayer;
186
119
  }
187
120
 
188
121
  get contentLayer(): HTMLElement {
189
- return this.baseCanvas.contentLayer;
122
+ return this.canvas.contentLayer;
190
123
  }
191
124
 
192
125
  get transform(): Transform {
193
- return this.baseCanvas.transform;
126
+ return this.canvas.transform;
194
127
  }
195
128
 
196
- // State management getters for React integration
197
129
  get isReady(): boolean {
198
130
  return this._isReady;
199
131
  }
@@ -203,142 +135,88 @@ export class MarkupCanvas implements Canvas {
203
135
  }
204
136
 
205
137
  get visibleBounds(): { x: number; y: number; width: number; height: number } {
206
- return this.getVisibleArea();
138
+ return getVisibleArea(this);
207
139
  }
208
140
 
209
141
  getBounds(): CanvasBounds {
210
- return this.baseCanvas.getBounds();
142
+ return getCanvasBounds(this.canvas, this.config);
211
143
  }
212
144
 
213
145
  updateTransform(newTransform: Partial<Transform>): boolean {
214
- const result = this.baseCanvas.updateTransform(newTransform);
146
+ const result = updateTransform(this.canvas, newTransform);
215
147
  if (result) {
216
- this.emitTransformEvents();
148
+ emitTransformEvents(this.event, this.canvas);
217
149
  }
218
150
  return result;
219
151
  }
220
152
 
221
- private emitTransformEvents(): void {
222
- const transform = this.baseCanvas.transform;
223
- this.listen.emit("transform", transform);
224
- this.listen.emit("zoom", transform.scale);
225
- this.listen.emit("pan", { x: transform.translateX, y: transform.translateY });
226
- }
227
-
228
153
  reset(): boolean {
229
- return this.baseCanvas.reset();
230
- }
231
-
232
- handleResize(): boolean {
233
- return this.baseCanvas.handleResize();
154
+ const result = resetTransform(this.canvas);
155
+ if (result) {
156
+ emitTransformEvents(this.event, this.canvas);
157
+ }
158
+ return result;
234
159
  }
235
160
 
236
161
  setZoom(zoomLevel: number): boolean {
237
- return withTransition(this.transformLayer, this.config, () => {
238
- return withClampedZoom(this.config, (clamp) => {
239
- const newScale = clamp(zoomLevel);
240
- const newTransform: Partial<Transform> = {
241
- scale: newScale,
242
- };
243
- return this.updateTransform(newTransform);
244
- });
245
- });
162
+ return setZoom(this, this.transformLayer, this.config, this.zoomToPoint.bind(this), zoomLevel);
246
163
  }
247
164
 
248
165
  canvasToContent(x: number, y: number): { x: number; y: number } {
249
- return this.baseCanvas.canvasToContent(x, y);
166
+ const matrix = createMatrix(this.canvas.transform.scale, this.canvas.transform.translateX, this.canvas.transform.translateY);
167
+ return canvasToContent(x, y, matrix);
250
168
  }
251
169
 
252
170
  zoomToPoint(x: number, y: number, targetScale: number): boolean {
253
- return withTransition(this.transformLayer, this.config, () => {
254
- const result = this.baseCanvas.zoomToPoint(x, y, targetScale);
255
- if (result) {
256
- this.emitTransformEvents();
257
- }
258
- return result;
259
- });
171
+ return zoomToPoint(this.canvas, this.transformLayer, this.config, x, y, targetScale);
260
172
  }
261
173
 
262
174
  resetView(): boolean {
263
- return withTransition(this.transformLayer, this.config, () => {
264
- const result = this.baseCanvas.resetView ? this.baseCanvas.resetView() : false;
265
- if (result) {
266
- this.emitTransformEvents();
267
- }
268
- return result;
269
- });
175
+ return resetView(this.canvas, this.transformLayer, this.config);
270
176
  }
271
177
 
272
- zoomToFitContent(): boolean {
273
- return withTransition(this.transformLayer, this.config, () => {
274
- const result = this.baseCanvas.zoomToFitContent();
275
- if (result) {
276
- this.emitTransformEvents();
277
- }
278
- return result;
279
- });
178
+ resetViewToCenter(): boolean {
179
+ return resetViewToCenter(this, this.transformLayer, this.config, this.zoomToPoint.bind(this));
280
180
  }
281
181
 
282
- // Pan methods
283
182
  panLeft(distance?: number): boolean {
284
- const panDistance = distance ?? this.config.keyboardPanStep;
285
- const newTransform: Partial<Transform> = {
286
- translateX: this.baseCanvas.transform.translateX + panDistance,
287
- };
288
- return this.updateTransform(newTransform);
183
+ return (
184
+ panLeft(this.canvas, this.config, this.updateTransform.bind(this)) ||
185
+ (distance ? panLeft(this.canvas, { ...this.config, keyboardPanStep: distance }, this.updateTransform.bind(this)) : false)
186
+ );
289
187
  }
290
188
 
291
189
  panRight(distance?: number): boolean {
292
- const panDistance = distance ?? this.config.keyboardPanStep;
293
- const newTransform: Partial<Transform> = {
294
- translateX: this.baseCanvas.transform.translateX - panDistance,
295
- };
296
- return this.updateTransform(newTransform);
190
+ return (
191
+ panRight(this.canvas, this.config, this.updateTransform.bind(this)) ||
192
+ (distance ? panRight(this.canvas, { ...this.config, keyboardPanStep: distance }, this.updateTransform.bind(this)) : false)
193
+ );
297
194
  }
298
195
 
299
196
  panUp(distance?: number): boolean {
300
- const panDistance = distance ?? this.config.keyboardPanStep;
301
- const newTransform: Partial<Transform> = {
302
- translateY: this.baseCanvas.transform.translateY + panDistance,
303
- };
304
- return this.updateTransform(newTransform);
197
+ return (
198
+ panUp(this.canvas, this.config, this.updateTransform.bind(this)) ||
199
+ (distance ? panUp(this.canvas, { ...this.config, keyboardPanStep: distance }, this.updateTransform.bind(this)) : false)
200
+ );
305
201
  }
306
202
 
307
203
  panDown(distance?: number): boolean {
308
- const panDistance = distance ?? this.config.keyboardPanStep;
309
- const newTransform: Partial<Transform> = {
310
- translateY: this.baseCanvas.transform.translateY - panDistance,
311
- };
312
- return this.updateTransform(newTransform);
313
- }
314
-
315
- // Zoom methods
316
- zoomIn(factor: number = 0.1): boolean {
317
- return withTransition(this.transformLayer, this.config, () => {
318
- return withClampedZoom(this.config, (clamp) => {
319
- const newScale = clamp(this.baseCanvas.transform.scale * (1 + factor));
320
- const newTransform: Partial<Transform> = {
321
- scale: newScale,
322
- };
323
- return this.updateTransform(newTransform);
324
- });
325
- });
204
+ return (
205
+ panDown(this.canvas, this.config, this.updateTransform.bind(this)) ||
206
+ (distance ? panDown(this.canvas, { ...this.config, keyboardPanStep: distance }, this.updateTransform.bind(this)) : false)
207
+ );
326
208
  }
327
209
 
328
- zoomOut(factor: number = 0.1): boolean {
329
- return withTransition(this.transformLayer, this.config, () => {
330
- return withClampedZoom(this.config, (clamp) => {
331
- const newScale = clamp(this.baseCanvas.transform.scale * (1 - factor));
332
- const newTransform: Partial<Transform> = {
333
- scale: newScale,
334
- };
335
- return this.updateTransform(newTransform);
336
- });
337
- });
210
+ zoomIn(factor: number = 0.5): boolean {
211
+ return zoomIn(this, this.transformLayer, this.config, this.zoomToPoint.bind(this), factor);
212
+ }
213
+
214
+ zoomOut(factor: number = 0.5): boolean {
215
+ return zoomOut(this, this.transformLayer, this.config, this.zoomToPoint.bind(this), factor);
338
216
  }
339
217
 
340
218
  resetZoom(): boolean {
341
- return this.resetView();
219
+ return this.resetViewToCenter();
342
220
  }
343
221
 
344
222
  // Mouse drag control methods
@@ -354,124 +232,80 @@ export class MarkupCanvas implements Canvas {
354
232
  return this.dragSetup?.isEnabled() ?? false;
355
233
  }
356
234
 
357
- // Grid control methods
358
235
  toggleGrid(): boolean {
359
- if (this.rulers?.toggleGrid) {
360
- this.rulers.toggleGrid();
361
- return true;
236
+ const result = toggleGrid(this.rulers);
237
+ if (result) {
238
+ this.event.emit("gridVisibility", this.isGridVisible());
362
239
  }
363
- return false;
240
+ return result;
364
241
  }
365
242
 
366
243
  showGrid(): boolean {
367
- if (this.rulers?.gridOverlay) {
368
- this.rulers.gridOverlay.style.display = "block";
369
- return true;
244
+ const result = showGrid(this.rulers);
245
+ if (result) {
246
+ this.event.emit("gridVisibility", true);
370
247
  }
371
- return false;
248
+ return result;
372
249
  }
373
250
 
374
251
  hideGrid(): boolean {
375
- if (this.rulers?.gridOverlay) {
376
- this.rulers.gridOverlay.style.display = "none";
377
- return true;
252
+ const result = hideGrid(this.rulers);
253
+ if (result) {
254
+ this.event.emit("gridVisibility", false);
378
255
  }
379
- return false;
256
+ return result;
380
257
  }
381
258
 
382
259
  isGridVisible(): boolean {
383
- if (this.rulers?.gridOverlay) {
384
- return this.rulers.gridOverlay.style.display !== "none";
385
- }
386
- return false;
260
+ return isGridVisible(this.rulers);
387
261
  }
388
262
 
389
- // Ruler control methods
390
263
  toggleRulers(): boolean {
391
- if (this.rulers) {
392
- const areVisible = this.areRulersVisible();
393
- if (areVisible) {
394
- this.rulers.hide();
395
- } else {
396
- this.rulers.show();
397
- }
398
- return true;
264
+ const result = toggleRulers(this.rulers, () => this.areRulersVisible());
265
+ if (result) {
266
+ this.event.emit("rulersVisibility", this.areRulersVisible());
399
267
  }
400
- return false;
268
+ return result;
401
269
  }
402
270
 
403
271
  showRulers(): boolean {
404
- if (this.rulers) {
405
- this.rulers.show();
406
- return true;
272
+ const result = showRulers(this.rulers);
273
+ if (result) {
274
+ this.event.emit("rulersVisibility", true);
407
275
  }
408
- return false;
276
+ return result;
409
277
  }
410
278
 
411
279
  hideRulers(): boolean {
412
- if (this.rulers) {
413
- this.rulers.hide();
414
- return true;
280
+ const result = hideRulers(this.rulers);
281
+ if (result) {
282
+ this.event.emit("rulersVisibility", false);
415
283
  }
416
- return false;
284
+ return result;
417
285
  }
418
286
 
419
287
  areRulersVisible(): boolean {
420
- if (this.rulers?.horizontalRuler) {
421
- return this.rulers.horizontalRuler.style.display !== "none";
422
- }
423
- return false;
288
+ return areRulersVisible(this.rulers);
424
289
  }
425
290
 
426
- // Utility methods
427
291
  centerContent(): boolean {
428
- return withTransition(this.transformLayer, this.config, () => {
429
- const bounds = this.baseCanvas.getBounds();
430
- const centerX = (bounds.width - bounds.contentWidth * this.baseCanvas.transform.scale) / 2;
431
- const centerY = (bounds.height - bounds.contentHeight * this.baseCanvas.transform.scale) / 2;
432
-
433
- return this.updateTransform({
434
- translateX: centerX,
435
- translateY: centerY,
436
- });
437
- });
292
+ return centerContent(this.canvas, this.config, this.updateTransform.bind(this), this.transformLayer);
438
293
  }
439
294
 
440
295
  fitToScreen(): boolean {
441
- return withTransition(this.transformLayer, this.config, () => {
442
- const result = this.baseCanvas.zoomToFitContent();
443
- if (result) {
444
- this.emitTransformEvents();
445
- }
446
- return result;
447
- });
296
+ return fitToScreen(this.canvas, this.transformLayer, this.config);
448
297
  }
449
298
 
450
299
  getVisibleArea(): { x: number; y: number; width: number; height: number } {
451
- const bounds = this.baseCanvas.getBounds();
452
- return bounds.visibleArea;
300
+ return getVisibleArea(this);
453
301
  }
454
302
 
455
303
  isPointVisible(x: number, y: number): boolean {
456
- const visibleArea = this.getVisibleArea();
457
- return x >= visibleArea.x && x <= visibleArea.x + visibleArea.width && y >= visibleArea.y && y <= visibleArea.y + visibleArea.height;
304
+ return isPointVisible(this, x, y);
458
305
  }
459
306
 
460
307
  scrollToPoint(x: number, y: number): boolean {
461
- return withTransition(this.transformLayer, this.config, () => {
462
- const bounds = this.baseCanvas.getBounds();
463
- const centerX = bounds.width / 2;
464
- const centerY = bounds.height / 2;
465
-
466
- // Calculate new translation to center the point
467
- const newTranslateX = centerX - x * this.baseCanvas.transform.scale;
468
- const newTranslateY = centerY - y * this.baseCanvas.transform.scale;
469
-
470
- return this.updateTransform({
471
- translateX: newTranslateX,
472
- translateY: newTranslateY,
473
- });
474
- });
308
+ return scrollToPoint(this.canvas, this.config, x, y, this.updateTransform.bind(this), this.transformLayer);
475
309
  }
476
310
 
477
311
  // Configuration access
@@ -485,40 +319,40 @@ export class MarkupCanvas implements Canvas {
485
319
 
486
320
  // Theme management
487
321
  updateThemeMode(mode: "light" | "dark"): void {
488
- const newConfig = {
489
- ...this.config,
490
- themeMode: mode,
491
- };
492
- this.config = createMarkupCanvasConfig(newConfig);
493
-
494
- // Update canvas background color
495
- const backgroundColor = getThemeValue(this.config, "canvasBackgroundColor");
496
- this.baseCanvas.container.style.backgroundColor = backgroundColor;
497
-
498
- // Update rulers if they exist
499
- if (this.rulers) {
500
- this.rulers.updateTheme(this.config);
501
- }
322
+ this.config = createMarkupCanvasConfig({ ...this.config, themeMode: mode });
323
+ updateThemeMode(this.canvas.container, this.config, this.rulers, mode);
324
+ }
325
+
326
+ toggleThemeMode(): "light" | "dark" {
327
+ const currentMode = this.config.themeMode;
328
+ const newMode = currentMode === "light" ? "dark" : "light";
329
+ this.updateThemeMode(newMode);
330
+ return newMode;
331
+ }
332
+
333
+ // Transition management
334
+ updateTransition(enabled: boolean): void {
335
+ this.config = createMarkupCanvasConfig({ ...this.config, enableTransition: enabled });
336
+ }
337
+
338
+ toggleTransitionMode(): boolean {
339
+ const newEnableTransition = toggleTransition(this.config.enableTransition);
340
+ this.updateTransition(newEnableTransition);
341
+ return newEnableTransition;
502
342
  }
503
343
 
504
344
  // Cleanup method
505
345
  cleanup(): void {
506
- this.cleanupGlobalBinding();
507
-
508
- // Cleanup postMessage listener
509
- if (this.postMessageCleanup) {
510
- this.postMessageCleanup();
511
- this.postMessageCleanup = null;
512
- }
346
+ cleanupWindowBinding(this.config);
513
347
 
514
- this.cleanupFunctions.forEach((cleanup) => {
348
+ this.cleanupCallbacks.forEach((cleanup) => {
515
349
  try {
516
350
  cleanup();
517
351
  } catch (cleanupError) {
518
352
  console.warn("Error during cleanup:", cleanupError);
519
353
  }
520
354
  });
521
- this.cleanupFunctions = [];
355
+ this.cleanupCallbacks = [];
522
356
 
523
357
  // Remove all event listeners
524
358
  this.removeAllListeners();
@@ -526,19 +360,19 @@ export class MarkupCanvas implements Canvas {
526
360
 
527
361
  // Event emitter delegation methods
528
362
  on<K extends keyof MarkupCanvasEvents>(event: K, handler: (data: MarkupCanvasEvents[K]) => void): void {
529
- this.listen.on(event, handler);
363
+ this.event.on(event, handler);
530
364
  }
531
365
 
532
366
  off<K extends keyof MarkupCanvasEvents>(event: K, handler: (data: MarkupCanvasEvents[K]) => void): void {
533
- this.listen.off(event, handler);
367
+ this.event.off(event, handler);
534
368
  }
535
369
 
536
370
  emit<K extends keyof MarkupCanvasEvents>(event: K, data: MarkupCanvasEvents[K]): void {
537
- this.listen.emit(event, data);
371
+ this.event.emit(event, data);
538
372
  }
539
373
 
540
374
  removeAllListeners(): void {
541
- this.listen.removeAllListeners();
375
+ this.event.removeAllListeners();
542
376
  }
543
377
 
544
378
  destroy(): void {
@@ -0,0 +1,5 @@
1
+ import type { MarkupCanvasConfig } from "@/types/index.js";
2
+
3
+ export function getConfig(config: Required<MarkupCanvasConfig>): Required<MarkupCanvasConfig> {
4
+ return { ...config };
5
+ }
@@ -0,0 +1,6 @@
1
+ // Pan actions
2
+ export * from "./pan/index.js";
3
+ // UI actions
4
+ export * from "./ui/index.js";
5
+ // Zoom actions
6
+ export * from "./zoom/index.js";