@markup-canvas/core 1.0.6 → 1.0.8
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/README.md +42 -2
- package/dist/lib/MarkupCanvas.d.ts +1 -0
- package/dist/lib/canvas/setupCanvasContainer.d.ts +2 -1
- package/dist/lib/helpers/index.d.ts +1 -0
- package/dist/lib/helpers/withTheme.d.ts +4 -0
- package/dist/lib/rulers/constants.d.ts +3 -6
- package/dist/lib/rulers/ticks/createHorizontalTick.d.ts +1 -1
- package/dist/lib/rulers/ticks/createVerticalTick.d.ts +1 -1
- package/dist/lib/rulers/updateRulerTheme.d.ts +8 -0
- package/dist/markup-canvas.cjs.js +149 -54
- package/dist/markup-canvas.esm.js +149 -54
- package/dist/markup-canvas.umd.js +130 -47
- package/dist/markup-canvas.umd.min.js +1 -1
- package/dist/types/config.d.ts +11 -2
- package/dist/types/rulers.d.ts +2 -0
- package/package.json +4 -4
- package/src/lib/MarkupCanvas.ts +19 -1
- package/src/lib/canvas/createCanvas.ts +1 -1
- package/src/lib/canvas/setupCanvasContainer.ts +9 -1
- package/src/lib/config/constants.ts +24 -9
- package/src/lib/config/presets/editor-preset.ts +23 -7
- package/src/lib/helpers/index.ts +1 -0
- package/src/lib/helpers/withTheme.ts +17 -0
- package/src/lib/rulers/constants.ts +3 -6
- package/src/lib/rulers/createCornerBox.ts +5 -4
- package/src/lib/rulers/createGridOverlay.ts +3 -2
- package/src/lib/rulers/createHorizontalRuler.ts +5 -4
- package/src/lib/rulers/createRulers.ts +19 -0
- package/src/lib/rulers/createVerticalRuler.ts +5 -4
- package/src/lib/rulers/ticks/createHorizontalTick.ts +8 -8
- package/src/lib/rulers/ticks/createVerticalTick.ts +8 -8
- package/src/lib/rulers/updateRulerTheme.ts +46 -0
- package/src/types/config.ts +18 -3
- package/src/types/rulers.ts +2 -0
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ Lightweight, canvas-like container with smooth pan and zoom capabilities. Simply
|
|
|
7
7
|
- 🚀 **High Performance**: 60fps smooth animations with GPU acceleration
|
|
8
8
|
- 🎯 **Precise Control**: Zoom, pan, and navigate with mouse, keyboard, or touch
|
|
9
9
|
- 📏 **Rulers & Grid**: Optional rulers and grid overlay
|
|
10
|
+
- 🌓 **Dark Mode**: Built-in dark theme support
|
|
10
11
|
- 🔧 **Event System**: Built-in EventEmitter for reactive updates
|
|
11
12
|
- 📦 **TypeScript**: Full TypeScript support with comprehensive types
|
|
12
13
|
|
|
@@ -102,6 +103,8 @@ const canvas = new MarkupCanvas(container, {
|
|
|
102
103
|
|--------|------|---------|-------------|
|
|
103
104
|
| `enableRulers` | `boolean` | `true` | Show rulers on top and left |
|
|
104
105
|
| `enableGrid` | `boolean` | `false` | Show background grid |
|
|
106
|
+
| `showRulers` | `boolean` | `true` | Initially show rulers (only applies if `enableRulers` is true) |
|
|
107
|
+
| `showGrid` | `boolean` | `false` | Initially show grid (only applies if `enableGrid` is true) |
|
|
105
108
|
| `gridColor` | `string` | `"#e0e0e0"` | Grid line color |
|
|
106
109
|
|
|
107
110
|
#### Ruler Styling
|
|
@@ -111,12 +114,22 @@ const canvas = new MarkupCanvas(container, {
|
|
|
111
114
|
| `rulerBackgroundColor` | `string` | `"#f5f5f5"` | Ruler background color |
|
|
112
115
|
| `rulerBorderColor` | `string` | `"#d0d0d0"` | Ruler border color |
|
|
113
116
|
| `rulerTextColor` | `string` | `"#666666"` | Ruler text color |
|
|
114
|
-
| `
|
|
115
|
-
| `rulerMinorTickColor` | `string` | `"#999999"` | Minor tick mark color |
|
|
117
|
+
| `rulerTickColor` | `string` | `"#cccccc"` | Tick mark color |
|
|
116
118
|
| `rulerFontSize` | `number` | `12` | Ruler font size in pixels |
|
|
117
119
|
| `rulerFontFamily` | `string` | `"monospace"` | Ruler font family |
|
|
118
120
|
| `rulerUnits` | `string` | `"px"` | Ruler units label |
|
|
119
121
|
|
|
122
|
+
#### Dark Theme Support
|
|
123
|
+
|
|
124
|
+
| Option | Type | Default | Description |
|
|
125
|
+
|--------|------|---------|-------------|
|
|
126
|
+
| `themeMode` | `"light" \| "dark"` | `"light"` | Current theme mode |
|
|
127
|
+
| `rulerBackgroundColorDark` | `string` | `"rgba(30, 30, 30, 0.95)"` | Dark mode ruler background color |
|
|
128
|
+
| `rulerBorderColorDark` | `string` | `"#444"` | Dark mode ruler border color |
|
|
129
|
+
| `rulerTextColorDark` | `string` | `"#aaa"` | Dark mode ruler text color |
|
|
130
|
+
| `rulerTickColorDark` | `string` | `"#383838"` | Dark mode tick mark color |
|
|
131
|
+
| `gridColorDark` | `string` | `"rgba(255, 255, 255, 0.1)"` | Dark mode grid line color |
|
|
132
|
+
|
|
120
133
|
#### Callbacks
|
|
121
134
|
|
|
122
135
|
| Option | Type | Description |
|
|
@@ -185,6 +198,33 @@ Always cleanup when you're done:
|
|
|
185
198
|
canvas.cleanup();
|
|
186
199
|
```
|
|
187
200
|
|
|
201
|
+
### Theme Management
|
|
202
|
+
|
|
203
|
+
Switch between light and dark themes dynamically:
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
// Change theme mode
|
|
207
|
+
canvas.updateThemeMode('dark');
|
|
208
|
+
canvas.updateThemeMode('light');
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
You can also customize dark theme colors:
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
const canvas = new MarkupCanvas(container, {
|
|
215
|
+
width: 20000,
|
|
216
|
+
height: 15000,
|
|
217
|
+
themeMode: 'light',
|
|
218
|
+
// Light theme colors (default)
|
|
219
|
+
rulerBackgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
220
|
+
rulerTextColor: '#666',
|
|
221
|
+
// Dark theme colors
|
|
222
|
+
rulerBackgroundColorDark: 'rgba(30, 30, 30, 0.95)',
|
|
223
|
+
rulerTextColorDark: '#aaa',
|
|
224
|
+
gridColorDark: 'rgba(255, 255, 255, 0.1)',
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
188
228
|
### Complete Example
|
|
189
229
|
|
|
190
230
|
Here's a complete example with HTML:
|
|
@@ -69,6 +69,7 @@ export declare class MarkupCanvas implements Canvas {
|
|
|
69
69
|
scrollToPoint(x: number, y: number): boolean;
|
|
70
70
|
getConfig(): Required<MarkupCanvasConfig>;
|
|
71
71
|
updateConfig(newConfig: Partial<MarkupCanvasConfig>): void;
|
|
72
|
+
updateThemeMode(mode: "light" | "dark"): void;
|
|
72
73
|
cleanup(): void;
|
|
73
74
|
on<K extends keyof MarkupCanvasEvents>(event: K, handler: (data: MarkupCanvasEvents[K]) => void): void;
|
|
74
75
|
off<K extends keyof MarkupCanvasEvents>(event: K, handler: (data: MarkupCanvasEvents[K]) => void): void;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { MarkupCanvasConfig } from "@/types/index.js";
|
|
2
|
+
export declare function setupCanvasContainer(container: HTMLElement, config?: Required<MarkupCanvasConfig>): void;
|
|
@@ -4,3 +4,4 @@ export { withFeatureEnabled } from "./withFeatureEnabled.js";
|
|
|
4
4
|
export { withRAF, withRAFThrottle } from "./withRAF.js";
|
|
5
5
|
export { withRulerAdjustment, withRulerCheck, withRulerOffsetObject, withRulerOffsets, withRulerSize, } from "./withRulerCheck.js";
|
|
6
6
|
export { withRulerOffset } from "./withRulerOffset.js";
|
|
7
|
+
export { getThemeValue } from "./withTheme.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MarkupCanvasConfig } from "@/types";
|
|
2
|
+
type ThemeColorKey = "canvasBackgroundColor" | "rulerBackgroundColor" | "rulerBorderColor" | "rulerTextColor" | "rulerTickColor" | "gridColor";
|
|
3
|
+
export declare function getThemeValue(config: Required<MarkupCanvasConfig>, key: ThemeColorKey): string;
|
|
4
|
+
export {};
|
|
@@ -4,12 +4,9 @@ export declare const RULER_Z_INDEX: {
|
|
|
4
4
|
readonly CORNER: 1001;
|
|
5
5
|
};
|
|
6
6
|
export declare const TICK_SETTINGS: {
|
|
7
|
-
readonly
|
|
8
|
-
readonly
|
|
9
|
-
readonly
|
|
10
|
-
readonly MINOR_WIDTH: 4;
|
|
11
|
-
readonly MAJOR_MULTIPLIER: 5;
|
|
12
|
-
readonly LABEL_INTERVAL: 100;
|
|
7
|
+
readonly TICK_HEIGHT: 4;
|
|
8
|
+
readonly TICK_WIDTH: 4;
|
|
9
|
+
readonly TICK_LABEL_INTERVAL: 100;
|
|
13
10
|
};
|
|
14
11
|
export declare const GRID_SETTINGS: {
|
|
15
12
|
readonly BASE_SIZE: 100;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { MarkupCanvasConfig } from "@/types/index.js";
|
|
2
|
-
export declare function createHorizontalTick(container: HTMLElement | DocumentFragment, position: number, pixelPos: number,
|
|
2
|
+
export declare function createHorizontalTick(container: HTMLElement | DocumentFragment, position: number, pixelPos: number, _tickSpacing: number, config: Required<MarkupCanvasConfig>): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { MarkupCanvasConfig } from "@/types/index.js";
|
|
2
|
-
export declare function createVerticalTick(container: HTMLElement | DocumentFragment, position: number, pixelPos: number,
|
|
2
|
+
export declare function createVerticalTick(container: HTMLElement | DocumentFragment, position: number, pixelPos: number, _tickSpacing: number, config: Required<MarkupCanvasConfig>): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MarkupCanvasConfig } from "@/types/index.js";
|
|
2
|
+
export interface RulerThemeUpdater {
|
|
3
|
+
horizontalRuler?: HTMLElement;
|
|
4
|
+
verticalRuler?: HTMLElement;
|
|
5
|
+
cornerBox?: HTMLElement;
|
|
6
|
+
gridOverlay?: HTMLElement;
|
|
7
|
+
}
|
|
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.8
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -40,17 +40,29 @@ const EDITOR_PRESET = {
|
|
|
40
40
|
// Visual elements
|
|
41
41
|
enableRulers: true,
|
|
42
42
|
enableGrid: false,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
rulerBackgroundColor: "rgba(255, 255, 255, 0.4)",
|
|
46
|
-
rulerBorderColor: "#ddd",
|
|
47
|
-
rulerTextColor: "oklch(70.5% 0.015 286.067)",
|
|
48
|
-
rulerMajorTickColor: "oklch(87.1% 0.006 286.286)",
|
|
49
|
-
rulerMinorTickColor: "oklch(92% 0.004 286.32)",
|
|
43
|
+
showRulers: true,
|
|
44
|
+
showGrid: false,
|
|
50
45
|
rulerFontSize: 9,
|
|
51
46
|
rulerFontFamily: "Monaco, Menlo, monospace",
|
|
52
47
|
rulerUnits: "px",
|
|
53
48
|
rulerSize: 20,
|
|
49
|
+
// Canvas styling
|
|
50
|
+
canvasBackgroundColor: "transparent",
|
|
51
|
+
canvasBackgroundColorDark: "transparent",
|
|
52
|
+
// Ruler styling
|
|
53
|
+
rulerBackgroundColor: "oklch(100% 0 0 / 0.4)",
|
|
54
|
+
rulerBorderColor: "oklch(96.7% 0.001 286.375)",
|
|
55
|
+
rulerTextColor: "oklch(70.5% 0.015 286.067)",
|
|
56
|
+
rulerTickColor: "oklch(92% 0.004 286.32)",
|
|
57
|
+
gridColor: "rgba(232, 86, 193, 0.5)",
|
|
58
|
+
// Ruler styling (dark theme)
|
|
59
|
+
rulerBackgroundColorDark: "oklch(27.4% 0.006 286.033)",
|
|
60
|
+
rulerBorderColorDark: "oklch(44.2% 0.017 285.786)",
|
|
61
|
+
rulerTextColorDark: "oklch(55.2% 0.016 285.938)",
|
|
62
|
+
rulerTickColorDark: "oklch(55.2% 0.016 285.938)",
|
|
63
|
+
gridColorDark: "rgba(232, 86, 193, 0.5)",
|
|
64
|
+
// Theme
|
|
65
|
+
themeMode: "light",
|
|
54
66
|
// Callbacks
|
|
55
67
|
onTransformUpdate: () => { },
|
|
56
68
|
};
|
|
@@ -285,6 +297,14 @@ function withRulerOffset(canvas, x, y, rulerSize, operation) {
|
|
|
285
297
|
return operation(adjustedX, adjustedY);
|
|
286
298
|
}
|
|
287
299
|
|
|
300
|
+
function getThemeValue(config, key) {
|
|
301
|
+
if (config.themeMode === "dark") {
|
|
302
|
+
const darkKey = `${key}Dark`;
|
|
303
|
+
return config[darkKey];
|
|
304
|
+
}
|
|
305
|
+
return config[key];
|
|
306
|
+
}
|
|
307
|
+
|
|
288
308
|
const DEFAULT_CONFIG = {
|
|
289
309
|
// Canvas dimensions
|
|
290
310
|
width: 8000,
|
|
@@ -317,18 +337,30 @@ const DEFAULT_CONFIG = {
|
|
|
317
337
|
requireOptionForClickZoom: false,
|
|
318
338
|
// Visual elements
|
|
319
339
|
enableRulers: true,
|
|
320
|
-
enableGrid:
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
rulerBackgroundColor: "rgba(255, 255, 255, 0.95)",
|
|
324
|
-
rulerBorderColor: "#ddd",
|
|
325
|
-
rulerTextColor: "#666",
|
|
326
|
-
rulerMajorTickColor: "#999",
|
|
327
|
-
rulerMinorTickColor: "#ccc",
|
|
340
|
+
enableGrid: false,
|
|
341
|
+
showRulers: true,
|
|
342
|
+
showGrid: false,
|
|
328
343
|
rulerFontSize: 9,
|
|
329
344
|
rulerFontFamily: "Monaco, Menlo, monospace",
|
|
330
345
|
rulerUnits: "px",
|
|
331
346
|
rulerSize: 20,
|
|
347
|
+
// Canvas styling
|
|
348
|
+
canvasBackgroundColor: "rgba(250, 250, 250, 1)",
|
|
349
|
+
canvasBackgroundColorDark: "rgba(40, 40, 40, 1)",
|
|
350
|
+
// Ruler styling (light theme)
|
|
351
|
+
rulerBackgroundColor: "rgba(255, 255, 255, 0.95)",
|
|
352
|
+
rulerBorderColor: "rgba(240, 240, 240, 1)",
|
|
353
|
+
rulerTextColor: "rgba(102, 102, 102, 1)",
|
|
354
|
+
rulerTickColor: "rgba(204, 204, 204, 1)",
|
|
355
|
+
gridColor: "rgba(232, 86, 193, 0.5)",
|
|
356
|
+
// Ruler styling (dark theme)
|
|
357
|
+
rulerBackgroundColorDark: "rgba(30, 30, 30, 0.95)",
|
|
358
|
+
rulerBorderColorDark: "rgba(68, 68, 68, 1)",
|
|
359
|
+
rulerTextColorDark: "rgba(170, 170, 170, 1)",
|
|
360
|
+
rulerTickColorDark: "rgba(104, 104, 104, 1)",
|
|
361
|
+
gridColorDark: "rgba(232, 86, 193, 0.5)",
|
|
362
|
+
// Theme
|
|
363
|
+
themeMode: "light",
|
|
332
364
|
// Callbacks
|
|
333
365
|
onTransformUpdate: () => { },
|
|
334
366
|
};
|
|
@@ -560,7 +592,7 @@ function checkContainerDimensions(container) {
|
|
|
560
592
|
}
|
|
561
593
|
}
|
|
562
594
|
|
|
563
|
-
function setupCanvasContainer(container) {
|
|
595
|
+
function setupCanvasContainer(container, config) {
|
|
564
596
|
const currentPosition = getComputedStyle(container).position;
|
|
565
597
|
if (currentPosition === "static") {
|
|
566
598
|
container.style.position = "relative";
|
|
@@ -568,6 +600,11 @@ function setupCanvasContainer(container) {
|
|
|
568
600
|
container.style.overflow = "hidden";
|
|
569
601
|
container.style.cursor = "grab";
|
|
570
602
|
container.style.overscrollBehavior = "none";
|
|
603
|
+
// Apply canvas background color
|
|
604
|
+
if (config) {
|
|
605
|
+
const backgroundColor = getThemeValue(config, "canvasBackgroundColor");
|
|
606
|
+
container.style.backgroundColor = backgroundColor;
|
|
607
|
+
}
|
|
571
608
|
if (!container.hasAttribute("tabindex")) {
|
|
572
609
|
container.setAttribute("tabindex", "0");
|
|
573
610
|
}
|
|
@@ -584,7 +621,7 @@ function createCanvas(container, config) {
|
|
|
584
621
|
return null;
|
|
585
622
|
}
|
|
586
623
|
try {
|
|
587
|
-
setupCanvasContainer(container);
|
|
624
|
+
setupCanvasContainer(container, config);
|
|
588
625
|
const { transformLayer, contentLayer } = createCanvasLayers(container, config);
|
|
589
626
|
// Enable hardware acceleration if requested
|
|
590
627
|
if (config.enableAcceleration) {
|
|
@@ -1330,12 +1367,9 @@ const RULER_Z_INDEX = {
|
|
|
1330
1367
|
CORNER: 1001,
|
|
1331
1368
|
};
|
|
1332
1369
|
const TICK_SETTINGS = {
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
MINOR_WIDTH: 4,
|
|
1337
|
-
MAJOR_MULTIPLIER: 5,
|
|
1338
|
-
LABEL_INTERVAL: 100,
|
|
1370
|
+
TICK_HEIGHT: 4,
|
|
1371
|
+
TICK_WIDTH: 4,
|
|
1372
|
+
TICK_LABEL_INTERVAL: 100,
|
|
1339
1373
|
};
|
|
1340
1374
|
const GRID_SETTINGS = {
|
|
1341
1375
|
BASE_SIZE: 100,
|
|
@@ -1352,16 +1386,16 @@ function createCornerBox(config) {
|
|
|
1352
1386
|
left: 0;
|
|
1353
1387
|
width: ${config.rulerSize}px;
|
|
1354
1388
|
height: ${config.rulerSize}px;
|
|
1355
|
-
background:
|
|
1356
|
-
border-right: 1px solid
|
|
1357
|
-
border-bottom: 1px solid
|
|
1389
|
+
background: var(--ruler-background-color);
|
|
1390
|
+
border-right: 1px solid var(--ruler-border-color);
|
|
1391
|
+
border-bottom: 1px solid var(--ruler-border-color);
|
|
1358
1392
|
z-index: ${RULER_Z_INDEX.CORNER};
|
|
1359
1393
|
display: flex;
|
|
1360
1394
|
align-items: center;
|
|
1361
1395
|
justify-content: center;
|
|
1362
1396
|
font-family: ${config.rulerFontFamily};
|
|
1363
1397
|
font-size: ${config.rulerFontSize - 2}px;
|
|
1364
|
-
color:
|
|
1398
|
+
color: var(--ruler-text-color);
|
|
1365
1399
|
pointer-events: none;
|
|
1366
1400
|
`;
|
|
1367
1401
|
corner.textContent = config.rulerUnits;
|
|
@@ -1380,8 +1414,8 @@ function createGridOverlay(config) {
|
|
|
1380
1414
|
pointer-events: none;
|
|
1381
1415
|
z-index: ${RULER_Z_INDEX.GRID};
|
|
1382
1416
|
background-image:
|
|
1383
|
-
linear-gradient(
|
|
1384
|
-
linear-gradient(90deg,
|
|
1417
|
+
linear-gradient(var(--grid-color) 1px, transparent 1px),
|
|
1418
|
+
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
|
|
1385
1419
|
background-size: 100px 100px;
|
|
1386
1420
|
opacity: 0.5;
|
|
1387
1421
|
`;
|
|
@@ -1397,14 +1431,14 @@ function createHorizontalRuler(config) {
|
|
|
1397
1431
|
left: ${config.rulerSize}px;
|
|
1398
1432
|
right: 0;
|
|
1399
1433
|
height: ${config.rulerSize}px;
|
|
1400
|
-
background:
|
|
1401
|
-
border-bottom: 1px solid
|
|
1402
|
-
border-right: 1px solid
|
|
1434
|
+
background: var(--ruler-background-color);
|
|
1435
|
+
border-bottom: 1px solid var(--ruler-border-color);
|
|
1436
|
+
border-right: 1px solid var(--ruler-border-color);
|
|
1403
1437
|
z-index: ${RULER_Z_INDEX.RULERS};
|
|
1404
1438
|
pointer-events: none;
|
|
1405
1439
|
font-family: ${config.rulerFontFamily};
|
|
1406
1440
|
font-size: ${config.rulerFontSize}px;
|
|
1407
|
-
color:
|
|
1441
|
+
color: var(--ruler-text-color);
|
|
1408
1442
|
overflow: hidden;
|
|
1409
1443
|
`;
|
|
1410
1444
|
return ruler;
|
|
@@ -1419,14 +1453,14 @@ function createVerticalRuler(config) {
|
|
|
1419
1453
|
left: 0;
|
|
1420
1454
|
bottom: 0;
|
|
1421
1455
|
width: ${config.rulerSize}px;
|
|
1422
|
-
background:
|
|
1423
|
-
border-right: 1px solid
|
|
1424
|
-
border-bottom: 1px solid
|
|
1456
|
+
background: var(--ruler-background-color);
|
|
1457
|
+
border-right: 1px solid var(--ruler-border-color);
|
|
1458
|
+
border-bottom: 1px solid var(--ruler-border-color);
|
|
1425
1459
|
z-index: ${RULER_Z_INDEX.RULERS};
|
|
1426
1460
|
pointer-events: none;
|
|
1427
1461
|
font-family: ${config.rulerFontFamily};
|
|
1428
1462
|
font-size: ${config.rulerFontSize}px;
|
|
1429
|
-
color:
|
|
1463
|
+
color: var(--ruler-text-color);
|
|
1430
1464
|
overflow: hidden;
|
|
1431
1465
|
`;
|
|
1432
1466
|
return ruler;
|
|
@@ -1496,29 +1530,28 @@ function calculateTickSpacing(contentSize, canvasSize) {
|
|
|
1496
1530
|
return niceSpacing * magnitude;
|
|
1497
1531
|
}
|
|
1498
1532
|
|
|
1499
|
-
function createHorizontalTick(container, position, pixelPos,
|
|
1533
|
+
function createHorizontalTick(container, position, pixelPos, _tickSpacing, config) {
|
|
1500
1534
|
const tick = document.createElement("div");
|
|
1501
|
-
|
|
1502
|
-
const tickHeight = isMajor ? TICK_SETTINGS.MAJOR_HEIGHT : TICK_SETTINGS.MINOR_HEIGHT;
|
|
1535
|
+
tick.className = "tick";
|
|
1503
1536
|
tick.style.cssText = `
|
|
1504
1537
|
position: absolute;
|
|
1505
1538
|
left: ${pixelPos}px;
|
|
1506
1539
|
bottom: 0;
|
|
1507
1540
|
width: 1px;
|
|
1508
|
-
height: ${
|
|
1509
|
-
background:
|
|
1541
|
+
height: ${TICK_SETTINGS.TICK_HEIGHT}px;
|
|
1542
|
+
background: var(--ruler-tick-color);
|
|
1510
1543
|
`;
|
|
1511
1544
|
container.appendChild(tick);
|
|
1512
|
-
const shouldShowLabel =
|
|
1545
|
+
const shouldShowLabel = position % TICK_SETTINGS.TICK_LABEL_INTERVAL === 0;
|
|
1513
1546
|
if (shouldShowLabel) {
|
|
1514
1547
|
const label = document.createElement("div");
|
|
1515
1548
|
label.style.cssText = `
|
|
1516
1549
|
position: absolute;
|
|
1517
1550
|
left: ${pixelPos}px;
|
|
1518
|
-
bottom: ${
|
|
1551
|
+
bottom: ${TICK_SETTINGS.TICK_HEIGHT + 2}px;
|
|
1519
1552
|
font-size: ${config.rulerFontSize}px;
|
|
1520
1553
|
line-height: 1;
|
|
1521
|
-
color:
|
|
1554
|
+
color: var(--ruler-text-color);
|
|
1522
1555
|
white-space: nowrap;
|
|
1523
1556
|
pointer-events: none;
|
|
1524
1557
|
`;
|
|
@@ -1544,29 +1577,28 @@ function updateHorizontalRuler(ruler, contentLeft, contentRight, canvasWidth, sc
|
|
|
1544
1577
|
ruler.appendChild(fragment);
|
|
1545
1578
|
}
|
|
1546
1579
|
|
|
1547
|
-
function createVerticalTick(container, position, pixelPos,
|
|
1580
|
+
function createVerticalTick(container, position, pixelPos, _tickSpacing, config) {
|
|
1548
1581
|
const tick = document.createElement("div");
|
|
1549
|
-
|
|
1550
|
-
const tickWidth = isMajor ? TICK_SETTINGS.MAJOR_WIDTH : TICK_SETTINGS.MINOR_WIDTH;
|
|
1582
|
+
tick.className = "tick";
|
|
1551
1583
|
tick.style.cssText = `
|
|
1552
1584
|
position: absolute;
|
|
1553
1585
|
top: ${pixelPos}px;
|
|
1554
1586
|
right: 0;
|
|
1555
|
-
width: ${
|
|
1587
|
+
width: ${TICK_SETTINGS.TICK_WIDTH}px;
|
|
1556
1588
|
height: 1px;
|
|
1557
|
-
background:
|
|
1589
|
+
background: var(--ruler-tick-color);
|
|
1558
1590
|
`;
|
|
1559
1591
|
container.appendChild(tick);
|
|
1560
|
-
const shouldShowLabel =
|
|
1592
|
+
const shouldShowLabel = position % TICK_SETTINGS.TICK_LABEL_INTERVAL === 0;
|
|
1561
1593
|
if (shouldShowLabel) {
|
|
1562
1594
|
const label = document.createElement("div");
|
|
1563
1595
|
label.style.cssText = `
|
|
1564
1596
|
position: absolute;
|
|
1565
1597
|
top: ${pixelPos - 6}px;
|
|
1566
|
-
right: ${
|
|
1598
|
+
right: ${TICK_SETTINGS.TICK_WIDTH + 6}px;
|
|
1567
1599
|
font-size: ${config.rulerFontSize}px;
|
|
1568
1600
|
line-height: 1;
|
|
1569
|
-
color:
|
|
1601
|
+
color: var(--ruler-text-color);
|
|
1570
1602
|
white-space: nowrap;
|
|
1571
1603
|
pointer-events: none;
|
|
1572
1604
|
transform: rotate(-90deg);
|
|
@@ -1612,6 +1644,39 @@ function updateRulers(canvas, horizontalRuler, verticalRuler, gridOverlay, confi
|
|
|
1612
1644
|
}
|
|
1613
1645
|
}
|
|
1614
1646
|
|
|
1647
|
+
function updateRulerTheme(elements, config) {
|
|
1648
|
+
// Get theme-aware colors
|
|
1649
|
+
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1650
|
+
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1651
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1652
|
+
const tickColor = getThemeValue(config, "rulerTickColor");
|
|
1653
|
+
const gridColor = getThemeValue(config, "gridColor");
|
|
1654
|
+
// Update horizontal ruler with CSS variables
|
|
1655
|
+
if (elements.horizontalRuler) {
|
|
1656
|
+
elements.horizontalRuler.style.setProperty("--ruler-background-color", backgroundColor);
|
|
1657
|
+
elements.horizontalRuler.style.setProperty("--ruler-border-color", borderColor);
|
|
1658
|
+
elements.horizontalRuler.style.setProperty("--ruler-text-color", textColor);
|
|
1659
|
+
elements.horizontalRuler.style.setProperty("--ruler-tick-color", tickColor);
|
|
1660
|
+
}
|
|
1661
|
+
// Update vertical ruler with CSS variables
|
|
1662
|
+
if (elements.verticalRuler) {
|
|
1663
|
+
elements.verticalRuler.style.setProperty("--ruler-background-color", backgroundColor);
|
|
1664
|
+
elements.verticalRuler.style.setProperty("--ruler-border-color", borderColor);
|
|
1665
|
+
elements.verticalRuler.style.setProperty("--ruler-text-color", textColor);
|
|
1666
|
+
elements.verticalRuler.style.setProperty("--ruler-tick-color", tickColor);
|
|
1667
|
+
}
|
|
1668
|
+
// Update corner box with CSS variables
|
|
1669
|
+
if (elements.cornerBox) {
|
|
1670
|
+
elements.cornerBox.style.setProperty("--ruler-background-color", backgroundColor);
|
|
1671
|
+
elements.cornerBox.style.setProperty("--ruler-border-color", borderColor);
|
|
1672
|
+
elements.cornerBox.style.setProperty("--ruler-text-color", textColor);
|
|
1673
|
+
}
|
|
1674
|
+
// Update grid overlay with CSS variables
|
|
1675
|
+
if (elements.gridOverlay) {
|
|
1676
|
+
elements.gridOverlay.style.setProperty("--grid-color", gridColor);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1615
1680
|
function createRulers(canvas, config) {
|
|
1616
1681
|
if (!canvas?.container) {
|
|
1617
1682
|
console.error("Invalid canvas provided to createRulers");
|
|
@@ -1628,13 +1693,28 @@ function createRulers(canvas, config) {
|
|
|
1628
1693
|
try {
|
|
1629
1694
|
elements = createRulerElements(canvas.container, config);
|
|
1630
1695
|
cleanupEvents = setupRulerEvents(canvas, safeUpdate);
|
|
1696
|
+
updateRulerTheme(elements, config);
|
|
1631
1697
|
safeUpdate();
|
|
1698
|
+
if (!config.showRulers) {
|
|
1699
|
+
elements.horizontalRuler.style.display = "none";
|
|
1700
|
+
elements.verticalRuler.style.display = "none";
|
|
1701
|
+
elements.cornerBox.style.display = "none";
|
|
1702
|
+
}
|
|
1703
|
+
if (!config.showGrid && elements.gridOverlay) {
|
|
1704
|
+
elements.gridOverlay.style.display = "none";
|
|
1705
|
+
}
|
|
1632
1706
|
return {
|
|
1633
1707
|
horizontalRuler: elements.horizontalRuler,
|
|
1634
1708
|
verticalRuler: elements.verticalRuler,
|
|
1635
1709
|
cornerBox: elements.cornerBox,
|
|
1636
1710
|
gridOverlay: elements.gridOverlay,
|
|
1637
1711
|
update: safeUpdate,
|
|
1712
|
+
updateTheme: (newConfig) => {
|
|
1713
|
+
if (isDestroyed)
|
|
1714
|
+
return;
|
|
1715
|
+
// Update all ruler theme colors
|
|
1716
|
+
updateRulerTheme(elements, newConfig);
|
|
1717
|
+
},
|
|
1638
1718
|
show: () => {
|
|
1639
1719
|
if (elements.horizontalRuler)
|
|
1640
1720
|
elements.horizontalRuler.style.display = "block";
|
|
@@ -2002,6 +2082,21 @@ class MarkupCanvas {
|
|
|
2002
2082
|
updateConfig(newConfig) {
|
|
2003
2083
|
this.config = createMarkupCanvasConfig({ ...this.config, ...newConfig });
|
|
2004
2084
|
}
|
|
2085
|
+
// Theme management
|
|
2086
|
+
updateThemeMode(mode) {
|
|
2087
|
+
const newConfig = {
|
|
2088
|
+
...this.config,
|
|
2089
|
+
themeMode: mode,
|
|
2090
|
+
};
|
|
2091
|
+
this.config = createMarkupCanvasConfig(newConfig);
|
|
2092
|
+
// Update canvas background color
|
|
2093
|
+
const backgroundColor = getThemeValue(this.config, "canvasBackgroundColor");
|
|
2094
|
+
this.baseCanvas.container.style.backgroundColor = backgroundColor;
|
|
2095
|
+
// Update rulers if they exist
|
|
2096
|
+
if (this.rulers) {
|
|
2097
|
+
this.rulers.updateTheme(this.config);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2005
2100
|
// Cleanup method
|
|
2006
2101
|
cleanup() {
|
|
2007
2102
|
this.cleanupFunctions.forEach((cleanup) => {
|