@markup-canvas/core 1.3.2 → 1.3.4

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Markup Canvas
3
3
  * High-performance markup canvas with zoom and pan capabilities
4
- * @version 1.3.2
4
+ * @version 1.3.4
5
5
  */
6
6
  const EDITOR_PRESET = {
7
7
  // Canvas dimensions
@@ -18,7 +18,7 @@ const EDITOR_PRESET = {
18
18
  enableKeyboard: true,
19
19
  bindKeyboardEventsTo: "document",
20
20
  // Zoom behavior
21
- zoomSpeed: 1.5,
21
+ zoomSpeed: 4,
22
22
  minZoom: 0.05,
23
23
  maxZoom: 80,
24
24
  enableTransition: false,
@@ -50,7 +50,7 @@ const EDITOR_PRESET = {
50
50
  canvasBackgroundColorDark: "transparent",
51
51
  // Ruler styling
52
52
  rulerBackgroundColor: "oklch(100% 0 0 / 0.96)",
53
- rulerBorderColor: "oklch(96.7% 0.001 286.375)",
53
+ rulerBorderColor: "oklch(0.322 0.0095 285.919)",
54
54
  rulerTextColor: "oklch(70.5% 0.015 286.067)",
55
55
  rulerTickColor: "oklch(92% 0.004 286.32)",
56
56
  gridColor: "rgba(232, 86, 193, 0.5)",
@@ -944,7 +944,8 @@ function getAdaptiveZoomSpeed(canvas, baseSpeed) {
944
944
  }
945
945
  }
946
946
 
947
- function setupKeyboardEvents(canvas, config) {
947
+ function setupKeyboardEvents(canvas, config, options) {
948
+ const textEditModeEnabled = options?.textEditModeEnabled ?? false;
948
949
  function handleKeyDown(event) {
949
950
  if (!(event instanceof KeyboardEvent))
950
951
  return;
@@ -954,23 +955,38 @@ function setupKeyboardEvents(canvas, config) {
954
955
  const newTransform = {};
955
956
  switch (event.key) {
956
957
  case "ArrowLeft":
958
+ if (textEditModeEnabled) {
959
+ return;
960
+ }
957
961
  newTransform.translateX = canvas.transform.translateX + config.keyboardPanStep;
958
962
  handled = true;
959
963
  break;
960
964
  case "ArrowRight":
965
+ if (textEditModeEnabled) {
966
+ return;
967
+ }
961
968
  newTransform.translateX = canvas.transform.translateX - config.keyboardPanStep;
962
969
  handled = true;
963
970
  break;
964
971
  case "ArrowUp":
972
+ if (textEditModeEnabled) {
973
+ return;
974
+ }
965
975
  newTransform.translateY = canvas.transform.translateY + config.keyboardPanStep;
966
976
  handled = true;
967
977
  break;
968
978
  case "ArrowDown":
979
+ if (textEditModeEnabled) {
980
+ return;
981
+ }
969
982
  newTransform.translateY = canvas.transform.translateY - config.keyboardPanStep;
970
983
  handled = true;
971
984
  break;
972
985
  case "=":
973
986
  case "+":
987
+ if (textEditModeEnabled) {
988
+ return;
989
+ }
974
990
  {
975
991
  const adaptiveZoomStep = config.enableAdaptiveSpeed
976
992
  ? getAdaptiveZoomSpeed(canvas, config.keyboardZoomStep)
@@ -980,6 +996,9 @@ function setupKeyboardEvents(canvas, config) {
980
996
  }
981
997
  break;
982
998
  case "-":
999
+ if (textEditModeEnabled) {
1000
+ return;
1001
+ }
983
1002
  {
984
1003
  const adaptiveZoomStep = config.enableAdaptiveSpeed
985
1004
  ? getAdaptiveZoomSpeed(canvas, config.keyboardZoomStep)
@@ -1326,117 +1345,125 @@ function sendPostMessageError(canvasName, action, error) {
1326
1345
  }, "*");
1327
1346
  }
1328
1347
 
1329
- function setupPostMessageEvents(canvas) {
1330
- const handleMessage = (event) => {
1331
- const data = event.data;
1332
- if (!["markup-canvas", "application"].includes(data.source)) {
1333
- return;
1334
- }
1335
- console.log("data", event.data);
1336
- const canvasName = canvas.config.name || "markupCanvas";
1337
- if (data.canvasName !== canvasName) {
1338
- console.log("canvasName", data.canvasName, "!==", canvasName);
1339
- return;
1340
- }
1341
- const action = data.action;
1342
- const payload = data.data;
1343
- try {
1344
- // View methods
1345
- if (action === "zoomIn") {
1346
- console.log("zoomIn", payload);
1348
+ function processPostMessage(canvas, action, payload, canvasName) {
1349
+ try {
1350
+ // View methods
1351
+ switch (action) {
1352
+ case "zoomIn":
1347
1353
  canvas.zoomIn(payload);
1348
- }
1349
- else if (action === "zoomOut") {
1354
+ break;
1355
+ case "zoomOut":
1350
1356
  canvas.zoomOut(payload);
1351
- }
1352
- else if (action === "setZoom") {
1357
+ break;
1358
+ case "setZoom": {
1353
1359
  const zoomLevel = payload;
1354
1360
  if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
1355
1361
  throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
1356
1362
  }
1357
1363
  canvas.setZoom(zoomLevel);
1364
+ break;
1358
1365
  }
1359
- else if (action === "resetZoom") {
1366
+ case "resetZoom":
1360
1367
  canvas.resetZoom();
1361
- }
1362
- else if (action === "panLeft") {
1368
+ break;
1369
+ case "panLeft":
1363
1370
  canvas.panLeft(payload);
1364
- }
1365
- else if (action === "panRight") {
1371
+ break;
1372
+ case "panRight":
1366
1373
  canvas.panRight(payload);
1367
- }
1368
- else if (action === "panUp") {
1374
+ break;
1375
+ case "panUp":
1369
1376
  canvas.panUp(payload);
1370
- }
1371
- else if (action === "panDown") {
1377
+ break;
1378
+ case "panDown":
1372
1379
  canvas.panDown(payload);
1373
- }
1374
- else if (action === "fitToScreen") {
1380
+ break;
1381
+ case "fitToScreen":
1375
1382
  canvas.fitToScreen();
1376
- }
1377
- else if (action === "centerContent") {
1383
+ break;
1384
+ case "centerContent":
1378
1385
  canvas.centerContent();
1386
+ break;
1387
+ case "panToPoint": {
1388
+ const point = payload;
1389
+ canvas.panToPoint(point.x, point.y);
1390
+ break;
1379
1391
  }
1380
- else if (action === "panToPoint") {
1381
- canvas.panToPoint(payload.x, payload.y);
1382
- }
1383
- else if (action === "resetView") {
1392
+ case "resetView":
1384
1393
  canvas.resetView();
1385
- }
1386
- else if (action === "resetViewToCenter") {
1394
+ break;
1395
+ case "resetViewToCenter":
1387
1396
  canvas.resetViewToCenter();
1388
- }
1397
+ break;
1389
1398
  // Ruler/Grid methods
1390
- else if (action === "toggleRulers") {
1399
+ case "toggleRulers":
1391
1400
  canvas.toggleRulers();
1392
- }
1393
- else if (action === "showRulers") {
1401
+ break;
1402
+ case "showRulers":
1394
1403
  canvas.showRulers();
1395
- }
1396
- else if (action === "hideRulers") {
1404
+ break;
1405
+ case "hideRulers":
1397
1406
  canvas.hideRulers();
1398
- }
1399
- else if (action === "toggleGrid") {
1407
+ break;
1408
+ case "toggleGrid":
1400
1409
  canvas.toggleGrid();
1401
- }
1402
- else if (action === "showGrid") {
1410
+ break;
1411
+ case "showGrid":
1403
1412
  canvas.showGrid();
1404
- }
1405
- else if (action === "hideGrid") {
1413
+ break;
1414
+ case "hideGrid":
1406
1415
  canvas.hideGrid();
1407
- }
1416
+ break;
1408
1417
  // Config methods
1409
- else if (action === "updateThemeMode") {
1418
+ case "updateThemeMode": {
1410
1419
  const mode = payload;
1411
1420
  if (mode !== "light" && mode !== "dark") {
1412
1421
  throw new Error(`Invalid theme mode: ${mode}`);
1413
1422
  }
1414
1423
  canvas.updateThemeMode(mode);
1424
+ break;
1415
1425
  }
1416
- else if (action === "toggleThemeMode") {
1426
+ case "toggleThemeMode": {
1417
1427
  const currentConfig = canvas.getConfig();
1418
1428
  const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
1419
1429
  canvas.updateThemeMode(newMode);
1430
+ break;
1420
1431
  }
1421
1432
  // Transition methods
1422
- else if (action === "updateTransition") {
1433
+ case "updateTransition": {
1423
1434
  const enabled = payload;
1424
1435
  if (typeof enabled !== "boolean") {
1425
1436
  throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
1426
1437
  }
1427
1438
  canvas.updateTransition(enabled);
1439
+ break;
1428
1440
  }
1429
- else if (action === "toggleTransitionMode") {
1441
+ case "toggleTransitionMode":
1430
1442
  canvas.toggleTransitionMode();
1431
- }
1432
- else {
1443
+ break;
1444
+ default:
1433
1445
  throw new Error(`Unknown action: ${action}`);
1434
- }
1435
1446
  }
1436
- catch (error) {
1437
- const errorMessage = error instanceof Error ? error.message : String(error);
1438
- sendPostMessageError(canvasName, action, errorMessage);
1447
+ }
1448
+ catch (error) {
1449
+ const errorMessage = error instanceof Error ? error.message : String(error);
1450
+ sendPostMessageError(canvasName, action, errorMessage);
1451
+ }
1452
+ }
1453
+
1454
+ function setupPostMessageEvents(canvas) {
1455
+ const handleMessage = (event) => {
1456
+ const data = event.data;
1457
+ if (!["markup-canvas", "application"].includes(data.source)) {
1458
+ return;
1439
1459
  }
1460
+ const canvasName = canvas.config.name || "markupCanvas";
1461
+ if (data.canvasName !== canvasName) {
1462
+ return;
1463
+ }
1464
+ const action = data.action;
1465
+ const payload = data.data;
1466
+ processPostMessage(canvas, action, payload, canvasName);
1440
1467
  };
1441
1468
  if (typeof window !== "undefined") {
1442
1469
  window.addEventListener("message", handleMessage);
@@ -1737,7 +1764,6 @@ function createHorizontalRuler(config) {
1737
1764
  height: ${config.rulerSize}px;
1738
1765
  background: var(--ruler-background-color);
1739
1766
  border-bottom: 1px solid var(--ruler-border-color);
1740
- border-right: 1px solid var(--ruler-border-color);
1741
1767
  z-index: ${RULER_Z_INDEX.RULERS};
1742
1768
  pointer-events: none;
1743
1769
  font-family: ${config.rulerFontFamily};
@@ -1759,7 +1785,6 @@ function createVerticalRuler(config) {
1759
1785
  width: ${config.rulerSize}px;
1760
1786
  background: var(--ruler-background-color);
1761
1787
  border-right: 1px solid var(--ruler-border-color);
1762
- border-bottom: 1px solid var(--ruler-border-color);
1763
1788
  z-index: ${RULER_Z_INDEX.RULERS};
1764
1789
  pointer-events: none;
1765
1790
  font-family: ${config.rulerFontFamily};
@@ -2161,6 +2186,9 @@ function bindCanvasToWindow(canvas, config) {
2161
2186
  enable: canvas.enableKeyboard.bind(canvas),
2162
2187
  disable: canvas.disableKeyboard.bind(canvas),
2163
2188
  isEnabled: canvas.isKeyboardEnabled.bind(canvas),
2189
+ enableTextEditMode: canvas.enableTextEditMode.bind(canvas),
2190
+ disableTextEditMode: canvas.disableTextEditMode.bind(canvas),
2191
+ isTextEditModeEnabled: canvas.isTextEditModeEnabled.bind(canvas),
2164
2192
  },
2165
2193
  // Grid group
2166
2194
  grid: {
@@ -2235,6 +2263,7 @@ class MarkupCanvas {
2235
2263
  this.rulers = null;
2236
2264
  this.dragSetup = null;
2237
2265
  this.keyboardCleanup = null;
2266
+ this.textEditModeEnabled = false;
2238
2267
  this.event = new EventEmitter();
2239
2268
  this._isReady = false;
2240
2269
  if (!container) {
@@ -2286,7 +2315,9 @@ class MarkupCanvas {
2286
2315
  }
2287
2316
  // Keyboard events
2288
2317
  withFeatureEnabled(this.config, "enableKeyboard", () => {
2289
- const keyboardCleanup = setupKeyboardEvents(this, this.config);
2318
+ const keyboardCleanup = setupKeyboardEvents(this, this.config, {
2319
+ textEditModeEnabled: this.textEditModeEnabled,
2320
+ });
2290
2321
  this.keyboardCleanup = keyboardCleanup;
2291
2322
  this.cleanupCallbacks.push(keyboardCleanup);
2292
2323
  });
@@ -2400,7 +2431,9 @@ class MarkupCanvas {
2400
2431
  if (this.keyboardCleanup) {
2401
2432
  return true; // Already enabled
2402
2433
  }
2403
- this.keyboardCleanup = setupKeyboardEvents(this, this.config);
2434
+ this.keyboardCleanup = setupKeyboardEvents(this, this.config, {
2435
+ textEditModeEnabled: this.textEditModeEnabled,
2436
+ });
2404
2437
  this.cleanupCallbacks.push(this.keyboardCleanup);
2405
2438
  return true;
2406
2439
  }
@@ -2415,6 +2448,54 @@ class MarkupCanvas {
2415
2448
  isKeyboardEnabled() {
2416
2449
  return this.keyboardCleanup !== null;
2417
2450
  }
2451
+ // Text edit mode control methods
2452
+ enableTextEditMode() {
2453
+ if (this.textEditModeEnabled) {
2454
+ return true; // Already enabled
2455
+ }
2456
+ this.textEditModeEnabled = true;
2457
+ // If keyboard is currently enabled, re-setup with new option
2458
+ if (this.keyboardCleanup) {
2459
+ // Remove old cleanup from callbacks
2460
+ const index = this.cleanupCallbacks.indexOf(this.keyboardCleanup);
2461
+ if (index > -1) {
2462
+ this.cleanupCallbacks.splice(index, 1);
2463
+ }
2464
+ // Cleanup old handler
2465
+ this.keyboardCleanup();
2466
+ // Setup new handler with text edit mode enabled
2467
+ this.keyboardCleanup = setupKeyboardEvents(this, this.config, {
2468
+ textEditModeEnabled: true,
2469
+ });
2470
+ this.cleanupCallbacks.push(this.keyboardCleanup);
2471
+ }
2472
+ return true;
2473
+ }
2474
+ disableTextEditMode() {
2475
+ if (!this.textEditModeEnabled) {
2476
+ return true; // Already disabled
2477
+ }
2478
+ this.textEditModeEnabled = false;
2479
+ // If keyboard is currently enabled, re-setup with new option
2480
+ if (this.keyboardCleanup) {
2481
+ // Remove old cleanup from callbacks
2482
+ const index = this.cleanupCallbacks.indexOf(this.keyboardCleanup);
2483
+ if (index > -1) {
2484
+ this.cleanupCallbacks.splice(index, 1);
2485
+ }
2486
+ // Cleanup old handler
2487
+ this.keyboardCleanup();
2488
+ // Setup new handler with text edit mode disabled
2489
+ this.keyboardCleanup = setupKeyboardEvents(this, this.config, {
2490
+ textEditModeEnabled: false,
2491
+ });
2492
+ this.cleanupCallbacks.push(this.keyboardCleanup);
2493
+ }
2494
+ return true;
2495
+ }
2496
+ isTextEditModeEnabled() {
2497
+ return this.textEditModeEnabled;
2498
+ }
2418
2499
  toggleGrid() {
2419
2500
  const result = toggleGrid(this.rulers);
2420
2501
  if (result) {