@markup-canvas/core 1.0.6 → 1.0.7
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 +13 -0
- package/dist/markup-canvas.cjs.js +170 -54
- package/dist/markup-canvas.esm.js +170 -54
- package/dist/markup-canvas.umd.js +151 -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 +9 -4
- package/src/lib/rulers/createGridOverlay.ts +5 -2
- package/src/lib/rulers/createHorizontalRuler.ts +9 -4
- package/src/lib/rulers/createRulers.ts +20 -0
- package/src/lib/rulers/createVerticalRuler.ts +9 -4
- package/src/lib/rulers/ticks/createHorizontalTick.ts +10 -8
- package/src/lib/rulers/ticks/createVerticalTick.ts +10 -8
- package/src/lib/rulers/updateRulerTheme.ts +54 -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,13 @@
|
|
|
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
|
+
/**
|
|
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
|
+
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.7
|
|
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: "oklch(98.5% 0 0)",
|
|
51
|
+
canvasBackgroundColorDark: "oklch(21% 0.006 285.885)",
|
|
52
|
+
// Ruler styling
|
|
53
|
+
rulerBackgroundColor: "oklch(100% 0 0 / 0.4)",
|
|
54
|
+
rulerBorderColor: "oklch(98.5% 0 0)",
|
|
55
|
+
rulerTextColor: "oklch(70.5% 0.015 286.067)",
|
|
56
|
+
rulerTickColor: "oklch(70.5% 0.015 286.067)",
|
|
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(37% 0.013 285.805)",
|
|
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(221, 221, 221, 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(56, 56, 56, 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,
|
|
@@ -1346,22 +1380,25 @@ const GRID_SETTINGS = {
|
|
|
1346
1380
|
function createCornerBox(config) {
|
|
1347
1381
|
const corner = document.createElement("div");
|
|
1348
1382
|
corner.className = "canvas-ruler corner-box";
|
|
1383
|
+
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1384
|
+
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1385
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1349
1386
|
corner.style.cssText = `
|
|
1350
1387
|
position: absolute;
|
|
1351
1388
|
top: 0;
|
|
1352
1389
|
left: 0;
|
|
1353
1390
|
width: ${config.rulerSize}px;
|
|
1354
1391
|
height: ${config.rulerSize}px;
|
|
1355
|
-
background: ${
|
|
1356
|
-
border-right: 1px solid ${
|
|
1357
|
-
border-bottom: 1px solid ${
|
|
1392
|
+
background: ${backgroundColor};
|
|
1393
|
+
border-right: 1px solid ${borderColor};
|
|
1394
|
+
border-bottom: 1px solid ${borderColor};
|
|
1358
1395
|
z-index: ${RULER_Z_INDEX.CORNER};
|
|
1359
1396
|
display: flex;
|
|
1360
1397
|
align-items: center;
|
|
1361
1398
|
justify-content: center;
|
|
1362
1399
|
font-family: ${config.rulerFontFamily};
|
|
1363
1400
|
font-size: ${config.rulerFontSize - 2}px;
|
|
1364
|
-
color: ${
|
|
1401
|
+
color: ${textColor};
|
|
1365
1402
|
pointer-events: none;
|
|
1366
1403
|
`;
|
|
1367
1404
|
corner.textContent = config.rulerUnits;
|
|
@@ -1371,6 +1408,7 @@ function createCornerBox(config) {
|
|
|
1371
1408
|
function createGridOverlay(config) {
|
|
1372
1409
|
const grid = document.createElement("div");
|
|
1373
1410
|
grid.className = "canvas-ruler grid-overlay";
|
|
1411
|
+
const gridColor = getThemeValue(config, "gridColor");
|
|
1374
1412
|
grid.style.cssText = `
|
|
1375
1413
|
position: absolute;
|
|
1376
1414
|
top: ${config.rulerSize}px;
|
|
@@ -1380,8 +1418,8 @@ function createGridOverlay(config) {
|
|
|
1380
1418
|
pointer-events: none;
|
|
1381
1419
|
z-index: ${RULER_Z_INDEX.GRID};
|
|
1382
1420
|
background-image:
|
|
1383
|
-
linear-gradient(${
|
|
1384
|
-
linear-gradient(90deg, ${
|
|
1421
|
+
linear-gradient(${gridColor} 1px, transparent 1px),
|
|
1422
|
+
linear-gradient(90deg, ${gridColor} 1px, transparent 1px);
|
|
1385
1423
|
background-size: 100px 100px;
|
|
1386
1424
|
opacity: 0.5;
|
|
1387
1425
|
`;
|
|
@@ -1391,20 +1429,23 @@ function createGridOverlay(config) {
|
|
|
1391
1429
|
function createHorizontalRuler(config) {
|
|
1392
1430
|
const ruler = document.createElement("div");
|
|
1393
1431
|
ruler.className = "canvas-ruler horizontal-ruler";
|
|
1432
|
+
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1433
|
+
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1434
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1394
1435
|
ruler.style.cssText = `
|
|
1395
1436
|
position: absolute;
|
|
1396
1437
|
top: 0;
|
|
1397
1438
|
left: ${config.rulerSize}px;
|
|
1398
1439
|
right: 0;
|
|
1399
1440
|
height: ${config.rulerSize}px;
|
|
1400
|
-
background: ${
|
|
1401
|
-
border-bottom: 1px solid ${
|
|
1402
|
-
border-right: 1px solid ${
|
|
1441
|
+
background: ${backgroundColor};
|
|
1442
|
+
border-bottom: 1px solid ${borderColor};
|
|
1443
|
+
border-right: 1px solid ${borderColor};
|
|
1403
1444
|
z-index: ${RULER_Z_INDEX.RULERS};
|
|
1404
1445
|
pointer-events: none;
|
|
1405
1446
|
font-family: ${config.rulerFontFamily};
|
|
1406
1447
|
font-size: ${config.rulerFontSize}px;
|
|
1407
|
-
color: ${
|
|
1448
|
+
color: ${textColor};
|
|
1408
1449
|
overflow: hidden;
|
|
1409
1450
|
`;
|
|
1410
1451
|
return ruler;
|
|
@@ -1413,20 +1454,23 @@ function createHorizontalRuler(config) {
|
|
|
1413
1454
|
function createVerticalRuler(config) {
|
|
1414
1455
|
const ruler = document.createElement("div");
|
|
1415
1456
|
ruler.className = "canvas-ruler vertical-ruler";
|
|
1457
|
+
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1458
|
+
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1459
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1416
1460
|
ruler.style.cssText = `
|
|
1417
1461
|
position: absolute;
|
|
1418
1462
|
top: ${config.rulerSize}px;
|
|
1419
1463
|
left: 0;
|
|
1420
1464
|
bottom: 0;
|
|
1421
1465
|
width: ${config.rulerSize}px;
|
|
1422
|
-
background: ${
|
|
1423
|
-
border-right: 1px solid ${
|
|
1424
|
-
border-bottom: 1px solid ${
|
|
1466
|
+
background: ${backgroundColor};
|
|
1467
|
+
border-right: 1px solid ${borderColor};
|
|
1468
|
+
border-bottom: 1px solid ${borderColor};
|
|
1425
1469
|
z-index: ${RULER_Z_INDEX.RULERS};
|
|
1426
1470
|
pointer-events: none;
|
|
1427
1471
|
font-family: ${config.rulerFontFamily};
|
|
1428
1472
|
font-size: ${config.rulerFontSize}px;
|
|
1429
|
-
color: ${
|
|
1473
|
+
color: ${textColor};
|
|
1430
1474
|
overflow: hidden;
|
|
1431
1475
|
`;
|
|
1432
1476
|
return ruler;
|
|
@@ -1496,29 +1540,29 @@ function calculateTickSpacing(contentSize, canvasSize) {
|
|
|
1496
1540
|
return niceSpacing * magnitude;
|
|
1497
1541
|
}
|
|
1498
1542
|
|
|
1499
|
-
function createHorizontalTick(container, position, pixelPos,
|
|
1543
|
+
function createHorizontalTick(container, position, pixelPos, _tickSpacing, config) {
|
|
1500
1544
|
const tick = document.createElement("div");
|
|
1501
|
-
const
|
|
1502
|
-
const tickHeight = isMajor ? TICK_SETTINGS.MAJOR_HEIGHT : TICK_SETTINGS.MINOR_HEIGHT;
|
|
1545
|
+
const tickColor = getThemeValue(config, "rulerTickColor");
|
|
1503
1546
|
tick.style.cssText = `
|
|
1504
1547
|
position: absolute;
|
|
1505
1548
|
left: ${pixelPos}px;
|
|
1506
1549
|
bottom: 0;
|
|
1507
1550
|
width: 1px;
|
|
1508
|
-
height: ${
|
|
1509
|
-
background: ${
|
|
1551
|
+
height: ${TICK_SETTINGS.TICK_HEIGHT}px;
|
|
1552
|
+
background: ${tickColor};
|
|
1510
1553
|
`;
|
|
1511
1554
|
container.appendChild(tick);
|
|
1512
|
-
const shouldShowLabel =
|
|
1555
|
+
const shouldShowLabel = position % TICK_SETTINGS.TICK_LABEL_INTERVAL === 0;
|
|
1513
1556
|
if (shouldShowLabel) {
|
|
1514
1557
|
const label = document.createElement("div");
|
|
1558
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1515
1559
|
label.style.cssText = `
|
|
1516
1560
|
position: absolute;
|
|
1517
1561
|
left: ${pixelPos}px;
|
|
1518
|
-
bottom: ${
|
|
1562
|
+
bottom: ${TICK_SETTINGS.TICK_HEIGHT + 2}px;
|
|
1519
1563
|
font-size: ${config.rulerFontSize}px;
|
|
1520
1564
|
line-height: 1;
|
|
1521
|
-
color: ${
|
|
1565
|
+
color: ${textColor};
|
|
1522
1566
|
white-space: nowrap;
|
|
1523
1567
|
pointer-events: none;
|
|
1524
1568
|
`;
|
|
@@ -1544,29 +1588,29 @@ function updateHorizontalRuler(ruler, contentLeft, contentRight, canvasWidth, sc
|
|
|
1544
1588
|
ruler.appendChild(fragment);
|
|
1545
1589
|
}
|
|
1546
1590
|
|
|
1547
|
-
function createVerticalTick(container, position, pixelPos,
|
|
1591
|
+
function createVerticalTick(container, position, pixelPos, _tickSpacing, config) {
|
|
1548
1592
|
const tick = document.createElement("div");
|
|
1549
|
-
const
|
|
1550
|
-
const tickWidth = isMajor ? TICK_SETTINGS.MAJOR_WIDTH : TICK_SETTINGS.MINOR_WIDTH;
|
|
1593
|
+
const tickColor = getThemeValue(config, "rulerTickColor");
|
|
1551
1594
|
tick.style.cssText = `
|
|
1552
1595
|
position: absolute;
|
|
1553
1596
|
top: ${pixelPos}px;
|
|
1554
1597
|
right: 0;
|
|
1555
|
-
width: ${
|
|
1598
|
+
width: ${TICK_SETTINGS.TICK_WIDTH}px;
|
|
1556
1599
|
height: 1px;
|
|
1557
|
-
background: ${
|
|
1600
|
+
background: ${tickColor};
|
|
1558
1601
|
`;
|
|
1559
1602
|
container.appendChild(tick);
|
|
1560
|
-
const shouldShowLabel =
|
|
1603
|
+
const shouldShowLabel = position % TICK_SETTINGS.TICK_LABEL_INTERVAL === 0;
|
|
1561
1604
|
if (shouldShowLabel) {
|
|
1562
1605
|
const label = document.createElement("div");
|
|
1606
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1563
1607
|
label.style.cssText = `
|
|
1564
1608
|
position: absolute;
|
|
1565
1609
|
top: ${pixelPos - 6}px;
|
|
1566
|
-
right: ${
|
|
1610
|
+
right: ${TICK_SETTINGS.TICK_WIDTH + 6}px;
|
|
1567
1611
|
font-size: ${config.rulerFontSize}px;
|
|
1568
1612
|
line-height: 1;
|
|
1569
|
-
color: ${
|
|
1613
|
+
color: ${textColor};
|
|
1570
1614
|
white-space: nowrap;
|
|
1571
1615
|
pointer-events: none;
|
|
1572
1616
|
transform: rotate(-90deg);
|
|
@@ -1612,6 +1656,47 @@ function updateRulers(canvas, horizontalRuler, verticalRuler, gridOverlay, confi
|
|
|
1612
1656
|
}
|
|
1613
1657
|
}
|
|
1614
1658
|
|
|
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
|
+
function updateRulerTheme(elements, config) {
|
|
1665
|
+
// Get theme-aware colors
|
|
1666
|
+
const backgroundColor = getThemeValue(config, "rulerBackgroundColor");
|
|
1667
|
+
const borderColor = getThemeValue(config, "rulerBorderColor");
|
|
1668
|
+
const textColor = getThemeValue(config, "rulerTextColor");
|
|
1669
|
+
const gridColor = getThemeValue(config, "gridColor");
|
|
1670
|
+
// Update horizontal ruler
|
|
1671
|
+
if (elements.horizontalRuler) {
|
|
1672
|
+
elements.horizontalRuler.style.background = backgroundColor;
|
|
1673
|
+
elements.horizontalRuler.style.borderBottomColor = borderColor;
|
|
1674
|
+
elements.horizontalRuler.style.borderRightColor = borderColor;
|
|
1675
|
+
elements.horizontalRuler.style.color = textColor;
|
|
1676
|
+
}
|
|
1677
|
+
// Update vertical ruler
|
|
1678
|
+
if (elements.verticalRuler) {
|
|
1679
|
+
elements.verticalRuler.style.background = backgroundColor;
|
|
1680
|
+
elements.verticalRuler.style.borderRightColor = borderColor;
|
|
1681
|
+
elements.verticalRuler.style.borderBottomColor = borderColor;
|
|
1682
|
+
elements.verticalRuler.style.color = textColor;
|
|
1683
|
+
}
|
|
1684
|
+
// Update corner box
|
|
1685
|
+
if (elements.cornerBox) {
|
|
1686
|
+
elements.cornerBox.style.background = backgroundColor;
|
|
1687
|
+
elements.cornerBox.style.borderRightColor = borderColor;
|
|
1688
|
+
elements.cornerBox.style.borderBottomColor = borderColor;
|
|
1689
|
+
elements.cornerBox.style.color = textColor;
|
|
1690
|
+
}
|
|
1691
|
+
// Update grid overlay
|
|
1692
|
+
if (elements.gridOverlay) {
|
|
1693
|
+
elements.gridOverlay.style.backgroundImage = `
|
|
1694
|
+
linear-gradient(${gridColor} 1px, transparent 1px),
|
|
1695
|
+
linear-gradient(90deg, ${gridColor} 1px, transparent 1px)
|
|
1696
|
+
`;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1615
1700
|
function createRulers(canvas, config) {
|
|
1616
1701
|
if (!canvas?.container) {
|
|
1617
1702
|
console.error("Invalid canvas provided to createRulers");
|
|
@@ -1629,12 +1714,28 @@ function createRulers(canvas, config) {
|
|
|
1629
1714
|
elements = createRulerElements(canvas.container, config);
|
|
1630
1715
|
cleanupEvents = setupRulerEvents(canvas, safeUpdate);
|
|
1631
1716
|
safeUpdate();
|
|
1717
|
+
if (!config.showRulers) {
|
|
1718
|
+
elements.horizontalRuler.style.display = "none";
|
|
1719
|
+
elements.verticalRuler.style.display = "none";
|
|
1720
|
+
elements.cornerBox.style.display = "none";
|
|
1721
|
+
}
|
|
1722
|
+
if (!config.showGrid && elements.gridOverlay) {
|
|
1723
|
+
elements.gridOverlay.style.display = "none";
|
|
1724
|
+
}
|
|
1632
1725
|
return {
|
|
1633
1726
|
horizontalRuler: elements.horizontalRuler,
|
|
1634
1727
|
verticalRuler: elements.verticalRuler,
|
|
1635
1728
|
cornerBox: elements.cornerBox,
|
|
1636
1729
|
gridOverlay: elements.gridOverlay,
|
|
1637
1730
|
update: safeUpdate,
|
|
1731
|
+
updateTheme: (newConfig) => {
|
|
1732
|
+
if (isDestroyed)
|
|
1733
|
+
return;
|
|
1734
|
+
// Update all ruler theme colors
|
|
1735
|
+
updateRulerTheme(elements, newConfig);
|
|
1736
|
+
// Re-render rulers to update tick colors
|
|
1737
|
+
safeUpdate();
|
|
1738
|
+
},
|
|
1638
1739
|
show: () => {
|
|
1639
1740
|
if (elements.horizontalRuler)
|
|
1640
1741
|
elements.horizontalRuler.style.display = "block";
|
|
@@ -2002,6 +2103,21 @@ class MarkupCanvas {
|
|
|
2002
2103
|
updateConfig(newConfig) {
|
|
2003
2104
|
this.config = createMarkupCanvasConfig({ ...this.config, ...newConfig });
|
|
2004
2105
|
}
|
|
2106
|
+
// Theme management
|
|
2107
|
+
updateThemeMode(mode) {
|
|
2108
|
+
const newConfig = {
|
|
2109
|
+
...this.config,
|
|
2110
|
+
themeMode: mode,
|
|
2111
|
+
};
|
|
2112
|
+
this.config = createMarkupCanvasConfig(newConfig);
|
|
2113
|
+
// Update canvas background color
|
|
2114
|
+
const backgroundColor = getThemeValue(this.config, "canvasBackgroundColor");
|
|
2115
|
+
this.baseCanvas.container.style.backgroundColor = backgroundColor;
|
|
2116
|
+
// Update rulers if they exist
|
|
2117
|
+
if (this.rulers) {
|
|
2118
|
+
this.rulers.updateTheme(this.config);
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2005
2121
|
// Cleanup method
|
|
2006
2122
|
cleanup() {
|
|
2007
2123
|
this.cleanupFunctions.forEach((cleanup) => {
|