@markup-canvas/core 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/MarkupCanvas.d.ts +3 -0
- package/dist/lib/events/EventEmitter.d.ts +2 -0
- package/dist/lib/rulers/updateRulerTheme.d.ts +0 -5
- package/dist/markup-canvas.cjs.js +110 -72
- package/dist/markup-canvas.esm.js +110 -72
- package/dist/markup-canvas.umd.js +100 -65
- package/dist/markup-canvas.umd.min.js +1 -1
- package/dist/types/config.d.ts +3 -1
- package/package.json +1 -1
- package/src/lib/MarkupCanvas.ts +65 -0
- package/src/lib/config/constants.ts +7 -3
- package/src/lib/config/presets/editor-preset.ts +11 -7
- package/src/lib/events/EventEmitter.ts +7 -0
- package/src/lib/events/keyboard/setupKeyboardEvents.ts +2 -2
- package/src/lib/events/keyboard/setupKeyboardNavigation.ts +2 -2
- package/src/lib/rulers/createCornerBox.ts +4 -8
- package/src/lib/rulers/createGridOverlay.ts +2 -4
- package/src/lib/rulers/createHorizontalRuler.ts +4 -8
- package/src/lib/rulers/createRulers.ts +2 -3
- package/src/lib/rulers/createVerticalRuler.ts +4 -8
- package/src/lib/rulers/ticks/createHorizontalTick.ts +3 -5
- package/src/lib/rulers/ticks/createVerticalTick.ts +3 -5
- package/src/lib/rulers/updateRulerTheme.ts +17 -25
- package/src/types/config.ts +5 -1
|
@@ -13,6 +13,9 @@ export declare class MarkupCanvas implements Canvas {
|
|
|
13
13
|
private _isReady;
|
|
14
14
|
private listen;
|
|
15
15
|
constructor(container: HTMLElement, options?: MarkupCanvasConfig);
|
|
16
|
+
private setupGlobalBinding;
|
|
17
|
+
private cleanupGlobalBinding;
|
|
18
|
+
private broadcastEvent;
|
|
16
19
|
private setupEventHandlers;
|
|
17
20
|
get container(): HTMLElement;
|
|
18
21
|
get transformLayer(): HTMLElement;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare class EventEmitter<Events extends Record<string, unknown>> {
|
|
2
2
|
private listeners;
|
|
3
|
+
private emitInterceptor?;
|
|
4
|
+
setEmitInterceptor(interceptor: (event: keyof Events, data: unknown) => void): void;
|
|
3
5
|
on<K extends keyof Events>(event: K, handler: (data: Events[K]) => void): void;
|
|
4
6
|
off<K extends keyof Events>(event: K, handler: (data: Events[K]) => void): void;
|
|
5
7
|
emit<K extends keyof Events>(event: K, data: Events[K]): void;
|
|
@@ -5,9 +5,4 @@ export interface RulerThemeUpdater {
|
|
|
5
5
|
cornerBox?: HTMLElement;
|
|
6
6
|
gridOverlay?: HTMLElement;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Updates all ruler elements with new theme colors
|
|
10
|
-
* @param elements - The ruler elements to update
|
|
11
|
-
* @param config - The canvas config containing theme and color settings
|
|
12
|
-
*/
|
|
13
8
|
export declare function updateRulerTheme(elements: RulerThemeUpdater, config: Required<MarkupCanvasConfig>): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Markup Canvas
|
|
3
3
|
* High-performance markup canvas with zoom and pan capabilities
|
|
4
|
-
* @version 1.0.
|
|
4
|
+
* @version 1.0.9
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -17,7 +17,7 @@ const EDITOR_PRESET = {
|
|
|
17
17
|
enablePan: true,
|
|
18
18
|
enableTouch: true,
|
|
19
19
|
enableKeyboard: false,
|
|
20
|
-
|
|
20
|
+
bindKeyboardEventsTo: "canvas",
|
|
21
21
|
// Zoom behavior
|
|
22
22
|
zoomSpeed: 1.5,
|
|
23
23
|
minZoom: 0.05,
|
|
@@ -47,22 +47,25 @@ const EDITOR_PRESET = {
|
|
|
47
47
|
rulerUnits: "px",
|
|
48
48
|
rulerSize: 20,
|
|
49
49
|
// Canvas styling
|
|
50
|
-
canvasBackgroundColor: "
|
|
51
|
-
canvasBackgroundColorDark: "
|
|
50
|
+
canvasBackgroundColor: "transparent",
|
|
51
|
+
canvasBackgroundColorDark: "transparent",
|
|
52
52
|
// Ruler styling
|
|
53
|
-
rulerBackgroundColor: "oklch(100% 0 0 / 0.
|
|
54
|
-
rulerBorderColor: "oklch(
|
|
53
|
+
rulerBackgroundColor: "oklch(100% 0 0 / 0.96)",
|
|
54
|
+
rulerBorderColor: "oklch(96.7% 0.001 286.375)",
|
|
55
55
|
rulerTextColor: "oklch(70.5% 0.015 286.067)",
|
|
56
|
-
rulerTickColor: "oklch(
|
|
56
|
+
rulerTickColor: "oklch(92% 0.004 286.32)",
|
|
57
57
|
gridColor: "rgba(232, 86, 193, 0.5)",
|
|
58
58
|
// Ruler styling (dark theme)
|
|
59
59
|
rulerBackgroundColorDark: "oklch(27.4% 0.006 286.033)",
|
|
60
|
-
rulerBorderColorDark: "oklch(
|
|
60
|
+
rulerBorderColorDark: "oklch(44.2% 0.017 285.786)",
|
|
61
61
|
rulerTextColorDark: "oklch(55.2% 0.016 285.938)",
|
|
62
62
|
rulerTickColorDark: "oklch(55.2% 0.016 285.938)",
|
|
63
63
|
gridColorDark: "rgba(232, 86, 193, 0.5)",
|
|
64
64
|
// Theme
|
|
65
65
|
themeMode: "light",
|
|
66
|
+
// Global Binding & Instance Access
|
|
67
|
+
bindToWindow: false,
|
|
68
|
+
name: "markupCanvas",
|
|
66
69
|
// Callbacks
|
|
67
70
|
onTransformUpdate: () => { },
|
|
68
71
|
};
|
|
@@ -315,7 +318,7 @@ const DEFAULT_CONFIG = {
|
|
|
315
318
|
enablePan: true,
|
|
316
319
|
enableTouch: true,
|
|
317
320
|
enableKeyboard: true,
|
|
318
|
-
|
|
321
|
+
bindKeyboardEventsTo: "canvas",
|
|
319
322
|
// Zoom behavior
|
|
320
323
|
zoomSpeed: 1.5,
|
|
321
324
|
minZoom: 0.05,
|
|
@@ -349,7 +352,7 @@ const DEFAULT_CONFIG = {
|
|
|
349
352
|
canvasBackgroundColorDark: "rgba(40, 40, 40, 1)",
|
|
350
353
|
// Ruler styling (light theme)
|
|
351
354
|
rulerBackgroundColor: "rgba(255, 255, 255, 0.95)",
|
|
352
|
-
rulerBorderColor: "rgba(
|
|
355
|
+
rulerBorderColor: "rgba(240, 240, 240, 1)",
|
|
353
356
|
rulerTextColor: "rgba(102, 102, 102, 1)",
|
|
354
357
|
rulerTickColor: "rgba(204, 204, 204, 1)",
|
|
355
358
|
gridColor: "rgba(232, 86, 193, 0.5)",
|
|
@@ -357,10 +360,13 @@ const DEFAULT_CONFIG = {
|
|
|
357
360
|
rulerBackgroundColorDark: "rgba(30, 30, 30, 0.95)",
|
|
358
361
|
rulerBorderColorDark: "rgba(68, 68, 68, 1)",
|
|
359
362
|
rulerTextColorDark: "rgba(170, 170, 170, 1)",
|
|
360
|
-
rulerTickColorDark: "rgba(
|
|
363
|
+
rulerTickColorDark: "rgba(104, 104, 104, 1)",
|
|
361
364
|
gridColorDark: "rgba(232, 86, 193, 0.5)",
|
|
362
365
|
// Theme
|
|
363
366
|
themeMode: "light",
|
|
367
|
+
// Global Binding & Instance Access
|
|
368
|
+
bindToWindow: false,
|
|
369
|
+
name: "markupCanvas",
|
|
364
370
|
// Callbacks
|
|
365
371
|
onTransformUpdate: () => { },
|
|
366
372
|
};
|
|
@@ -708,6 +714,9 @@ class EventEmitter {
|
|
|
708
714
|
constructor() {
|
|
709
715
|
this.listeners = new Map();
|
|
710
716
|
}
|
|
717
|
+
setEmitInterceptor(interceptor) {
|
|
718
|
+
this.emitInterceptor = interceptor;
|
|
719
|
+
}
|
|
711
720
|
on(event, handler) {
|
|
712
721
|
if (!this.listeners.has(event)) {
|
|
713
722
|
this.listeners.set(event, new Set());
|
|
@@ -721,6 +730,7 @@ class EventEmitter {
|
|
|
721
730
|
}
|
|
722
731
|
}
|
|
723
732
|
emit(event, data) {
|
|
733
|
+
this.emitInterceptor?.(event, data);
|
|
724
734
|
const handlers = this.listeners.get(event);
|
|
725
735
|
if (handlers) {
|
|
726
736
|
handlers.forEach((handler) => {
|
|
@@ -779,7 +789,7 @@ function setupKeyboardEvents(canvas, config) {
|
|
|
779
789
|
function handleKeyDown(event) {
|
|
780
790
|
if (!(event instanceof KeyboardEvent))
|
|
781
791
|
return;
|
|
782
|
-
if (config.
|
|
792
|
+
if (config.bindKeyboardEventsTo === "canvas" && document.activeElement !== canvas.container)
|
|
783
793
|
return;
|
|
784
794
|
const isFastPan = event.shiftKey;
|
|
785
795
|
const panDistance = config.keyboardPanStep * (isFastPan ? config.keyboardFastMultiplier : 1);
|
|
@@ -852,7 +862,7 @@ function setupKeyboardEvents(canvas, config) {
|
|
|
852
862
|
}
|
|
853
863
|
}
|
|
854
864
|
}
|
|
855
|
-
const keyboardTarget = config.
|
|
865
|
+
const keyboardTarget = config.bindKeyboardEventsTo === "canvas" ? canvas.container : document;
|
|
856
866
|
keyboardTarget.addEventListener("keydown", handleKeyDown);
|
|
857
867
|
canvas.container.addEventListener("mousemove", handleMouseMove);
|
|
858
868
|
return () => {
|
|
@@ -1380,25 +1390,22 @@ const GRID_SETTINGS = {
|
|
|
1380
1390
|
function createCornerBox(config) {
|
|
1381
1391
|
const corner = document.createElement("div");
|
|
1382
1392
|
corner.className = "canvas-ruler corner-box";
|
|
1383
|
-
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1384
|
-
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1385
|
-
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1386
1393
|
corner.style.cssText = `
|
|
1387
1394
|
position: absolute;
|
|
1388
1395
|
top: 0;
|
|
1389
1396
|
left: 0;
|
|
1390
1397
|
width: ${config.rulerSize}px;
|
|
1391
1398
|
height: ${config.rulerSize}px;
|
|
1392
|
-
background:
|
|
1393
|
-
border-right: 1px solid
|
|
1394
|
-
border-bottom: 1px solid
|
|
1399
|
+
background: var(--ruler-background-color);
|
|
1400
|
+
border-right: 1px solid var(--ruler-border-color);
|
|
1401
|
+
border-bottom: 1px solid var(--ruler-border-color);
|
|
1395
1402
|
z-index: ${RULER_Z_INDEX.CORNER};
|
|
1396
1403
|
display: flex;
|
|
1397
1404
|
align-items: center;
|
|
1398
1405
|
justify-content: center;
|
|
1399
1406
|
font-family: ${config.rulerFontFamily};
|
|
1400
1407
|
font-size: ${config.rulerFontSize - 2}px;
|
|
1401
|
-
color:
|
|
1408
|
+
color: var(--ruler-text-color);
|
|
1402
1409
|
pointer-events: none;
|
|
1403
1410
|
`;
|
|
1404
1411
|
corner.textContent = config.rulerUnits;
|
|
@@ -1408,7 +1415,6 @@ function createCornerBox(config) {
|
|
|
1408
1415
|
function createGridOverlay(config) {
|
|
1409
1416
|
const grid = document.createElement("div");
|
|
1410
1417
|
grid.className = "canvas-ruler grid-overlay";
|
|
1411
|
-
const gridColor = getThemeValue(config, "gridColor");
|
|
1412
1418
|
grid.style.cssText = `
|
|
1413
1419
|
position: absolute;
|
|
1414
1420
|
top: ${config.rulerSize}px;
|
|
@@ -1418,8 +1424,8 @@ function createGridOverlay(config) {
|
|
|
1418
1424
|
pointer-events: none;
|
|
1419
1425
|
z-index: ${RULER_Z_INDEX.GRID};
|
|
1420
1426
|
background-image:
|
|
1421
|
-
linear-gradient(
|
|
1422
|
-
linear-gradient(90deg,
|
|
1427
|
+
linear-gradient(var(--grid-color) 1px, transparent 1px),
|
|
1428
|
+
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
|
|
1423
1429
|
background-size: 100px 100px;
|
|
1424
1430
|
opacity: 0.5;
|
|
1425
1431
|
`;
|
|
@@ -1429,23 +1435,20 @@ function createGridOverlay(config) {
|
|
|
1429
1435
|
function createHorizontalRuler(config) {
|
|
1430
1436
|
const ruler = document.createElement("div");
|
|
1431
1437
|
ruler.className = "canvas-ruler horizontal-ruler";
|
|
1432
|
-
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1433
|
-
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1434
|
-
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1435
1438
|
ruler.style.cssText = `
|
|
1436
1439
|
position: absolute;
|
|
1437
1440
|
top: 0;
|
|
1438
1441
|
left: ${config.rulerSize}px;
|
|
1439
1442
|
right: 0;
|
|
1440
1443
|
height: ${config.rulerSize}px;
|
|
1441
|
-
background:
|
|
1442
|
-
border-bottom: 1px solid
|
|
1443
|
-
border-right: 1px solid
|
|
1444
|
+
background: var(--ruler-background-color);
|
|
1445
|
+
border-bottom: 1px solid var(--ruler-border-color);
|
|
1446
|
+
border-right: 1px solid var(--ruler-border-color);
|
|
1444
1447
|
z-index: ${RULER_Z_INDEX.RULERS};
|
|
1445
1448
|
pointer-events: none;
|
|
1446
1449
|
font-family: ${config.rulerFontFamily};
|
|
1447
1450
|
font-size: ${config.rulerFontSize}px;
|
|
1448
|
-
color:
|
|
1451
|
+
color: var(--ruler-text-color);
|
|
1449
1452
|
overflow: hidden;
|
|
1450
1453
|
`;
|
|
1451
1454
|
return ruler;
|
|
@@ -1454,23 +1457,20 @@ function createHorizontalRuler(config) {
|
|
|
1454
1457
|
function createVerticalRuler(config) {
|
|
1455
1458
|
const ruler = document.createElement("div");
|
|
1456
1459
|
ruler.className = "canvas-ruler vertical-ruler";
|
|
1457
|
-
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1458
|
-
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1459
|
-
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1460
1460
|
ruler.style.cssText = `
|
|
1461
1461
|
position: absolute;
|
|
1462
1462
|
top: ${config.rulerSize}px;
|
|
1463
1463
|
left: 0;
|
|
1464
1464
|
bottom: 0;
|
|
1465
1465
|
width: ${config.rulerSize}px;
|
|
1466
|
-
background:
|
|
1467
|
-
border-right: 1px solid
|
|
1468
|
-
border-bottom: 1px solid
|
|
1466
|
+
background: var(--ruler-background-color);
|
|
1467
|
+
border-right: 1px solid var(--ruler-border-color);
|
|
1468
|
+
border-bottom: 1px solid var(--ruler-border-color);
|
|
1469
1469
|
z-index: ${RULER_Z_INDEX.RULERS};
|
|
1470
1470
|
pointer-events: none;
|
|
1471
1471
|
font-family: ${config.rulerFontFamily};
|
|
1472
1472
|
font-size: ${config.rulerFontSize}px;
|
|
1473
|
-
color:
|
|
1473
|
+
color: var(--ruler-text-color);
|
|
1474
1474
|
overflow: hidden;
|
|
1475
1475
|
`;
|
|
1476
1476
|
return ruler;
|
|
@@ -1542,27 +1542,26 @@ function calculateTickSpacing(contentSize, canvasSize) {
|
|
|
1542
1542
|
|
|
1543
1543
|
function createHorizontalTick(container, position, pixelPos, _tickSpacing, config) {
|
|
1544
1544
|
const tick = document.createElement("div");
|
|
1545
|
-
|
|
1545
|
+
tick.className = "tick";
|
|
1546
1546
|
tick.style.cssText = `
|
|
1547
1547
|
position: absolute;
|
|
1548
1548
|
left: ${pixelPos}px;
|
|
1549
1549
|
bottom: 0;
|
|
1550
1550
|
width: 1px;
|
|
1551
1551
|
height: ${TICK_SETTINGS.TICK_HEIGHT}px;
|
|
1552
|
-
background:
|
|
1552
|
+
background: var(--ruler-tick-color);
|
|
1553
1553
|
`;
|
|
1554
1554
|
container.appendChild(tick);
|
|
1555
1555
|
const shouldShowLabel = position % TICK_SETTINGS.TICK_LABEL_INTERVAL === 0;
|
|
1556
1556
|
if (shouldShowLabel) {
|
|
1557
1557
|
const label = document.createElement("div");
|
|
1558
|
-
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1559
1558
|
label.style.cssText = `
|
|
1560
1559
|
position: absolute;
|
|
1561
1560
|
left: ${pixelPos}px;
|
|
1562
1561
|
bottom: ${TICK_SETTINGS.TICK_HEIGHT + 2}px;
|
|
1563
1562
|
font-size: ${config.rulerFontSize}px;
|
|
1564
1563
|
line-height: 1;
|
|
1565
|
-
color:
|
|
1564
|
+
color: var(--ruler-text-color);
|
|
1566
1565
|
white-space: nowrap;
|
|
1567
1566
|
pointer-events: none;
|
|
1568
1567
|
`;
|
|
@@ -1590,27 +1589,26 @@ function updateHorizontalRuler(ruler, contentLeft, contentRight, canvasWidth, sc
|
|
|
1590
1589
|
|
|
1591
1590
|
function createVerticalTick(container, position, pixelPos, _tickSpacing, config) {
|
|
1592
1591
|
const tick = document.createElement("div");
|
|
1593
|
-
|
|
1592
|
+
tick.className = "tick";
|
|
1594
1593
|
tick.style.cssText = `
|
|
1595
1594
|
position: absolute;
|
|
1596
1595
|
top: ${pixelPos}px;
|
|
1597
1596
|
right: 0;
|
|
1598
1597
|
width: ${TICK_SETTINGS.TICK_WIDTH}px;
|
|
1599
1598
|
height: 1px;
|
|
1600
|
-
background:
|
|
1599
|
+
background: var(--ruler-tick-color);
|
|
1601
1600
|
`;
|
|
1602
1601
|
container.appendChild(tick);
|
|
1603
1602
|
const shouldShowLabel = position % TICK_SETTINGS.TICK_LABEL_INTERVAL === 0;
|
|
1604
1603
|
if (shouldShowLabel) {
|
|
1605
1604
|
const label = document.createElement("div");
|
|
1606
|
-
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1607
1605
|
label.style.cssText = `
|
|
1608
1606
|
position: absolute;
|
|
1609
1607
|
top: ${pixelPos - 6}px;
|
|
1610
1608
|
right: ${TICK_SETTINGS.TICK_WIDTH + 6}px;
|
|
1611
1609
|
font-size: ${config.rulerFontSize}px;
|
|
1612
1610
|
line-height: 1;
|
|
1613
|
-
color:
|
|
1611
|
+
color: var(--ruler-text-color);
|
|
1614
1612
|
white-space: nowrap;
|
|
1615
1613
|
pointer-events: none;
|
|
1616
1614
|
transform: rotate(-90deg);
|
|
@@ -1656,44 +1654,36 @@ function updateRulers(canvas, horizontalRuler, verticalRuler, gridOverlay, confi
|
|
|
1656
1654
|
}
|
|
1657
1655
|
}
|
|
1658
1656
|
|
|
1659
|
-
/**
|
|
1660
|
-
* Updates all ruler elements with new theme colors
|
|
1661
|
-
* @param elements - The ruler elements to update
|
|
1662
|
-
* @param config - The canvas config containing theme and color settings
|
|
1663
|
-
*/
|
|
1664
1657
|
function updateRulerTheme(elements, config) {
|
|
1665
1658
|
// Get theme-aware colors
|
|
1666
1659
|
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1667
1660
|
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1668
1661
|
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1662
|
+
const tickColor = getThemeValue(config, "rulerTickColor");
|
|
1669
1663
|
const gridColor = getThemeValue(config, "gridColor");
|
|
1670
|
-
// Update horizontal ruler
|
|
1664
|
+
// Update horizontal ruler with CSS variables
|
|
1671
1665
|
if (elements.horizontalRuler) {
|
|
1672
|
-
elements.horizontalRuler.style.background
|
|
1673
|
-
elements.horizontalRuler.style.
|
|
1674
|
-
elements.horizontalRuler.style.
|
|
1675
|
-
elements.horizontalRuler.style.color
|
|
1666
|
+
elements.horizontalRuler.style.setProperty("--ruler-background-color", backgroundColor);
|
|
1667
|
+
elements.horizontalRuler.style.setProperty("--ruler-border-color", borderColor);
|
|
1668
|
+
elements.horizontalRuler.style.setProperty("--ruler-text-color", textColor);
|
|
1669
|
+
elements.horizontalRuler.style.setProperty("--ruler-tick-color", tickColor);
|
|
1676
1670
|
}
|
|
1677
|
-
// Update vertical ruler
|
|
1671
|
+
// Update vertical ruler with CSS variables
|
|
1678
1672
|
if (elements.verticalRuler) {
|
|
1679
|
-
elements.verticalRuler.style.background
|
|
1680
|
-
elements.verticalRuler.style.
|
|
1681
|
-
elements.verticalRuler.style.
|
|
1682
|
-
elements.verticalRuler.style.color
|
|
1673
|
+
elements.verticalRuler.style.setProperty("--ruler-background-color", backgroundColor);
|
|
1674
|
+
elements.verticalRuler.style.setProperty("--ruler-border-color", borderColor);
|
|
1675
|
+
elements.verticalRuler.style.setProperty("--ruler-text-color", textColor);
|
|
1676
|
+
elements.verticalRuler.style.setProperty("--ruler-tick-color", tickColor);
|
|
1683
1677
|
}
|
|
1684
|
-
// Update corner box
|
|
1678
|
+
// Update corner box with CSS variables
|
|
1685
1679
|
if (elements.cornerBox) {
|
|
1686
|
-
elements.cornerBox.style.background
|
|
1687
|
-
elements.cornerBox.style.
|
|
1688
|
-
elements.cornerBox.style.
|
|
1689
|
-
elements.cornerBox.style.color = textColor;
|
|
1680
|
+
elements.cornerBox.style.setProperty("--ruler-background-color", backgroundColor);
|
|
1681
|
+
elements.cornerBox.style.setProperty("--ruler-border-color", borderColor);
|
|
1682
|
+
elements.cornerBox.style.setProperty("--ruler-text-color", textColor);
|
|
1690
1683
|
}
|
|
1691
|
-
// Update grid overlay
|
|
1684
|
+
// Update grid overlay with CSS variables
|
|
1692
1685
|
if (elements.gridOverlay) {
|
|
1693
|
-
elements.gridOverlay.style.
|
|
1694
|
-
linear-gradient(${gridColor} 1px, transparent 1px),
|
|
1695
|
-
linear-gradient(90deg, ${gridColor} 1px, transparent 1px)
|
|
1696
|
-
`;
|
|
1686
|
+
elements.gridOverlay.style.setProperty("--grid-color", gridColor);
|
|
1697
1687
|
}
|
|
1698
1688
|
}
|
|
1699
1689
|
|
|
@@ -1713,6 +1703,7 @@ function createRulers(canvas, config) {
|
|
|
1713
1703
|
try {
|
|
1714
1704
|
elements = createRulerElements(canvas.container, config);
|
|
1715
1705
|
cleanupEvents = setupRulerEvents(canvas, safeUpdate);
|
|
1706
|
+
updateRulerTheme(elements, config);
|
|
1716
1707
|
safeUpdate();
|
|
1717
1708
|
if (!config.showRulers) {
|
|
1718
1709
|
elements.horizontalRuler.style.display = "none";
|
|
@@ -1733,8 +1724,6 @@ function createRulers(canvas, config) {
|
|
|
1733
1724
|
return;
|
|
1734
1725
|
// Update all ruler theme colors
|
|
1735
1726
|
updateRulerTheme(elements, newConfig);
|
|
1736
|
-
// Re-render rulers to update tick colors
|
|
1737
|
-
safeUpdate();
|
|
1738
1727
|
},
|
|
1739
1728
|
show: () => {
|
|
1740
1729
|
if (elements.horizontalRuler)
|
|
@@ -1804,11 +1793,59 @@ class MarkupCanvas {
|
|
|
1804
1793
|
throw new Error("Failed to create canvas");
|
|
1805
1794
|
}
|
|
1806
1795
|
this.baseCanvas = canvas;
|
|
1796
|
+
if (this.config.bindToWindow) {
|
|
1797
|
+
this.listen.setEmitInterceptor((event, data) => {
|
|
1798
|
+
this.broadcastEvent(event, data);
|
|
1799
|
+
});
|
|
1800
|
+
this.setupGlobalBinding();
|
|
1801
|
+
}
|
|
1807
1802
|
this.setupEventHandlers();
|
|
1808
1803
|
this._isReady = true;
|
|
1809
1804
|
// Emit ready event
|
|
1810
1805
|
this.listen.emit("ready", this);
|
|
1811
1806
|
}
|
|
1807
|
+
setupGlobalBinding() {
|
|
1808
|
+
if (typeof window === "undefined") {
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
const canvasName = this.config.name || "markupCanvas";
|
|
1812
|
+
const windowObj = window;
|
|
1813
|
+
// Bind instance to window
|
|
1814
|
+
windowObj[canvasName] = this;
|
|
1815
|
+
// Track all instances
|
|
1816
|
+
if (!windowObj.__markupCanvasInstances) {
|
|
1817
|
+
windowObj.__markupCanvasInstances = new Map();
|
|
1818
|
+
}
|
|
1819
|
+
windowObj.__markupCanvasInstances.set(canvasName, this);
|
|
1820
|
+
}
|
|
1821
|
+
cleanupGlobalBinding() {
|
|
1822
|
+
if (typeof window === "undefined") {
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
const canvasName = this.config.name || "markupCanvas";
|
|
1826
|
+
const windowObj = window;
|
|
1827
|
+
delete windowObj[canvasName];
|
|
1828
|
+
if (windowObj.__markupCanvasInstances) {
|
|
1829
|
+
windowObj.__markupCanvasInstances.delete(canvasName);
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
broadcastEvent(event, data) {
|
|
1833
|
+
if (typeof window === "undefined") {
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
// Receivers can get the instance from the window binding
|
|
1837
|
+
let broadcastData = data;
|
|
1838
|
+
if (event === "ready") {
|
|
1839
|
+
broadcastData = { ready: true };
|
|
1840
|
+
}
|
|
1841
|
+
window.postMessage({
|
|
1842
|
+
source: "markup-canvas",
|
|
1843
|
+
event,
|
|
1844
|
+
data: broadcastData,
|
|
1845
|
+
timestamp: Date.now(),
|
|
1846
|
+
canvasName: this.config.name,
|
|
1847
|
+
}, "*");
|
|
1848
|
+
}
|
|
1812
1849
|
setupEventHandlers() {
|
|
1813
1850
|
try {
|
|
1814
1851
|
// Wheel zoom
|
|
@@ -2120,6 +2157,7 @@ class MarkupCanvas {
|
|
|
2120
2157
|
}
|
|
2121
2158
|
// Cleanup method
|
|
2122
2159
|
cleanup() {
|
|
2160
|
+
this.cleanupGlobalBinding();
|
|
2123
2161
|
this.cleanupFunctions.forEach((cleanup) => {
|
|
2124
2162
|
try {
|
|
2125
2163
|
cleanup();
|