@markup-canvas/core 1.3.1 → 1.3.3
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/events/postMessage/processPostMessages.d.ts +3 -0
- package/dist/markup-canvas.cjs.js +73 -62
- package/dist/markup-canvas.esm.js +73 -62
- package/dist/markup-canvas.umd.js +73 -62
- package/dist/markup-canvas.umd.min.js +1 -1
- package/package.json +1 -1
- package/src/lib/events/postMessage/processPostMessages.ts +113 -0
- package/src/lib/events/postMessage/setupPostMessageEvents.ts +4 -78
- /package/dist/lib/events/postMessage/{sendError.d.ts → sendPostMessageError.d.ts} +0 -0
- /package/src/lib/events/postMessage/{sendError.ts → sendPostMessageError.ts} +0 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { MarkupCanvas } from "@/lib/MarkupCanvas.js";
|
|
2
|
+
import type { PostMessageAction } from "@/types/events";
|
|
3
|
+
export declare function processPostMessage(canvas: MarkupCanvas, action: PostMessageAction, payload: string | number | boolean | object, canvasName: string): 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.3.
|
|
4
|
+
* @version 1.3.3
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
@@ -1330,114 +1330,125 @@ function sendPostMessageError(canvasName, action, error) {
|
|
|
1330
1330
|
}, "*");
|
|
1331
1331
|
}
|
|
1332
1332
|
|
|
1333
|
-
function
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
}
|
|
1339
|
-
const canvasName = canvas.config.name || "markupCanvas";
|
|
1340
|
-
if (data.canvasName !== canvasName) {
|
|
1341
|
-
return;
|
|
1342
|
-
}
|
|
1343
|
-
const action = data.action;
|
|
1344
|
-
const payload = data.data;
|
|
1345
|
-
try {
|
|
1346
|
-
// View methods
|
|
1347
|
-
if (action === "zoomIn") {
|
|
1333
|
+
function processPostMessage(canvas, action, payload, canvasName) {
|
|
1334
|
+
try {
|
|
1335
|
+
// View methods
|
|
1336
|
+
switch (action) {
|
|
1337
|
+
case "zoomIn":
|
|
1348
1338
|
canvas.zoomIn(payload);
|
|
1349
|
-
|
|
1350
|
-
|
|
1339
|
+
break;
|
|
1340
|
+
case "zoomOut":
|
|
1351
1341
|
canvas.zoomOut(payload);
|
|
1352
|
-
|
|
1353
|
-
|
|
1342
|
+
break;
|
|
1343
|
+
case "setZoom": {
|
|
1354
1344
|
const zoomLevel = payload;
|
|
1355
1345
|
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
1356
1346
|
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
1357
1347
|
}
|
|
1358
1348
|
canvas.setZoom(zoomLevel);
|
|
1349
|
+
break;
|
|
1359
1350
|
}
|
|
1360
|
-
|
|
1351
|
+
case "resetZoom":
|
|
1361
1352
|
canvas.resetZoom();
|
|
1362
|
-
|
|
1363
|
-
|
|
1353
|
+
break;
|
|
1354
|
+
case "panLeft":
|
|
1364
1355
|
canvas.panLeft(payload);
|
|
1365
|
-
|
|
1366
|
-
|
|
1356
|
+
break;
|
|
1357
|
+
case "panRight":
|
|
1367
1358
|
canvas.panRight(payload);
|
|
1368
|
-
|
|
1369
|
-
|
|
1359
|
+
break;
|
|
1360
|
+
case "panUp":
|
|
1370
1361
|
canvas.panUp(payload);
|
|
1371
|
-
|
|
1372
|
-
|
|
1362
|
+
break;
|
|
1363
|
+
case "panDown":
|
|
1373
1364
|
canvas.panDown(payload);
|
|
1374
|
-
|
|
1375
|
-
|
|
1365
|
+
break;
|
|
1366
|
+
case "fitToScreen":
|
|
1376
1367
|
canvas.fitToScreen();
|
|
1377
|
-
|
|
1378
|
-
|
|
1368
|
+
break;
|
|
1369
|
+
case "centerContent":
|
|
1379
1370
|
canvas.centerContent();
|
|
1371
|
+
break;
|
|
1372
|
+
case "panToPoint": {
|
|
1373
|
+
const point = payload;
|
|
1374
|
+
canvas.panToPoint(point.x, point.y);
|
|
1375
|
+
break;
|
|
1380
1376
|
}
|
|
1381
|
-
|
|
1382
|
-
canvas.panToPoint(payload.x, payload.y);
|
|
1383
|
-
}
|
|
1384
|
-
else if (action === "resetView") {
|
|
1377
|
+
case "resetView":
|
|
1385
1378
|
canvas.resetView();
|
|
1386
|
-
|
|
1387
|
-
|
|
1379
|
+
break;
|
|
1380
|
+
case "resetViewToCenter":
|
|
1388
1381
|
canvas.resetViewToCenter();
|
|
1389
|
-
|
|
1382
|
+
break;
|
|
1390
1383
|
// Ruler/Grid methods
|
|
1391
|
-
|
|
1384
|
+
case "toggleRulers":
|
|
1392
1385
|
canvas.toggleRulers();
|
|
1393
|
-
|
|
1394
|
-
|
|
1386
|
+
break;
|
|
1387
|
+
case "showRulers":
|
|
1395
1388
|
canvas.showRulers();
|
|
1396
|
-
|
|
1397
|
-
|
|
1389
|
+
break;
|
|
1390
|
+
case "hideRulers":
|
|
1398
1391
|
canvas.hideRulers();
|
|
1399
|
-
|
|
1400
|
-
|
|
1392
|
+
break;
|
|
1393
|
+
case "toggleGrid":
|
|
1401
1394
|
canvas.toggleGrid();
|
|
1402
|
-
|
|
1403
|
-
|
|
1395
|
+
break;
|
|
1396
|
+
case "showGrid":
|
|
1404
1397
|
canvas.showGrid();
|
|
1405
|
-
|
|
1406
|
-
|
|
1398
|
+
break;
|
|
1399
|
+
case "hideGrid":
|
|
1407
1400
|
canvas.hideGrid();
|
|
1408
|
-
|
|
1401
|
+
break;
|
|
1409
1402
|
// Config methods
|
|
1410
|
-
|
|
1403
|
+
case "updateThemeMode": {
|
|
1411
1404
|
const mode = payload;
|
|
1412
1405
|
if (mode !== "light" && mode !== "dark") {
|
|
1413
1406
|
throw new Error(`Invalid theme mode: ${mode}`);
|
|
1414
1407
|
}
|
|
1415
1408
|
canvas.updateThemeMode(mode);
|
|
1409
|
+
break;
|
|
1416
1410
|
}
|
|
1417
|
-
|
|
1411
|
+
case "toggleThemeMode": {
|
|
1418
1412
|
const currentConfig = canvas.getConfig();
|
|
1419
1413
|
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
1420
1414
|
canvas.updateThemeMode(newMode);
|
|
1415
|
+
break;
|
|
1421
1416
|
}
|
|
1422
1417
|
// Transition methods
|
|
1423
|
-
|
|
1418
|
+
case "updateTransition": {
|
|
1424
1419
|
const enabled = payload;
|
|
1425
1420
|
if (typeof enabled !== "boolean") {
|
|
1426
1421
|
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
1427
1422
|
}
|
|
1428
1423
|
canvas.updateTransition(enabled);
|
|
1424
|
+
break;
|
|
1429
1425
|
}
|
|
1430
|
-
|
|
1426
|
+
case "toggleTransitionMode":
|
|
1431
1427
|
canvas.toggleTransitionMode();
|
|
1432
|
-
|
|
1433
|
-
|
|
1428
|
+
break;
|
|
1429
|
+
default:
|
|
1434
1430
|
throw new Error(`Unknown action: ${action}`);
|
|
1435
|
-
}
|
|
1436
1431
|
}
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1432
|
+
}
|
|
1433
|
+
catch (error) {
|
|
1434
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1435
|
+
sendPostMessageError(canvasName, action, errorMessage);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
function setupPostMessageEvents(canvas) {
|
|
1440
|
+
const handleMessage = (event) => {
|
|
1441
|
+
const data = event.data;
|
|
1442
|
+
if (!["markup-canvas", "application"].includes(data.source)) {
|
|
1443
|
+
return;
|
|
1440
1444
|
}
|
|
1445
|
+
const canvasName = canvas.config.name || "markupCanvas";
|
|
1446
|
+
if (data.canvasName !== canvasName) {
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
const action = data.action;
|
|
1450
|
+
const payload = data.data;
|
|
1451
|
+
processPostMessage(canvas, action, payload, canvasName);
|
|
1441
1452
|
};
|
|
1442
1453
|
if (typeof window !== "undefined") {
|
|
1443
1454
|
window.addEventListener("message", handleMessage);
|
|
@@ -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.
|
|
4
|
+
* @version 1.3.3
|
|
5
5
|
*/
|
|
6
6
|
const EDITOR_PRESET = {
|
|
7
7
|
// Canvas dimensions
|
|
@@ -1326,114 +1326,125 @@ function sendPostMessageError(canvasName, action, error) {
|
|
|
1326
1326
|
}, "*");
|
|
1327
1327
|
}
|
|
1328
1328
|
|
|
1329
|
-
function
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
}
|
|
1335
|
-
const canvasName = canvas.config.name || "markupCanvas";
|
|
1336
|
-
if (data.canvasName !== canvasName) {
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
|
-
const action = data.action;
|
|
1340
|
-
const payload = data.data;
|
|
1341
|
-
try {
|
|
1342
|
-
// View methods
|
|
1343
|
-
if (action === "zoomIn") {
|
|
1329
|
+
function processPostMessage(canvas, action, payload, canvasName) {
|
|
1330
|
+
try {
|
|
1331
|
+
// View methods
|
|
1332
|
+
switch (action) {
|
|
1333
|
+
case "zoomIn":
|
|
1344
1334
|
canvas.zoomIn(payload);
|
|
1345
|
-
|
|
1346
|
-
|
|
1335
|
+
break;
|
|
1336
|
+
case "zoomOut":
|
|
1347
1337
|
canvas.zoomOut(payload);
|
|
1348
|
-
|
|
1349
|
-
|
|
1338
|
+
break;
|
|
1339
|
+
case "setZoom": {
|
|
1350
1340
|
const zoomLevel = payload;
|
|
1351
1341
|
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
1352
1342
|
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
1353
1343
|
}
|
|
1354
1344
|
canvas.setZoom(zoomLevel);
|
|
1345
|
+
break;
|
|
1355
1346
|
}
|
|
1356
|
-
|
|
1347
|
+
case "resetZoom":
|
|
1357
1348
|
canvas.resetZoom();
|
|
1358
|
-
|
|
1359
|
-
|
|
1349
|
+
break;
|
|
1350
|
+
case "panLeft":
|
|
1360
1351
|
canvas.panLeft(payload);
|
|
1361
|
-
|
|
1362
|
-
|
|
1352
|
+
break;
|
|
1353
|
+
case "panRight":
|
|
1363
1354
|
canvas.panRight(payload);
|
|
1364
|
-
|
|
1365
|
-
|
|
1355
|
+
break;
|
|
1356
|
+
case "panUp":
|
|
1366
1357
|
canvas.panUp(payload);
|
|
1367
|
-
|
|
1368
|
-
|
|
1358
|
+
break;
|
|
1359
|
+
case "panDown":
|
|
1369
1360
|
canvas.panDown(payload);
|
|
1370
|
-
|
|
1371
|
-
|
|
1361
|
+
break;
|
|
1362
|
+
case "fitToScreen":
|
|
1372
1363
|
canvas.fitToScreen();
|
|
1373
|
-
|
|
1374
|
-
|
|
1364
|
+
break;
|
|
1365
|
+
case "centerContent":
|
|
1375
1366
|
canvas.centerContent();
|
|
1367
|
+
break;
|
|
1368
|
+
case "panToPoint": {
|
|
1369
|
+
const point = payload;
|
|
1370
|
+
canvas.panToPoint(point.x, point.y);
|
|
1371
|
+
break;
|
|
1376
1372
|
}
|
|
1377
|
-
|
|
1378
|
-
canvas.panToPoint(payload.x, payload.y);
|
|
1379
|
-
}
|
|
1380
|
-
else if (action === "resetView") {
|
|
1373
|
+
case "resetView":
|
|
1381
1374
|
canvas.resetView();
|
|
1382
|
-
|
|
1383
|
-
|
|
1375
|
+
break;
|
|
1376
|
+
case "resetViewToCenter":
|
|
1384
1377
|
canvas.resetViewToCenter();
|
|
1385
|
-
|
|
1378
|
+
break;
|
|
1386
1379
|
// Ruler/Grid methods
|
|
1387
|
-
|
|
1380
|
+
case "toggleRulers":
|
|
1388
1381
|
canvas.toggleRulers();
|
|
1389
|
-
|
|
1390
|
-
|
|
1382
|
+
break;
|
|
1383
|
+
case "showRulers":
|
|
1391
1384
|
canvas.showRulers();
|
|
1392
|
-
|
|
1393
|
-
|
|
1385
|
+
break;
|
|
1386
|
+
case "hideRulers":
|
|
1394
1387
|
canvas.hideRulers();
|
|
1395
|
-
|
|
1396
|
-
|
|
1388
|
+
break;
|
|
1389
|
+
case "toggleGrid":
|
|
1397
1390
|
canvas.toggleGrid();
|
|
1398
|
-
|
|
1399
|
-
|
|
1391
|
+
break;
|
|
1392
|
+
case "showGrid":
|
|
1400
1393
|
canvas.showGrid();
|
|
1401
|
-
|
|
1402
|
-
|
|
1394
|
+
break;
|
|
1395
|
+
case "hideGrid":
|
|
1403
1396
|
canvas.hideGrid();
|
|
1404
|
-
|
|
1397
|
+
break;
|
|
1405
1398
|
// Config methods
|
|
1406
|
-
|
|
1399
|
+
case "updateThemeMode": {
|
|
1407
1400
|
const mode = payload;
|
|
1408
1401
|
if (mode !== "light" && mode !== "dark") {
|
|
1409
1402
|
throw new Error(`Invalid theme mode: ${mode}`);
|
|
1410
1403
|
}
|
|
1411
1404
|
canvas.updateThemeMode(mode);
|
|
1405
|
+
break;
|
|
1412
1406
|
}
|
|
1413
|
-
|
|
1407
|
+
case "toggleThemeMode": {
|
|
1414
1408
|
const currentConfig = canvas.getConfig();
|
|
1415
1409
|
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
1416
1410
|
canvas.updateThemeMode(newMode);
|
|
1411
|
+
break;
|
|
1417
1412
|
}
|
|
1418
1413
|
// Transition methods
|
|
1419
|
-
|
|
1414
|
+
case "updateTransition": {
|
|
1420
1415
|
const enabled = payload;
|
|
1421
1416
|
if (typeof enabled !== "boolean") {
|
|
1422
1417
|
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
1423
1418
|
}
|
|
1424
1419
|
canvas.updateTransition(enabled);
|
|
1420
|
+
break;
|
|
1425
1421
|
}
|
|
1426
|
-
|
|
1422
|
+
case "toggleTransitionMode":
|
|
1427
1423
|
canvas.toggleTransitionMode();
|
|
1428
|
-
|
|
1429
|
-
|
|
1424
|
+
break;
|
|
1425
|
+
default:
|
|
1430
1426
|
throw new Error(`Unknown action: ${action}`);
|
|
1431
|
-
}
|
|
1432
1427
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1428
|
+
}
|
|
1429
|
+
catch (error) {
|
|
1430
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1431
|
+
sendPostMessageError(canvasName, action, errorMessage);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
function setupPostMessageEvents(canvas) {
|
|
1436
|
+
const handleMessage = (event) => {
|
|
1437
|
+
const data = event.data;
|
|
1438
|
+
if (!["markup-canvas", "application"].includes(data.source)) {
|
|
1439
|
+
return;
|
|
1436
1440
|
}
|
|
1441
|
+
const canvasName = canvas.config.name || "markupCanvas";
|
|
1442
|
+
if (data.canvasName !== canvasName) {
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1445
|
+
const action = data.action;
|
|
1446
|
+
const payload = data.data;
|
|
1447
|
+
processPostMessage(canvas, action, payload, canvasName);
|
|
1437
1448
|
};
|
|
1438
1449
|
if (typeof window !== "undefined") {
|
|
1439
1450
|
window.addEventListener("message", handleMessage);
|
|
@@ -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.
|
|
4
|
+
* @version 1.3.3
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
7
7
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
@@ -1271,114 +1271,125 @@
|
|
|
1271
1271
|
}, "*");
|
|
1272
1272
|
}
|
|
1273
1273
|
|
|
1274
|
-
function
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
}
|
|
1280
|
-
const canvasName = canvas.config.name || "markupCanvas";
|
|
1281
|
-
if (data.canvasName !== canvasName) {
|
|
1282
|
-
return;
|
|
1283
|
-
}
|
|
1284
|
-
const action = data.action;
|
|
1285
|
-
const payload = data.data;
|
|
1286
|
-
try {
|
|
1287
|
-
// View methods
|
|
1288
|
-
if (action === "zoomIn") {
|
|
1274
|
+
function processPostMessage(canvas, action, payload, canvasName) {
|
|
1275
|
+
try {
|
|
1276
|
+
// View methods
|
|
1277
|
+
switch (action) {
|
|
1278
|
+
case "zoomIn":
|
|
1289
1279
|
canvas.zoomIn(payload);
|
|
1290
|
-
|
|
1291
|
-
|
|
1280
|
+
break;
|
|
1281
|
+
case "zoomOut":
|
|
1292
1282
|
canvas.zoomOut(payload);
|
|
1293
|
-
|
|
1294
|
-
|
|
1283
|
+
break;
|
|
1284
|
+
case "setZoom": {
|
|
1295
1285
|
const zoomLevel = payload;
|
|
1296
1286
|
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
1297
1287
|
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
1298
1288
|
}
|
|
1299
1289
|
canvas.setZoom(zoomLevel);
|
|
1290
|
+
break;
|
|
1300
1291
|
}
|
|
1301
|
-
|
|
1292
|
+
case "resetZoom":
|
|
1302
1293
|
canvas.resetZoom();
|
|
1303
|
-
|
|
1304
|
-
|
|
1294
|
+
break;
|
|
1295
|
+
case "panLeft":
|
|
1305
1296
|
canvas.panLeft(payload);
|
|
1306
|
-
|
|
1307
|
-
|
|
1297
|
+
break;
|
|
1298
|
+
case "panRight":
|
|
1308
1299
|
canvas.panRight(payload);
|
|
1309
|
-
|
|
1310
|
-
|
|
1300
|
+
break;
|
|
1301
|
+
case "panUp":
|
|
1311
1302
|
canvas.panUp(payload);
|
|
1312
|
-
|
|
1313
|
-
|
|
1303
|
+
break;
|
|
1304
|
+
case "panDown":
|
|
1314
1305
|
canvas.panDown(payload);
|
|
1315
|
-
|
|
1316
|
-
|
|
1306
|
+
break;
|
|
1307
|
+
case "fitToScreen":
|
|
1317
1308
|
canvas.fitToScreen();
|
|
1318
|
-
|
|
1319
|
-
|
|
1309
|
+
break;
|
|
1310
|
+
case "centerContent":
|
|
1320
1311
|
canvas.centerContent();
|
|
1312
|
+
break;
|
|
1313
|
+
case "panToPoint": {
|
|
1314
|
+
const point = payload;
|
|
1315
|
+
canvas.panToPoint(point.x, point.y);
|
|
1316
|
+
break;
|
|
1321
1317
|
}
|
|
1322
|
-
|
|
1323
|
-
canvas.panToPoint(payload.x, payload.y);
|
|
1324
|
-
}
|
|
1325
|
-
else if (action === "resetView") {
|
|
1318
|
+
case "resetView":
|
|
1326
1319
|
canvas.resetView();
|
|
1327
|
-
|
|
1328
|
-
|
|
1320
|
+
break;
|
|
1321
|
+
case "resetViewToCenter":
|
|
1329
1322
|
canvas.resetViewToCenter();
|
|
1330
|
-
|
|
1323
|
+
break;
|
|
1331
1324
|
// Ruler/Grid methods
|
|
1332
|
-
|
|
1325
|
+
case "toggleRulers":
|
|
1333
1326
|
canvas.toggleRulers();
|
|
1334
|
-
|
|
1335
|
-
|
|
1327
|
+
break;
|
|
1328
|
+
case "showRulers":
|
|
1336
1329
|
canvas.showRulers();
|
|
1337
|
-
|
|
1338
|
-
|
|
1330
|
+
break;
|
|
1331
|
+
case "hideRulers":
|
|
1339
1332
|
canvas.hideRulers();
|
|
1340
|
-
|
|
1341
|
-
|
|
1333
|
+
break;
|
|
1334
|
+
case "toggleGrid":
|
|
1342
1335
|
canvas.toggleGrid();
|
|
1343
|
-
|
|
1344
|
-
|
|
1336
|
+
break;
|
|
1337
|
+
case "showGrid":
|
|
1345
1338
|
canvas.showGrid();
|
|
1346
|
-
|
|
1347
|
-
|
|
1339
|
+
break;
|
|
1340
|
+
case "hideGrid":
|
|
1348
1341
|
canvas.hideGrid();
|
|
1349
|
-
|
|
1342
|
+
break;
|
|
1350
1343
|
// Config methods
|
|
1351
|
-
|
|
1344
|
+
case "updateThemeMode": {
|
|
1352
1345
|
const mode = payload;
|
|
1353
1346
|
if (mode !== "light" && mode !== "dark") {
|
|
1354
1347
|
throw new Error(`Invalid theme mode: ${mode}`);
|
|
1355
1348
|
}
|
|
1356
1349
|
canvas.updateThemeMode(mode);
|
|
1350
|
+
break;
|
|
1357
1351
|
}
|
|
1358
|
-
|
|
1352
|
+
case "toggleThemeMode": {
|
|
1359
1353
|
const currentConfig = canvas.getConfig();
|
|
1360
1354
|
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
1361
1355
|
canvas.updateThemeMode(newMode);
|
|
1356
|
+
break;
|
|
1362
1357
|
}
|
|
1363
1358
|
// Transition methods
|
|
1364
|
-
|
|
1359
|
+
case "updateTransition": {
|
|
1365
1360
|
const enabled = payload;
|
|
1366
1361
|
if (typeof enabled !== "boolean") {
|
|
1367
1362
|
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
1368
1363
|
}
|
|
1369
1364
|
canvas.updateTransition(enabled);
|
|
1365
|
+
break;
|
|
1370
1366
|
}
|
|
1371
|
-
|
|
1367
|
+
case "toggleTransitionMode":
|
|
1372
1368
|
canvas.toggleTransitionMode();
|
|
1373
|
-
|
|
1374
|
-
|
|
1369
|
+
break;
|
|
1370
|
+
default:
|
|
1375
1371
|
throw new Error(`Unknown action: ${action}`);
|
|
1376
|
-
}
|
|
1377
1372
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1373
|
+
}
|
|
1374
|
+
catch (error) {
|
|
1375
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1376
|
+
sendPostMessageError(canvasName, action, errorMessage);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
function setupPostMessageEvents(canvas) {
|
|
1381
|
+
const handleMessage = (event) => {
|
|
1382
|
+
const data = event.data;
|
|
1383
|
+
if (!["markup-canvas", "application"].includes(data.source)) {
|
|
1384
|
+
return;
|
|
1381
1385
|
}
|
|
1386
|
+
const canvasName = canvas.config.name || "markupCanvas";
|
|
1387
|
+
if (data.canvasName !== canvasName) {
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
const action = data.action;
|
|
1391
|
+
const payload = data.data;
|
|
1392
|
+
processPostMessage(canvas, action, payload, canvasName);
|
|
1382
1393
|
};
|
|
1383
1394
|
if (typeof window !== "undefined") {
|
|
1384
1395
|
window.addEventListener("message", handleMessage);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas=t()}(this,function(){"use strict";function e(e,t,n){if(!n?.inverse)return{x:e,y:t};try{const r=n.inverse(),o=new DOMPoint(e,t).matrixTransform(r);return{x:o.x,y:o.y}}catch(n){return console.warn("Canvas to content conversion failed:",n),{x:e,y:t}}}function t(e,t){return Math.max(t.minZoom,Math.min(t.maxZoom,e))}function n(e,t,n){return new DOMMatrix([e,0,0,e,t,n])}const r="canvas-container",o="transform-layer",a="content-layer";function i(e,n,r,o,a){const i=a.enableRulers?-a.rulerSize:0,s=r||{scale:1,translateX:i,translateY:i},{scale:l,translateX:c,translateY:u}=s,d=t(l*o,a);if(Math.abs(d-l)<.001)return{scale:l,translateX:c,translateY:u};return{scale:d,translateX:e-(e-c)/l*d,translateY:n-(n-u)/l*d}}function s(e){return e.getBounds().visibleArea}function l(e,n){return n(n=>t(n,e))}const c=new Map;function u(e,t,n){return e[t]?n():null}function d(e){let t=null,n=null;const r=(...r)=>{n=r,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return r.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},r}function h(e,t,n){return n(null!==e.container.querySelector(".canvas-ruler")?t:0)}function g(e,t,n,r,o){const a=null!==e.container.querySelector(".canvas-ruler");return o(a?t-r:t,a?n-r:n)}function m(e,t){if("dark"===e.themeMode){return e[`${t}Dark`]}return e[t]}const f={width:8e3,height:8e3,enableAcceleration:!0,initialZoom:1,initialPan:{x:0,y:0},name:"markupCanvas",enablePostMessageAPI:!1,enableZoom:!0,enablePan:!0,enableTouch:!0,enableKeyboard:!0,bindKeyboardEventsTo:"document",zoomSpeed:1.5,minZoom:.05,maxZoom:80,enableTransition:!0,transitionDuration:.2,enableAdaptiveSpeed:!0,enableLeftDrag:!0,enableMiddleDrag:!0,requireSpaceForMouseDrag:!1,keyboardPanStep:50,keyboardFastMultiplier:20,keyboardZoomStep:.2,enableClickToZoom:!0,clickZoomLevel:1,requireOptionForClickZoom:!1,enableRulers:!0,enableGrid:!1,showRulers:!0,showGrid:!1,rulerFontSize:9,rulerFontFamily:"Monaco, Menlo, monospace",rulerUnits:"px",rulerSize:20,canvasBackgroundColor:"rgba(250, 250, 250, 1)",canvasBackgroundColorDark:"rgba(40, 40, 40, 1)",rulerBackgroundColor:"rgba(255, 255, 255, 0.95)",rulerBorderColor:"rgba(240, 240, 240, 1)",rulerTextColor:"rgba(102, 102, 102, 1)",rulerTickColor:"rgba(204, 204, 204, 1)",gridColor:"rgba(232, 86, 193, 0.5)",rulerBackgroundColorDark:"rgba(30, 30, 30, 0.95)",rulerBorderColorDark:"rgba(68, 68, 68, 1)",rulerTextColorDark:"rgba(170, 170, 170, 1)",rulerTickColorDark:"rgba(104, 104, 104, 1)",gridColorDark:"rgba(232, 86, 193, 0.5)",themeMode:"light"};function p(t,r){try{const o=t.container,a=t.transform||{scale:1,translateX:0,translateY:0},i=o.getBoundingClientRect(),s=i.width||o.clientWidth||0,l=i.height||o.clientHeight||0,c=h({container:o},r.rulerSize,e=>Math.max(0,s-e)),u=h({container:o},r.rulerSize,e=>Math.max(0,l-e)),d=r.width||f.width,g=r.height||f.height,m=function(t,r,o,a,i){const s=e(0,0,n(i.scale,i.translateX,i.translateY)),l=e(t,r,n(i.scale,i.translateX,i.translateY));return{x:Math.max(0,Math.min(o,s.x)),y:Math.max(0,Math.min(a,s.y)),width:Math.max(0,Math.min(o-s.x,l.x-s.x)),height:Math.max(0,Math.min(a-s.y,l.y-s.y))}}(c,u,d,g,a);return{width:c,height:u,contentWidth:d,contentHeight:g,scale:a.scale,translateX:a.translateX,translateY:a.translateY,visibleArea:m,scaledContentWidth:d*a.scale,scaledContentHeight:g*a.scale,canPanLeft:a.translateX<0,canPanRight:a.translateX+d*a.scale>c,canPanUp:a.translateY<0,canPanDown:a.translateY+g*a.scale>u,canZoomIn:a.scale<3.5,canZoomOut:a.scale>.1}}catch(e){return console.error("Failed to calculate canvas bounds:",e),{width:0,height:0,contentWidth:0,contentHeight:0,scale:1,translateX:0,translateY:0,visibleArea:{x:0,y:0,width:0,height:0},scaledContentWidth:0,scaledContentHeight:0,canPanLeft:!1,canPanRight:!1,canPanUp:!1,canPanDown:!1,canZoomIn:!1,canZoomOut:!1}}}function b(e,t){try{if(t.enableTransition){window.__markupCanvasTransitionTimeout&&(clearTimeout(window.__markupCanvasTransitionTimeout),window.__markupCanvasTransitionTimeout=void 0);return function(e,t,n){const r=c.get(e);r&&clearTimeout(r);const o=window.setTimeout(()=>{n(),c.delete(e)},t);c.set(e,o)}("disableTransition",1e3*(t.transitionDuration??.2),()=>{e.style.transition="none",window.__markupCanvasTransitionTimeout=void 0}),!0}return!1}catch(e){return console.error("Failed to disable transitions:",e),!0}}function y(e,t,n){!function(e,t){try{return!!t.enableTransition&&(window.__markupCanvasTransitionTimeout&&(clearTimeout(window.__markupCanvasTransitionTimeout),window.__markupCanvasTransitionTimeout=void 0),e.style.transition=`transform ${t.transitionDuration}s linear`,!0)}catch(e){return console.error("Failed to enable transitions:",e),!1}}(e,t);try{return n()}finally{b(e,t)}}function v(e,t,n){const r=t.keyboardPanStep;return n({translateY:e.transform.translateY-r})}function w(e,t,n){const r=t.keyboardPanStep;return n({translateX:e.transform.translateX+r})}function k(e,t,n){const r=t.keyboardPanStep;return n({translateX:e.transform.translateX-r})}function x(e,t,n){const r=t.keyboardPanStep;return n({translateY:e.transform.translateY+r})}function T(e,t){if(!e?.style||!t)return!1;try{return e.style.transform=function(e){return`matrix3d(${e.m11}, ${e.m12}, ${e.m13}, ${e.m14}, ${e.m21}, ${e.m22}, ${e.m23}, ${e.m24}, ${e.m31}, ${e.m32}, ${e.m33}, ${e.m34}, ${e.m41}, ${e.m42}, ${e.m43}, ${e.m44})`}(t),!0}catch(e){return console.warn("Transform application failed:",e),!1}}function C(e,t){e.transform={...e.transform,...t};const r=n(e.transform.scale,e.transform.translateX,e.transform.translateY);return T(e.transformLayer,r)}function M(e={}){const t={...f,...e};return("number"!=typeof t.width||t.width<=0)&&(console.warn("Invalid width, using default"),t.width=f.width),("number"!=typeof t.height||t.height<=0)&&(console.warn("Invalid height, using default"),t.height=f.height),("number"!=typeof t.zoomSpeed||t.zoomSpeed<=0)&&(console.warn("Invalid zoomSpeed, using default"),t.zoomSpeed=f.zoomSpeed),("number"!=typeof t.minZoom||t.minZoom<=0)&&(console.warn("Invalid minZoom, using default"),t.minZoom=f.minZoom),("number"!=typeof t.maxZoom||t.maxZoom<=t.minZoom)&&(console.warn("Invalid maxZoom, using default"),t.maxZoom=f.maxZoom),("number"!=typeof t.keyboardPanStep||t.keyboardPanStep<=0)&&(console.warn("Invalid keyboardPanStep, using default"),t.keyboardPanStep=f.keyboardPanStep),("number"!=typeof t.keyboardFastMultiplier||t.keyboardFastMultiplier<=0)&&(console.warn("Invalid keyboardFastMultiplier, using default"),t.keyboardFastMultiplier=f.keyboardFastMultiplier),("number"!=typeof t.clickZoomLevel||t.clickZoomLevel<=0)&&(console.warn("Invalid clickZoomLevel, using default"),t.clickZoomLevel=f.clickZoomLevel),("number"!=typeof t.rulerFontSize||t.rulerFontSize<=0)&&(console.warn("Invalid rulerFontSize, using default"),t.rulerFontSize=f.rulerFontSize),("number"!=typeof t.rulerSize||t.rulerSize<=0)&&(console.warn("Invalid rulerSize, using default"),t.rulerSize=f.rulerSize),t}function S(e,t,n,r){const o=M({...t,themeMode:r}),a=m(o,"canvasBackgroundColor");e.style.backgroundColor=a,n&&n.updateTheme(o)}function D(e){try{const t=e.getBounds();return{x:t.width/2,y:t.height/2}}catch(e){return console.warn("Failed to calculate viewport center:",e),{x:0,y:0}}}function z(e,t){const n=Array.from(e.children);let r=e.querySelector(`.${o}`);r||(r=document.createElement("div"),r.className=o,e.appendChild(r)),function(e,t){e.style.position="absolute";const n=t.rulerSize;e.style.top=`${n}px`,e.style.left=`${n}px`,e.style.width=`${t.width}px`,e.style.height=`${t.height}px`,e.style.transformOrigin="0 0"}(r,t);let i=r.querySelector(`.${a}`);return i||(i=document.createElement("div"),i.className=a,r.appendChild(i),function(e,t,n){e.forEach(e=>{e===n||e.classList.contains(o)||t.appendChild(e)})}(n,i,r)),function(e){e.style.position="relative",e.style.width="100%",e.style.height="100%",e.style.pointerEvents="auto"}(i),{transformLayer:r,contentLayer:i}}function L(e,t){if("static"===getComputedStyle(e).position&&(e.style.position="relative"),e.style.overflow="hidden",e.style.cursor="grab",e.style.overscrollBehavior="none",t){const n=m(t,"canvasBackgroundColor");e.style.backgroundColor=n}e.hasAttribute("tabindex")||e.setAttribute("tabindex","0"),function(e){const t=e.getBoundingClientRect(),n=getComputedStyle(e);0===t.height&&"auto"===n.height&&console.error("MarkupCanvas: Container height is 0. Please set a height on your container element using CSS.","Examples: height: 100vh, height: 500px, or use flexbox/grid layout.",e),0===t.width&&"auto"===n.width&&console.error("MarkupCanvas: Container width is 0. Please set a width on your container element using CSS.","Examples: width: 100vw, width: 800px, or use flexbox/grid layout.",e)}(e),e.classList.contains(r)||e.classList.add(r)}function R(e,t){if(!e?.appendChild)return console.error("Invalid container element provided to createCanvas"),null;try{L(e,t);const{transformLayer:r,contentLayer:o}=z(e,t);u(t,"enableAcceleration",()=>{!function(e){try{return e.style.transform=e.style.transform||"translateZ(0)",e.style.backfaceVisibility="hidden",!0}catch(e){return console.error("Failed to enable hardware acceleration:",e),!1}}(r)});const a=t.enableRulers?-t.rulerSize:0,i={scale:t.initialZoom??1,translateX:(t.initialPan?.x??0)+a,translateY:(t.initialPan?.y??0)+a},s=n(i.scale,i.translateX,i.translateY);T(r,s);return{container:e,transformLayer:r,contentLayer:o,transform:i}}catch(e){return console.error("Failed to create canvas:",e),null}}class P{constructor(){this.listeners=new Map}setEmitInterceptor(e){this.emitInterceptor=e}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){const n=this.listeners.get(e);n&&n.delete(t)}emit(e,t){this.emitInterceptor?.(e,t);const n=this.listeners.get(e);n&&n.forEach(n=>{try{n(t)}catch(t){console.error(`Error in event handler for "${String(e)}":`,t)}})}removeAllListeners(){this.listeners.clear()}}function E(e,t){const n=t.transform;e.emit("transform",n),e.emit("zoom",n.scale),e.emit("pan",{x:n.translateX,y:n.translateY})}const Y=300,X=5;function $(e,t){if(!e?.getBounds)return t;try{const n=e.getBounds(),r=n.width*n.height;return t*(r/2073600)**1}catch(e){return console.warn("Failed to calculate adaptive zoom speed, using base speed:",e),t}}function I(e,t){function n(n){if(!(n instanceof KeyboardEvent))return;if("canvas"===t.bindKeyboardEventsTo&&document.activeElement!==e.container)return;let r=!1;const o={};switch(n.key){case"ArrowLeft":o.translateX=e.transform.translateX+t.keyboardPanStep,r=!0;break;case"ArrowRight":o.translateX=e.transform.translateX-t.keyboardPanStep,r=!0;break;case"ArrowUp":o.translateY=e.transform.translateY+t.keyboardPanStep,r=!0;break;case"ArrowDown":o.translateY=e.transform.translateY-t.keyboardPanStep,r=!0;break;case"=":case"+":{const n=t.enableAdaptiveSpeed?$(e,t.keyboardZoomStep):t.keyboardZoomStep;e.zoomIn(n),r=!0}break;case"-":{const n=t.enableAdaptiveSpeed?$(e,t.keyboardZoomStep):t.keyboardZoomStep;e.zoomOut(n),r=!0}break;case"0":n.ctrlKey?(e.resetView&&e.resetView(),r=!0):(n.metaKey||n.ctrlKey)&&(e.resetViewToCenter&&e.resetViewToCenter(),r=!0);break;case"g":case"G":n.shiftKey&&e.toggleGrid&&e.toggleGrid(),r=n.shiftKey;break;case"r":case"R":!n.shiftKey||n.metaKey||n.ctrlKey||n.altKey||!e.toggleRulers||(e.toggleRulers(),r=!0)}r&&(n.preventDefault(),Object.keys(o).length>0&&e.updateTransform(o))}const r="canvas"===t.bindKeyboardEventsTo?e.container:document;return r.addEventListener("keydown",n),()=>{r.removeEventListener("keydown",n)}}function B(e,t,n,r,o){n?t.requireSpaceForMouseDrag?e.container.style.cursor=r?"grab":"default":e.container.style.cursor=o?"grabbing":"grab":e.container.style.cursor="default"}function Z(e,t,n,r,o){o.setIsDragging(!1),o.setDragButton(-1),B(e,t,n,r,!1)}function F(e,t,n,r,o,a,i,s,l,c){a&&e.button===i&&Z(t,n,r,o,{setIsDragging:c.setIsDragging,setDragButton:c.setDragButton}),r&&0===e.button&&n.enableClickToZoom&&s>0&&function(e,t,n,r,o,a){const i=Date.now()-r,s=e.altKey,l=!n.requireOptionForClickZoom||s;if(i<Y&&!o&&!a&&l){e.preventDefault();const r=t.container.getBoundingClientRect(),o=e.clientX-r.left,a=e.clientY-r.top,{clickX:i,clickY:s}=g(t,o,a,n.rulerSize,(e,t)=>({clickX:e,clickY:t})),l=t.canvasToContent(i,s),c=r.width/2,u=r.height/2,d=n.clickZoomLevel,h={scale:d,translateX:c-l.x*d,translateY:u-l.y*d};y(t.transformLayer,t.config,()=>{t.updateTransform(h)})}}(e,t,n,s,l,a),0===e.button&&function(e){e.setMouseDownTime(0),e.setHasDragged(!1)}({setMouseDownTime:c.setMouseDownTime,setHasDragged:c.setHasDragged})}function O(e,t,n=!0){let r=!0,o=!1,a=0,i=0,s=-1,l=!1,c=0,u=0,h=0,g=!1;const m={setIsDragging:e=>{o=e},setDragButton:e=>{s=e},setIsSpacePressed:e=>{l=e},setMouseDownTime:e=>{c=e},setMouseDownX:e=>{u=e},setMouseDownY:e=>{h=e},setHasDragged:e=>{g=e},setLastMouseX:e=>{a=e},setLastMouseY:e=>{i=e}},f=n=>{!function(e,t,n,r,o,a){n.requireSpaceForMouseDrag&&" "===e.key&&(a.setIsSpacePressed(!0),B(t,n,r,!0,o))}(n,e,t,r,o,{setIsSpacePressed:m.setIsSpacePressed})},p=n=>{!function(e,t,n,r,o,a){n.requireSpaceForMouseDrag&&" "===e.key&&(a.setIsSpacePressed(!1),B(t,n,r,!1,o),o&&Z(t,n,r,!1,{setIsDragging:a.setIsDragging,setDragButton:a.setDragButton}))}(n,e,t,r,o,{setIsSpacePressed:m.setIsSpacePressed,setIsDragging:m.setIsDragging,setDragButton:m.setDragButton})},b=n=>{!function(e,t,n,r,o,a){const i=0===e.button,s=1===e.button;if(i&&(a.setMouseDownTime(Date.now()),a.setMouseDownX(e.clientX),a.setMouseDownY(e.clientY),a.setHasDragged(!1)),!r)return;(!n.requireSpaceForMouseDrag||o)&&(i&&n.enableLeftDrag||s&&n.enableMiddleDrag)&&(e.preventDefault(),a.setDragButton(e.button),a.setLastMouseX(e.clientX),a.setLastMouseY(e.clientY),B(t,n,r,o,!1))}(n,e,t,r,l,m)},y=n=>{!function(e,t,n,r,o,a,i,s,l,c,u,h){if(i>0){const t=Math.abs(e.clientX-s),i=Math.abs(e.clientY-l);if(t>X||i>X){h.setHasDragged(!0);const e=!n.requireSpaceForMouseDrag||a;!o&&r&&e&&h.setIsDragging(!0)}}if(!o||!r)return;e.preventDefault(),d((...e)=>{const n=e[0];if(!o||!r)return;const a=n.clientX-c,i=n.clientY-u,s={translateX:t.transform.translateX+a,translateY:t.transform.translateY+i};t.updateTransform(s),h.setLastMouseX(n.clientX),h.setLastMouseY(n.clientY)})(e)}(n,e,t,r,o,l,c,u,h,a,i,{setHasDragged:m.setHasDragged,setIsDragging:m.setIsDragging,setLastMouseX:m.setLastMouseX,setLastMouseY:m.setLastMouseY})},v=n=>{F(n,e,t,r,l,o,s,c,g,{setIsDragging:m.setIsDragging,setDragButton:m.setDragButton,setMouseDownTime:m.setMouseDownTime,setHasDragged:m.setHasDragged})},w=()=>{!function(e,t,n,r,o,a){o&&Z(e,t,n,r,a)}(e,t,r,l,o,{setIsDragging:m.setIsDragging,setDragButton:m.setDragButton})};e.container.addEventListener("mousedown",b),document.addEventListener("mousemove",y),document.addEventListener("mouseup",v),e.container.addEventListener("mouseleave",w),t.requireSpaceForMouseDrag&&(document.addEventListener("keydown",f),document.addEventListener("keyup",p)),B(e,t,r,l,o);const k=()=>{e.container.removeEventListener("mousedown",b),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",v),e.container.removeEventListener("mouseleave",w),t.requireSpaceForMouseDrag&&(document.removeEventListener("keydown",f),document.removeEventListener("keyup",p))};return n?{cleanup:k,enable:()=>(r=!0,B(e,t,r,l,o),!0),disable:()=>(r=!1,o&&Z(e,t,r,l,{setIsDragging:m.setIsDragging,setDragButton:m.setDragButton}),B(e,t,r,l,o),!0),isEnabled:()=>r}:k}function V(e){const t=t=>{const n=t.data;if(!["markup-canvas","application"].includes(n.source))return;const r=e.config.name||"markupCanvas";if(n.canvasName!==r)return;const o=n.action,a=n.data;try{if("zoomIn"===o)e.zoomIn(a);else if("zoomOut"===o)e.zoomOut(a);else if("setZoom"===o){const t=a;if("number"!=typeof t||t<=0)throw new Error(`Invalid zoom level: ${t}. Must be a positive number.`);e.setZoom(t)}else if("resetZoom"===o)e.resetZoom();else if("panLeft"===o)e.panLeft(a);else if("panRight"===o)e.panRight(a);else if("panUp"===o)e.panUp(a);else if("panDown"===o)e.panDown(a);else if("fitToScreen"===o)e.fitToScreen();else if("centerContent"===o)e.centerContent();else if("panToPoint"===o)e.panToPoint(a.x,a.y);else if("resetView"===o)e.resetView();else if("resetViewToCenter"===o)e.resetViewToCenter();else if("toggleRulers"===o)e.toggleRulers();else if("showRulers"===o)e.showRulers();else if("hideRulers"===o)e.hideRulers();else if("toggleGrid"===o)e.toggleGrid();else if("showGrid"===o)e.showGrid();else if("hideGrid"===o)e.hideGrid();else if("updateThemeMode"===o){const t=a;if("light"!==t&&"dark"!==t)throw new Error(`Invalid theme mode: ${t}`);e.updateThemeMode(t)}else if("toggleThemeMode"===o){const t="light"===e.getConfig().themeMode?"dark":"light";e.updateThemeMode(t)}else if("updateTransition"===o){const t=a;if("boolean"!=typeof t)throw new Error(`Invalid transition enabled value: ${t}. Must be a boolean.`);e.updateTransition(t)}else{if("toggleTransitionMode"!==o)throw new Error(`Unknown action: ${o}`);e.toggleTransitionMode()}}catch(e){!function(e,t,n){window.postMessage({source:"markup-canvas-error",canvasName:e,action:t,error:n,timestamp:Date.now()},"*")}(r,o,e instanceof Error?e.message:String(e))}};return"undefined"!=typeof window&&window.addEventListener("message",t),()=>{"undefined"!=typeof window&&window.removeEventListener("message",t)}}function A(e,t){return{x:(e.clientX+t.clientX)/2,y:(e.clientY+t.clientY)/2}}function _(e,t){const n=e.clientX-t.clientX,r=e.clientY-t.clientY;return Math.sqrt(n*n+r*r)}function G(e,t,n,r){const o=i(n,r,e.transform,t,e.config);return e.updateTransform(o)}function K(e,t,n){e.preventDefault();const r=Array.from(e.touches);d((...e)=>{const r=e[0];if(1===r.length){if(1===n.touches.length){const e=r[0].clientX-n.touches[0].clientX,o=r[0].clientY-n.touches[0].clientY,a={translateX:t.transform.translateX+e,translateY:t.transform.translateY+o};t.updateTransform(a)}}else if(2===r.length){const e=_(r[0],r[1]),o=A(r[0],r[1]);if(n.lastDistance>0){const r=e/n.lastDistance,a=t.container.getBoundingClientRect();let i=o.x-a.left,s=o.y-a.top;const l=function(e,t,n,r){return h(e,t,e=>{const t={...n,x:n.x-e,y:n.y-e};return r(t)})}(t,t.config.rulerSize,{x:i,y:s},e=>e);i=l.x,s=l.y,G(t,r,i,s)}n.lastDistance=e,n.lastCenter=o}n.touches=r})(r)}function H(e){const t={touches:[],lastDistance:0,lastCenter:{}},n=e=>{!function(e,t){e.preventDefault(),t.touches=Array.from(e.touches),2===t.touches.length&&(t.lastDistance=_(t.touches[0],t.touches[1]),t.lastCenter=A(t.touches[0],t.touches[1]))}(e,t)},r=n=>{K(n,e,t)},o=e=>{!function(e,t){t.touches=Array.from(e.touches),t.touches.length<2&&(t.lastDistance=0)}(e,t)};return e.container.addEventListener("touchstart",n,{passive:!1}),e.container.addEventListener("touchmove",r,{passive:!1}),e.container.addEventListener("touchend",o,{passive:!1}),()=>{e.container.removeEventListener("touchstart",n),e.container.removeEventListener("touchmove",r),e.container.removeEventListener("touchend",o)}}function N(e){const t=e.ctrlKey||e.metaKey,n=[0===e.deltaMode,Math.abs(e.deltaY)<50,e.deltaY%1!=0,Math.abs(e.deltaX)>0&&Math.abs(e.deltaY)>0].filter(Boolean).length>=2;return{isTrackpad:n,isMouseWheel:!n,isTrackpadScroll:n&&!t,isTrackpadPinch:n&&t,isZoomGesture:t}}function q(e,t){const n=(e=>d((...t)=>{const n=t[0];if(!n||!e?.updateTransform)return!1;try{const t=e.transform,r=1,o=n.deltaX*r,a=n.deltaY*r,i={scale:t.scale,translateX:t.translateX-o,translateY:t.translateY-a};return b(e.transformLayer,e.config),e.updateTransform(i)}catch(e){return console.error("Error handling trackpad pan:",e),!1}}))(e),r=r=>N(r).isTrackpadScroll?n(r):function(e,t,n){if(!e||"number"!=typeof e.deltaY)return console.warn("Invalid wheel event provided"),!1;if(!t?.updateTransform)return console.warn("Invalid canvas provided to handleWheelEvent"),!1;try{e.preventDefault();const r=t.container.getBoundingClientRect(),o=e.clientX-r.left,a=e.clientY-r.top,{mouseX:i,mouseY:s}=g(t,o,a,n.rulerSize,(e,t)=>({mouseX:e,mouseY:t})),l=n.zoomSpeed,c=N(e);if(!c.isZoomGesture)return!1;let u=n.enableAdaptiveSpeed?$(t,l):l;if(c.isTrackpadPinch){const e=.05*n.zoomSpeed;u=n.enableAdaptiveSpeed?$(t,e):e}return G(t,(e.deltaY<0?1:-1)>0?1+u:1/(1+u),i,s)}catch(e){return console.error("Error handling wheel event:",e),!1}}(r,e,t);return e.container.addEventListener("wheel",r,{passive:!1}),()=>{e.container.removeEventListener("wheel",r)}}const U=100,W=1e3,j=1001,J=4,Q=4,ee=100,te=100,ne=20,re=200;function oe(e,t){const n=function(e){const t=document.createElement("div");return t.className="canvas-ruler horizontal-ruler",t.style.cssText=`\n\tposition: absolute;\n\ttop: 0;\n\tleft: ${e.rulerSize}px;\n\tright: 0;\n\theight: ${e.rulerSize}px;\n\tbackground: var(--ruler-background-color);\n\tborder-bottom: 1px solid var(--ruler-border-color);\n\tborder-right: 1px solid var(--ruler-border-color);\n\tz-index: ${W};\n\tpointer-events: none;\n\tfont-family: ${e.rulerFontFamily};\n\tfont-size: ${e.rulerFontSize}px;\n\tcolor: var(--ruler-text-color);\n\toverflow: hidden;\n `,t}(t),r=function(e){const t=document.createElement("div");return t.className="canvas-ruler vertical-ruler",t.style.cssText=`\n\tposition: absolute;\n\ttop: ${e.rulerSize}px;\n\tleft: 0;\n\tbottom: 0;\n\twidth: ${e.rulerSize}px;\n\tbackground: var(--ruler-background-color);\n\tborder-right: 1px solid var(--ruler-border-color);\n\tborder-bottom: 1px solid var(--ruler-border-color);\n\tz-index: ${W};\n\tpointer-events: none;\n\tfont-family: ${e.rulerFontFamily};\n\tfont-size: ${e.rulerFontSize}px;\n\tcolor: var(--ruler-text-color);\n\toverflow: hidden;\n `,t}(t),o=function(e){const t=document.createElement("div");return t.className="canvas-ruler corner-box",t.style.cssText=`\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\tleft: 0;\n\t\twidth: ${e.rulerSize}px;\n\t\theight: ${e.rulerSize}px;\n\t\tbackground: var(--ruler-background-color);\n\t\tborder-right: 1px solid var(--ruler-border-color);\n\t\tborder-bottom: 1px solid var(--ruler-border-color);\n\t\tz-index: ${j};\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tfont-family: ${e.rulerFontFamily};\n\t\tfont-size: ${e.rulerFontSize-2}px;\n\t\tcolor: var(--ruler-text-color);\n\t\tpointer-events: none;\n\t`,t.textContent=e.rulerUnits,t}(t),a=t.enableGrid?function(e){const t=document.createElement("div");return t.className="canvas-ruler grid-overlay",t.style.cssText=`\n\t\tposition: absolute;\n\t\ttop: ${e.rulerSize}px;\n\t\tleft: ${e.rulerSize}px;\n\t\tright: 0;\n\t\tbottom: 0;\n\t\tpointer-events: none;\n\t\tz-index: ${U};\n\t\tbackground-image: \n\t\t\tlinear-gradient(var(--grid-color) 1px, transparent 1px),\n\t\t\tlinear-gradient(90deg, var(--grid-color) 1px, transparent 1px);\n\t\tbackground-size: 100px 100px;\n\t\topacity: 0.5;\n\t`,t}(t):void 0;return e.appendChild(n),e.appendChild(r),e.appendChild(o),a&&e.appendChild(a),{horizontalRuler:n,verticalRuler:r,cornerBox:o,gridOverlay:a}}function ae(e,t){const n=e/Math.max(5,Math.min(20,t/50)),r=10**Math.floor(Math.log10(n)),o=n/r;let a;return a=o<=1?1:o<=2?2:o<=5?5:10,a*r}function ie(e,t,n,r,o){const a=document.createElement("div");a.className="tick",a.style.cssText=`\n\t\tposition: absolute;\n\t\tleft: ${n}px;\n\t\tbottom: 0;\n\t\twidth: 1px;\n\t\theight: ${J}px;\n\t\tbackground: var(--ruler-tick-color);\n\t`,e.appendChild(a);if(t%ee===0){const r=document.createElement("div");r.style.cssText=`\n\t\t\tposition: absolute;\n\t\t\tleft: ${n}px;\n\t\t\tbottom: ${J+2}px;\n\t\t\tfont-size: ${o.rulerFontSize}px;\n\t\t\tline-height: 1;\n\t\t\tcolor: var(--ruler-text-color);\n\t\t\twhite-space: nowrap;\n\t\t\tpointer-events: none;\n\t\t`,r.textContent=Math.round(t).toString(),e.appendChild(r)}}function se(e,t,n,r,o){const a=document.createElement("div");a.className="tick",a.style.cssText=`\n\t\tposition: absolute;\n\t\ttop: ${n}px;\n\t\tright: 0;\n\t\twidth: ${Q}px;\n\t\theight: 1px;\n\t\tbackground: var(--ruler-tick-color);\n\t`,e.appendChild(a);if(t%ee===0){const r=document.createElement("div");r.style.cssText=`\n\t\t\tposition: absolute;\n\t\t\ttop: ${n-6}px;\n\t\t\tright: ${Q+6}px;\n\t\t\tfont-size: ${o.rulerFontSize}px;\n\t\t\tline-height: 1;\n\t\t\tcolor: var(--ruler-text-color);\n\t\t\twhite-space: nowrap;\n\t\t\tpointer-events: none;\n\t\t\ttransform: rotate(-90deg);\n\t\t\ttransform-origin: right center;\n\t\t`,r.textContent=Math.round(t).toString(),e.appendChild(r)}}function le(e,t,n,r,o){const a=e.getBounds(),i=a.scale||1,s=a.translateX||0,l=a.translateY||0,c=a.width-o.rulerSize,u=a.height-o.rulerSize,d=-s/i,h=-l/i,g=h+u/i;!function(e,t,n,r,o,a){const i=r,s=ae(n-t,i),l=document.createDocumentFragment(),c=Math.floor(t/s)*s,u=Math.ceil(n/s)*s;for(let e=c;e<=u;e+=s){const n=(e-t)*o;n>=-50&&n<=i+50&&ie(l,e,n,0,a)}e.innerHTML="",e.appendChild(l)}(t,d,d+c/i,c,i,o),function(e,t,n,r,o,a){const i=r,s=ae(n-t,i),l=document.createDocumentFragment(),c=Math.floor(t/s)*s,u=Math.ceil(n/s)*s;for(let e=c;e<=u;e+=s){const n=(e-t)*o;n>=-50&&n<=i+50&&se(l,e,n,0,a)}e.innerHTML="",e.appendChild(l)}(n,h,g,u,i,o),r&&function(e,t,n,r){let o=te*t;for(;o<ne;)o*=2;for(;o>re;)o/=2;e.style.backgroundSize=`${o}px ${o}px`,e.style.backgroundPosition=`${n%o}px ${r%o}px`}(r,i,s,l)}function ce(e,t){const n=m(t,"rulerBackgroundColor"),r=m(t,"rulerBorderColor"),o=m(t,"rulerTextColor"),a=m(t,"rulerTickColor"),i=m(t,"gridColor");e.horizontalRuler&&(e.horizontalRuler.style.setProperty("--ruler-background-color",n),e.horizontalRuler.style.setProperty("--ruler-border-color",r),e.horizontalRuler.style.setProperty("--ruler-text-color",o),e.horizontalRuler.style.setProperty("--ruler-tick-color",a)),e.verticalRuler&&(e.verticalRuler.style.setProperty("--ruler-background-color",n),e.verticalRuler.style.setProperty("--ruler-border-color",r),e.verticalRuler.style.setProperty("--ruler-text-color",o),e.verticalRuler.style.setProperty("--ruler-tick-color",a)),e.cornerBox&&(e.cornerBox.style.setProperty("--ruler-background-color",n),e.cornerBox.style.setProperty("--ruler-border-color",r),e.cornerBox.style.setProperty("--ruler-text-color",o)),e.gridOverlay&&e.gridOverlay.style.setProperty("--grid-color",i)}function ue(e,t){if(!e?.container)return console.error("Invalid canvas provided to createRulers"),null;let n,r=null,o=!1;const a=()=>{!o&&n.horizontalRuler&&n.verticalRuler&&le(e,n.horizontalRuler,n.verticalRuler,n.gridOverlay,t)};try{return n=oe(e.container,t),r=function(e,t){const n=d(t),r=e.updateTransform;e.updateTransform=function(e){const t=r.call(this,e);return n(),t};const o=d(t);return window.addEventListener("resize",o),()=>{window.removeEventListener("resize",o),e.updateTransform=r,n.cleanup(),o.cleanup()}}(e,a),ce(n,t),a(),t.showRulers||(n.horizontalRuler.style.display="none",n.verticalRuler.style.display="none",n.cornerBox.style.display="none"),!t.showGrid&&n.gridOverlay&&(n.gridOverlay.style.display="none"),{horizontalRuler:n.horizontalRuler,verticalRuler:n.verticalRuler,cornerBox:n.cornerBox,gridOverlay:n.gridOverlay,update:a,updateTheme:e=>{o||ce(n,e)},show:()=>{n.horizontalRuler&&(n.horizontalRuler.style.display="block"),n.verticalRuler&&(n.verticalRuler.style.display="block"),n.cornerBox&&(n.cornerBox.style.display="flex")},hide:()=>{n.horizontalRuler&&(n.horizontalRuler.style.display="none"),n.verticalRuler&&(n.verticalRuler.style.display="none"),n.cornerBox&&(n.cornerBox.style.display="none"),n.gridOverlay&&(n.gridOverlay.style.display="none")},toggleGrid:()=>{if(n.gridOverlay){const e="none"!==n.gridOverlay.style.display;n.gridOverlay.style.display=e?"none":"block"}},destroy:()=>{o=!0,r&&r(),n.horizontalRuler?.parentNode&&n.horizontalRuler.parentNode.removeChild(n.horizontalRuler),n.verticalRuler?.parentNode&&n.verticalRuler.parentNode.removeChild(n.verticalRuler),n.cornerBox?.parentNode&&n.cornerBox.parentNode.removeChild(n.cornerBox),n.gridOverlay?.parentNode&&n.gridOverlay.parentNode.removeChild(n.gridOverlay)}}}catch(e){return console.error("Failed to create rulers:",e),null}}return class{constructor(e,t={}){if(this.cleanupCallbacks=[],this.rulers=null,this.dragSetup=null,this.keyboardCleanup=null,this.event=new P,this._isReady=!1,!e)throw new Error("Container element is required");this.config=M(t);const n=R(e,this.config);if(!n)throw new Error("Failed to create canvas");if(this.canvas=n,u(this.config,"enableRulers",()=>{this.rulers=ue(this,this.config),this.cleanupCallbacks.push(()=>{this.rulers&&this.rulers.destroy()})}),t.themeMode&&S(this.canvas.container,this.config,this.rulers,t.themeMode),this.event.setEmitInterceptor((e,t)=>{!function(e,t,n){if("undefined"==typeof window)return;let r=t;"ready"===e&&(r={ready:!0});const o=n.name||"markupCanvas";window.postMessage({source:"markup-canvas",action:e,data:r,timestamp:Date.now(),canvasName:o},"*"),window.parent&&window.parent.postMessage({source:"markup-canvas",action:e,data:r,timestamp:Date.now(),canvasName:o},"*")}(e,t,this.config)}),function(e,t){if("undefined"==typeof window)return;const n=t.name||"markupCanvas",r=window,o={config:{get current(){return e.config},get:e.getConfig.bind(e),update:e.updateConfig.bind(e)},transform:{update:e.updateTransform.bind(e),reset:e.reset.bind(e)},zoom:{get current(){return e.transform.scale||1},set:e.setZoom.bind(e),toPoint:e.zoomToPoint.bind(e),in:e.zoomIn.bind(e),out:e.zoomOut.bind(e),reset:e.resetZoom.bind(e),resetToCenter:e.resetViewToCenter.bind(e),fitToScreen:e.fitToScreen.bind(e)},pan:{left:e.panLeft.bind(e),right:e.panRight.bind(e),up:e.panUp.bind(e),down:e.panDown.bind(e),toPoint:e.panToPoint.bind(e),toCenter:e.centerContent.bind(e)},mouseDrag:{enable:e.enableMouseDrag.bind(e),disable:e.disableMouseDrag.bind(e),isEnabled:e.isMouseDragEnabled.bind(e)},keyboard:{enable:e.enableKeyboard.bind(e),disable:e.disableKeyboard.bind(e),isEnabled:e.isKeyboardEnabled.bind(e)},grid:{toggle:e.toggleGrid.bind(e),show:e.showGrid.bind(e),hide:e.hideGrid.bind(e),isVisible:e.isGridVisible.bind(e)},rulers:{toggle:e.toggleRulers.bind(e),show:e.showRulers.bind(e),hide:e.hideRulers.bind(e),isVisible:e.areRulersVisible.bind(e)},canvas:{canvasToContent:e.canvasToContent.bind(e),getVisibleArea:e.getVisibleArea.bind(e),isPointVisible:e.isPointVisible.bind(e),getBounds:e.getBounds.bind(e)},theme:{get current(){return e.config.themeMode},update:e.updateThemeMode.bind(e),toggle:e.toggleThemeMode.bind(e)},transition:{get current(){return e.config.enableTransition},set:e.updateTransition.bind(e),toggle:e.toggleTransitionMode.bind(e)},event:e.event,lifecycle:{cleanup:e.cleanup.bind(e),destroy:e.destroy.bind(e)},state:{get isReady(){return e.isReady},get isTransforming(){return e.isTransforming},get visibleBounds(){return e.visibleBounds},get transform(){return e.transform}}};r[n]=o,r.__markupCanvasInstances||(r.__markupCanvasInstances=new Map),r.__markupCanvasInstances.set(n,o)}(this,this.config),this.config.enablePostMessageAPI){const e=V(this);this.cleanupCallbacks.push(e)}this.setupEventHandlers(),this._isReady=!0,this.event.emit("ready",this)}setupEventHandlers(){try{u(this.config,"enableZoom",()=>{const e=q(this,this.config);this.cleanupCallbacks.push(e)}),(this.config.enablePan||this.config.enableClickToZoom)&&(this.dragSetup=O(this,this.config,!0),this.cleanupCallbacks.push(this.dragSetup.cleanup)),u(this.config,"enableKeyboard",()=>{const e=I(this,this.config);this.keyboardCleanup=e,this.cleanupCallbacks.push(e)}),u(this.config,"enableTouch",()=>{const e=H(this);this.cleanupCallbacks.push(e)})}catch(e){throw console.error("Failed to set up event handlers:",e),this.cleanup(),e}}get container(){return this.canvas.container}get transformLayer(){return this.canvas.transformLayer}get contentLayer(){return this.canvas.contentLayer}get transform(){return this.canvas.transform}get isReady(){return this._isReady}get isTransforming(){return this.dragSetup?.isEnabled()||!1}get visibleBounds(){return s(this)}getBounds(){return p(this.canvas,this.config)}updateTransform(e){const t=C(this.canvas,e);return t&&E(this.event,this.canvas),t}reset(){const e=C(this.canvas,{scale:1,translateX:0,translateY:0});return e&&E(this.event,this.canvas),e}setZoom(e){return function(e,t,n,r,o){return y(t,n,()=>l(n,t=>{const n=t(o),a=D(e);return r(a.x,a.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this),e)}canvasToContent(t,r){return e(t,r,n(this.canvas.transform.scale,this.canvas.transform.translateX,this.canvas.transform.translateY))}zoomToPoint(e,t,n){const r=function(e,t,n,r,o,a){return y(t,n,()=>{const t=i(r,o,e.transform,a/e.transform.scale,n);return C(e,t)})}(this.canvas,this.transformLayer,this.config,e,t,n);return r&&E(this.event,this.canvas),r}resetView(){return e=this.canvas,t=this.transformLayer,n=this.config,y(t,n,()=>h(e,n.rulerSize,t=>C(e,{scale:1,translateX:-1*t,translateY:-1*t})));var e,t,n}resetViewToCenter(){return function(e,t,n,r){return y(t,n,()=>l(n,t=>{const n=t(1),o=D(e);return r(o.x,o.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this))}panLeft(e){return w(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&w(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}panRight(e){return k(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&k(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}panUp(e){return x(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&x(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}panDown(e){return v(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&v(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}zoomIn(e=.5){return function(e,t,n,r,o=.5){return y(t,n,()=>l(n,t=>{const n=t(e.transform.scale*(1+o)),a=D(e);return r(a.x,a.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this),e)}zoomOut(e=.5){return function(e,t,n,r,o=.5){return y(t,n,()=>l(n,t=>{const n=t(e.transform.scale*(1-o)),a=D(e);return r(a.x,a.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this),e)}resetZoom(){return this.resetViewToCenter()}enableMouseDrag(){return this.dragSetup?.enable()??!1}disableMouseDrag(){return this.dragSetup?.disable()??!1}isMouseDragEnabled(){return this.dragSetup?.isEnabled()??!1}enableKeyboard(){return this.keyboardCleanup||(this.keyboardCleanup=I(this,this.config),this.cleanupCallbacks.push(this.keyboardCleanup)),!0}disableKeyboard(){return!!this.keyboardCleanup&&(this.keyboardCleanup(),this.keyboardCleanup=null,!0)}isKeyboardEnabled(){return null!==this.keyboardCleanup}toggleGrid(){const e=(t=this.rulers,!!t?.toggleGrid&&(t.toggleGrid(),!0));var t;return e&&this.event.emit("gridVisibility",this.isGridVisible()),e}showGrid(){const e=(t=this.rulers,!!t?.gridOverlay&&(t.gridOverlay.style.display="block",!0));var t;return e&&this.event.emit("gridVisibility",!0),e}hideGrid(){const e=(t=this.rulers,!!t?.gridOverlay&&(t.gridOverlay.style.display="none",!0));var t;return e&&this.event.emit("gridVisibility",!1),e}isGridVisible(){return e=this.rulers,!!e?.gridOverlay&&"none"!==e.gridOverlay.style.display;var e}toggleRulers(){const e=function(e,t){if(e)return t()?e.hide():e.show(),!0;return!1}(this.rulers,()=>this.areRulersVisible());return e&&this.event.emit("rulersVisibility",this.areRulersVisible()),e}showRulers(){const e=!!(t=this.rulers)&&(t.show(),!0);var t;return e&&this.event.emit("rulersVisibility",!0),e}hideRulers(){const e=!!(t=this.rulers)&&(t.hide(),!0);var t;return e&&this.event.emit("rulersVisibility",!1),e}areRulersVisible(){return e=this.rulers,!!e?.horizontalRuler&&"none"!==e.horizontalRuler.style.display;var e}centerContent(){return e=this.canvas,t=this.config,n=this.updateTransform.bind(this),y(this.transformLayer,t,()=>{const r=p(e,t),o=(r.width-r.contentWidth*e.transform.scale)/2,a=(r.height-r.contentHeight*e.transform.scale)/2;return n({translateX:o,translateY:a})});var e,t,n}fitToScreen(){return e=this.canvas,t=this.transformLayer,n=this.config,y(t,n,()=>{const t=p(e,n),r=t.width/n.width,o=t.height/n.height,a=l(n,e=>e(.9*Math.min(r,o))),i=n.width*a,s=n.height*a,c=(t.width-i)/2,u=(t.height-s)/2;return C(e,{scale:a,translateX:c,translateY:u})});var e,t,n}getVisibleArea(){return s(this)}isPointVisible(e,t){return function(e,t,n){const r=s(e);return t>=r.x&&t<=r.x+r.width&&n>=r.y&&n<=r.y+r.height}(this,e,t)}panToPoint(e,t){return function(e,t,n,r,o,a){return y(a,t,()=>{const a=p(e,t),i=a.width/2,s=a.height/2,l=i-n*e.transform.scale,c=s-r*e.transform.scale;return o({translateX:l,translateY:c})})}(this.canvas,this.config,e,t,this.updateTransform.bind(this),this.transformLayer)}getConfig(){return{...this.config}}updateConfig(e){this.config=M({...this.config,...e})}updateThemeMode(e){this.config=M({...this.config,themeMode:e}),S(this.canvas.container,this.config,this.rulers,e)}toggleThemeMode(){const e="light"===this.config.themeMode?"dark":"light";return this.updateThemeMode(e),e}updateTransition(e){this.config=M({...this.config,enableTransition:e})}toggleTransitionMode(){const e=function(e){return!e}(this.config.enableTransition);return this.updateTransition(e),e}cleanup(){!function(e){if("undefined"==typeof window)return;const t=e.name||"markupCanvas",n=window;delete n[t],n.__markupCanvasInstances&&n.__markupCanvasInstances.delete(t)}(this.config),this.cleanupCallbacks.forEach(e=>{try{e()}catch(e){console.warn("Error during cleanup:",e)}}),this.cleanupCallbacks=[],this.removeAllListeners()}on(e,t){this.event.on(e,t)}off(e,t){this.event.off(e,t)}emit(e,t){this.event.emit(e,t)}removeAllListeners(){this.event.removeAllListeners()}destroy(){this.cleanup(),window.__markupCanvasTransitionTimeout&&clearTimeout(window.__markupCanvasTransitionTimeout)}}});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).MarkupCanvas=t()}(this,function(){"use strict";function e(e,t,n){if(!n?.inverse)return{x:e,y:t};try{const r=n.inverse(),o=new DOMPoint(e,t).matrixTransform(r);return{x:o.x,y:o.y}}catch(n){return console.warn("Canvas to content conversion failed:",n),{x:e,y:t}}}function t(e,t){return Math.max(t.minZoom,Math.min(t.maxZoom,e))}function n(e,t,n){return new DOMMatrix([e,0,0,e,t,n])}const r="canvas-container",o="transform-layer",a="content-layer";function s(e,n,r,o,a){const s=a.enableRulers?-a.rulerSize:0,i=r||{scale:1,translateX:s,translateY:s},{scale:l,translateX:c,translateY:u}=i,d=t(l*o,a);if(Math.abs(d-l)<.001)return{scale:l,translateX:c,translateY:u};return{scale:d,translateX:e-(e-c)/l*d,translateY:n-(n-u)/l*d}}function i(e){return e.getBounds().visibleArea}function l(e,n){return n(n=>t(n,e))}const c=new Map;function u(e,t,n){return e[t]?n():null}function d(e){let t=null,n=null;const r=(...r)=>{n=r,null===t&&(t=requestAnimationFrame(()=>{n&&e(...n),t=null,n=null}))};return r.cleanup=()=>{null!==t&&(cancelAnimationFrame(t),t=null,n=null)},r}function h(e,t,n){return n(null!==e.container.querySelector(".canvas-ruler")?t:0)}function g(e,t,n,r,o){const a=null!==e.container.querySelector(".canvas-ruler");return o(a?t-r:t,a?n-r:n)}function m(e,t){if("dark"===e.themeMode){return e[`${t}Dark`]}return e[t]}const p={width:8e3,height:8e3,enableAcceleration:!0,initialZoom:1,initialPan:{x:0,y:0},name:"markupCanvas",enablePostMessageAPI:!1,enableZoom:!0,enablePan:!0,enableTouch:!0,enableKeyboard:!0,bindKeyboardEventsTo:"document",zoomSpeed:1.5,minZoom:.05,maxZoom:80,enableTransition:!0,transitionDuration:.2,enableAdaptiveSpeed:!0,enableLeftDrag:!0,enableMiddleDrag:!0,requireSpaceForMouseDrag:!1,keyboardPanStep:50,keyboardFastMultiplier:20,keyboardZoomStep:.2,enableClickToZoom:!0,clickZoomLevel:1,requireOptionForClickZoom:!1,enableRulers:!0,enableGrid:!1,showRulers:!0,showGrid:!1,rulerFontSize:9,rulerFontFamily:"Monaco, Menlo, monospace",rulerUnits:"px",rulerSize:20,canvasBackgroundColor:"rgba(250, 250, 250, 1)",canvasBackgroundColorDark:"rgba(40, 40, 40, 1)",rulerBackgroundColor:"rgba(255, 255, 255, 0.95)",rulerBorderColor:"rgba(240, 240, 240, 1)",rulerTextColor:"rgba(102, 102, 102, 1)",rulerTickColor:"rgba(204, 204, 204, 1)",gridColor:"rgba(232, 86, 193, 0.5)",rulerBackgroundColorDark:"rgba(30, 30, 30, 0.95)",rulerBorderColorDark:"rgba(68, 68, 68, 1)",rulerTextColorDark:"rgba(170, 170, 170, 1)",rulerTickColorDark:"rgba(104, 104, 104, 1)",gridColorDark:"rgba(232, 86, 193, 0.5)",themeMode:"light"};function f(t,r){try{const o=t.container,a=t.transform||{scale:1,translateX:0,translateY:0},s=o.getBoundingClientRect(),i=s.width||o.clientWidth||0,l=s.height||o.clientHeight||0,c=h({container:o},r.rulerSize,e=>Math.max(0,i-e)),u=h({container:o},r.rulerSize,e=>Math.max(0,l-e)),d=r.width||p.width,g=r.height||p.height,m=function(t,r,o,a,s){const i=e(0,0,n(s.scale,s.translateX,s.translateY)),l=e(t,r,n(s.scale,s.translateX,s.translateY));return{x:Math.max(0,Math.min(o,i.x)),y:Math.max(0,Math.min(a,i.y)),width:Math.max(0,Math.min(o-i.x,l.x-i.x)),height:Math.max(0,Math.min(a-i.y,l.y-i.y))}}(c,u,d,g,a);return{width:c,height:u,contentWidth:d,contentHeight:g,scale:a.scale,translateX:a.translateX,translateY:a.translateY,visibleArea:m,scaledContentWidth:d*a.scale,scaledContentHeight:g*a.scale,canPanLeft:a.translateX<0,canPanRight:a.translateX+d*a.scale>c,canPanUp:a.translateY<0,canPanDown:a.translateY+g*a.scale>u,canZoomIn:a.scale<3.5,canZoomOut:a.scale>.1}}catch(e){return console.error("Failed to calculate canvas bounds:",e),{width:0,height:0,contentWidth:0,contentHeight:0,scale:1,translateX:0,translateY:0,visibleArea:{x:0,y:0,width:0,height:0},scaledContentWidth:0,scaledContentHeight:0,canPanLeft:!1,canPanRight:!1,canPanUp:!1,canPanDown:!1,canZoomIn:!1,canZoomOut:!1}}}function b(e,t){try{if(t.enableTransition){window.__markupCanvasTransitionTimeout&&(clearTimeout(window.__markupCanvasTransitionTimeout),window.__markupCanvasTransitionTimeout=void 0);return function(e,t,n){const r=c.get(e);r&&clearTimeout(r);const o=window.setTimeout(()=>{n(),c.delete(e)},t);c.set(e,o)}("disableTransition",1e3*(t.transitionDuration??.2),()=>{e.style.transition="none",window.__markupCanvasTransitionTimeout=void 0}),!0}return!1}catch(e){return console.error("Failed to disable transitions:",e),!0}}function y(e,t,n){!function(e,t){try{return!!t.enableTransition&&(window.__markupCanvasTransitionTimeout&&(clearTimeout(window.__markupCanvasTransitionTimeout),window.__markupCanvasTransitionTimeout=void 0),e.style.transition=`transform ${t.transitionDuration}s linear`,!0)}catch(e){return console.error("Failed to enable transitions:",e),!1}}(e,t);try{return n()}finally{b(e,t)}}function v(e,t,n){const r=t.keyboardPanStep;return n({translateY:e.transform.translateY-r})}function w(e,t,n){const r=t.keyboardPanStep;return n({translateX:e.transform.translateX+r})}function k(e,t,n){const r=t.keyboardPanStep;return n({translateX:e.transform.translateX-r})}function x(e,t,n){const r=t.keyboardPanStep;return n({translateY:e.transform.translateY+r})}function T(e,t){if(!e?.style||!t)return!1;try{return e.style.transform=function(e){return`matrix3d(${e.m11}, ${e.m12}, ${e.m13}, ${e.m14}, ${e.m21}, ${e.m22}, ${e.m23}, ${e.m24}, ${e.m31}, ${e.m32}, ${e.m33}, ${e.m34}, ${e.m41}, ${e.m42}, ${e.m43}, ${e.m44})`}(t),!0}catch(e){return console.warn("Transform application failed:",e),!1}}function C(e,t){e.transform={...e.transform,...t};const r=n(e.transform.scale,e.transform.translateX,e.transform.translateY);return T(e.transformLayer,r)}function M(e={}){const t={...p,...e};return("number"!=typeof t.width||t.width<=0)&&(console.warn("Invalid width, using default"),t.width=p.width),("number"!=typeof t.height||t.height<=0)&&(console.warn("Invalid height, using default"),t.height=p.height),("number"!=typeof t.zoomSpeed||t.zoomSpeed<=0)&&(console.warn("Invalid zoomSpeed, using default"),t.zoomSpeed=p.zoomSpeed),("number"!=typeof t.minZoom||t.minZoom<=0)&&(console.warn("Invalid minZoom, using default"),t.minZoom=p.minZoom),("number"!=typeof t.maxZoom||t.maxZoom<=t.minZoom)&&(console.warn("Invalid maxZoom, using default"),t.maxZoom=p.maxZoom),("number"!=typeof t.keyboardPanStep||t.keyboardPanStep<=0)&&(console.warn("Invalid keyboardPanStep, using default"),t.keyboardPanStep=p.keyboardPanStep),("number"!=typeof t.keyboardFastMultiplier||t.keyboardFastMultiplier<=0)&&(console.warn("Invalid keyboardFastMultiplier, using default"),t.keyboardFastMultiplier=p.keyboardFastMultiplier),("number"!=typeof t.clickZoomLevel||t.clickZoomLevel<=0)&&(console.warn("Invalid clickZoomLevel, using default"),t.clickZoomLevel=p.clickZoomLevel),("number"!=typeof t.rulerFontSize||t.rulerFontSize<=0)&&(console.warn("Invalid rulerFontSize, using default"),t.rulerFontSize=p.rulerFontSize),("number"!=typeof t.rulerSize||t.rulerSize<=0)&&(console.warn("Invalid rulerSize, using default"),t.rulerSize=p.rulerSize),t}function S(e,t,n,r){const o=M({...t,themeMode:r}),a=m(o,"canvasBackgroundColor");e.style.backgroundColor=a,n&&n.updateTheme(o)}function D(e){try{const t=e.getBounds();return{x:t.width/2,y:t.height/2}}catch(e){return console.warn("Failed to calculate viewport center:",e),{x:0,y:0}}}function z(e,t){const n=Array.from(e.children);let r=e.querySelector(`.${o}`);r||(r=document.createElement("div"),r.className=o,e.appendChild(r)),function(e,t){e.style.position="absolute";const n=t.rulerSize;e.style.top=`${n}px`,e.style.left=`${n}px`,e.style.width=`${t.width}px`,e.style.height=`${t.height}px`,e.style.transformOrigin="0 0"}(r,t);let s=r.querySelector(`.${a}`);return s||(s=document.createElement("div"),s.className=a,r.appendChild(s),function(e,t,n){e.forEach(e=>{e===n||e.classList.contains(o)||t.appendChild(e)})}(n,s,r)),function(e){e.style.position="relative",e.style.width="100%",e.style.height="100%",e.style.pointerEvents="auto"}(s),{transformLayer:r,contentLayer:s}}function L(e,t){if("static"===getComputedStyle(e).position&&(e.style.position="relative"),e.style.overflow="hidden",e.style.cursor="grab",e.style.overscrollBehavior="none",t){const n=m(t,"canvasBackgroundColor");e.style.backgroundColor=n}e.hasAttribute("tabindex")||e.setAttribute("tabindex","0"),function(e){const t=e.getBoundingClientRect(),n=getComputedStyle(e);0===t.height&&"auto"===n.height&&console.error("MarkupCanvas: Container height is 0. Please set a height on your container element using CSS.","Examples: height: 100vh, height: 500px, or use flexbox/grid layout.",e),0===t.width&&"auto"===n.width&&console.error("MarkupCanvas: Container width is 0. Please set a width on your container element using CSS.","Examples: width: 100vw, width: 800px, or use flexbox/grid layout.",e)}(e),e.classList.contains(r)||e.classList.add(r)}function R(e,t){if(!e?.appendChild)return console.error("Invalid container element provided to createCanvas"),null;try{L(e,t);const{transformLayer:r,contentLayer:o}=z(e,t);u(t,"enableAcceleration",()=>{!function(e){try{return e.style.transform=e.style.transform||"translateZ(0)",e.style.backfaceVisibility="hidden",!0}catch(e){return console.error("Failed to enable hardware acceleration:",e),!1}}(r)});const a=t.enableRulers?-t.rulerSize:0,s={scale:t.initialZoom??1,translateX:(t.initialPan?.x??0)+a,translateY:(t.initialPan?.y??0)+a},i=n(s.scale,s.translateX,s.translateY);T(r,i);return{container:e,transformLayer:r,contentLayer:o,transform:s}}catch(e){return console.error("Failed to create canvas:",e),null}}class P{constructor(){this.listeners=new Map}setEmitInterceptor(e){this.emitInterceptor=e}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){const n=this.listeners.get(e);n&&n.delete(t)}emit(e,t){this.emitInterceptor?.(e,t);const n=this.listeners.get(e);n&&n.forEach(n=>{try{n(t)}catch(t){console.error(`Error in event handler for "${String(e)}":`,t)}})}removeAllListeners(){this.listeners.clear()}}function E(e,t){const n=t.transform;e.emit("transform",n),e.emit("zoom",n.scale),e.emit("pan",{x:n.translateX,y:n.translateY})}const Y=300,X=5;function $(e,t){if(!e?.getBounds)return t;try{const n=e.getBounds(),r=n.width*n.height;return t*(r/2073600)**1}catch(e){return console.warn("Failed to calculate adaptive zoom speed, using base speed:",e),t}}function I(e,t){function n(n){if(!(n instanceof KeyboardEvent))return;if("canvas"===t.bindKeyboardEventsTo&&document.activeElement!==e.container)return;let r=!1;const o={};switch(n.key){case"ArrowLeft":o.translateX=e.transform.translateX+t.keyboardPanStep,r=!0;break;case"ArrowRight":o.translateX=e.transform.translateX-t.keyboardPanStep,r=!0;break;case"ArrowUp":o.translateY=e.transform.translateY+t.keyboardPanStep,r=!0;break;case"ArrowDown":o.translateY=e.transform.translateY-t.keyboardPanStep,r=!0;break;case"=":case"+":{const n=t.enableAdaptiveSpeed?$(e,t.keyboardZoomStep):t.keyboardZoomStep;e.zoomIn(n),r=!0}break;case"-":{const n=t.enableAdaptiveSpeed?$(e,t.keyboardZoomStep):t.keyboardZoomStep;e.zoomOut(n),r=!0}break;case"0":n.ctrlKey?(e.resetView&&e.resetView(),r=!0):(n.metaKey||n.ctrlKey)&&(e.resetViewToCenter&&e.resetViewToCenter(),r=!0);break;case"g":case"G":n.shiftKey&&e.toggleGrid&&e.toggleGrid(),r=n.shiftKey;break;case"r":case"R":!n.shiftKey||n.metaKey||n.ctrlKey||n.altKey||!e.toggleRulers||(e.toggleRulers(),r=!0)}r&&(n.preventDefault(),Object.keys(o).length>0&&e.updateTransform(o))}const r="canvas"===t.bindKeyboardEventsTo?e.container:document;return r.addEventListener("keydown",n),()=>{r.removeEventListener("keydown",n)}}function B(e,t,n,r,o){n?t.requireSpaceForMouseDrag?e.container.style.cursor=r?"grab":"default":e.container.style.cursor=o?"grabbing":"grab":e.container.style.cursor="default"}function Z(e,t,n,r,o){o.setIsDragging(!1),o.setDragButton(-1),B(e,t,n,r,!1)}function F(e,t,n,r,o,a,s,i,l,c){a&&e.button===s&&Z(t,n,r,o,{setIsDragging:c.setIsDragging,setDragButton:c.setDragButton}),r&&0===e.button&&n.enableClickToZoom&&i>0&&function(e,t,n,r,o,a){const s=Date.now()-r,i=e.altKey,l=!n.requireOptionForClickZoom||i;if(s<Y&&!o&&!a&&l){e.preventDefault();const r=t.container.getBoundingClientRect(),o=e.clientX-r.left,a=e.clientY-r.top,{clickX:s,clickY:i}=g(t,o,a,n.rulerSize,(e,t)=>({clickX:e,clickY:t})),l=t.canvasToContent(s,i),c=r.width/2,u=r.height/2,d=n.clickZoomLevel,h={scale:d,translateX:c-l.x*d,translateY:u-l.y*d};y(t.transformLayer,t.config,()=>{t.updateTransform(h)})}}(e,t,n,i,l,a),0===e.button&&function(e){e.setMouseDownTime(0),e.setHasDragged(!1)}({setMouseDownTime:c.setMouseDownTime,setHasDragged:c.setHasDragged})}function O(e,t,n=!0){let r=!0,o=!1,a=0,s=0,i=-1,l=!1,c=0,u=0,h=0,g=!1;const m={setIsDragging:e=>{o=e},setDragButton:e=>{i=e},setIsSpacePressed:e=>{l=e},setMouseDownTime:e=>{c=e},setMouseDownX:e=>{u=e},setMouseDownY:e=>{h=e},setHasDragged:e=>{g=e},setLastMouseX:e=>{a=e},setLastMouseY:e=>{s=e}},p=n=>{!function(e,t,n,r,o,a){n.requireSpaceForMouseDrag&&" "===e.key&&(a.setIsSpacePressed(!0),B(t,n,r,!0,o))}(n,e,t,r,o,{setIsSpacePressed:m.setIsSpacePressed})},f=n=>{!function(e,t,n,r,o,a){n.requireSpaceForMouseDrag&&" "===e.key&&(a.setIsSpacePressed(!1),B(t,n,r,!1,o),o&&Z(t,n,r,!1,{setIsDragging:a.setIsDragging,setDragButton:a.setDragButton}))}(n,e,t,r,o,{setIsSpacePressed:m.setIsSpacePressed,setIsDragging:m.setIsDragging,setDragButton:m.setDragButton})},b=n=>{!function(e,t,n,r,o,a){const s=0===e.button,i=1===e.button;if(s&&(a.setMouseDownTime(Date.now()),a.setMouseDownX(e.clientX),a.setMouseDownY(e.clientY),a.setHasDragged(!1)),!r)return;(!n.requireSpaceForMouseDrag||o)&&(s&&n.enableLeftDrag||i&&n.enableMiddleDrag)&&(e.preventDefault(),a.setDragButton(e.button),a.setLastMouseX(e.clientX),a.setLastMouseY(e.clientY),B(t,n,r,o,!1))}(n,e,t,r,l,m)},y=n=>{!function(e,t,n,r,o,a,s,i,l,c,u,h){if(s>0){const t=Math.abs(e.clientX-i),s=Math.abs(e.clientY-l);if(t>X||s>X){h.setHasDragged(!0);const e=!n.requireSpaceForMouseDrag||a;!o&&r&&e&&h.setIsDragging(!0)}}if(!o||!r)return;e.preventDefault(),d((...e)=>{const n=e[0];if(!o||!r)return;const a=n.clientX-c,s=n.clientY-u,i={translateX:t.transform.translateX+a,translateY:t.transform.translateY+s};t.updateTransform(i),h.setLastMouseX(n.clientX),h.setLastMouseY(n.clientY)})(e)}(n,e,t,r,o,l,c,u,h,a,s,{setHasDragged:m.setHasDragged,setIsDragging:m.setIsDragging,setLastMouseX:m.setLastMouseX,setLastMouseY:m.setLastMouseY})},v=n=>{F(n,e,t,r,l,o,i,c,g,{setIsDragging:m.setIsDragging,setDragButton:m.setDragButton,setMouseDownTime:m.setMouseDownTime,setHasDragged:m.setHasDragged})},w=()=>{!function(e,t,n,r,o,a){o&&Z(e,t,n,r,a)}(e,t,r,l,o,{setIsDragging:m.setIsDragging,setDragButton:m.setDragButton})};e.container.addEventListener("mousedown",b),document.addEventListener("mousemove",y),document.addEventListener("mouseup",v),e.container.addEventListener("mouseleave",w),t.requireSpaceForMouseDrag&&(document.addEventListener("keydown",p),document.addEventListener("keyup",f)),B(e,t,r,l,o);const k=()=>{e.container.removeEventListener("mousedown",b),document.removeEventListener("mousemove",y),document.removeEventListener("mouseup",v),e.container.removeEventListener("mouseleave",w),t.requireSpaceForMouseDrag&&(document.removeEventListener("keydown",p),document.removeEventListener("keyup",f))};return n?{cleanup:k,enable:()=>(r=!0,B(e,t,r,l,o),!0),disable:()=>(r=!1,o&&Z(e,t,r,l,{setIsDragging:m.setIsDragging,setDragButton:m.setDragButton}),B(e,t,r,l,o),!0),isEnabled:()=>r}:k}function V(e,t,n,r){try{switch(t){case"zoomIn":e.zoomIn(n);break;case"zoomOut":e.zoomOut(n);break;case"setZoom":{const t=n;if("number"!=typeof t||t<=0)throw new Error(`Invalid zoom level: ${t}. Must be a positive number.`);e.setZoom(t);break}case"resetZoom":e.resetZoom();break;case"panLeft":e.panLeft(n);break;case"panRight":e.panRight(n);break;case"panUp":e.panUp(n);break;case"panDown":e.panDown(n);break;case"fitToScreen":e.fitToScreen();break;case"centerContent":e.centerContent();break;case"panToPoint":{const t=n;e.panToPoint(t.x,t.y);break}case"resetView":e.resetView();break;case"resetViewToCenter":e.resetViewToCenter();break;case"toggleRulers":e.toggleRulers();break;case"showRulers":e.showRulers();break;case"hideRulers":e.hideRulers();break;case"toggleGrid":e.toggleGrid();break;case"showGrid":e.showGrid();break;case"hideGrid":e.hideGrid();break;case"updateThemeMode":{const t=n;if("light"!==t&&"dark"!==t)throw new Error(`Invalid theme mode: ${t}`);e.updateThemeMode(t);break}case"toggleThemeMode":{const t="light"===e.getConfig().themeMode?"dark":"light";e.updateThemeMode(t);break}case"updateTransition":{const t=n;if("boolean"!=typeof t)throw new Error(`Invalid transition enabled value: ${t}. Must be a boolean.`);e.updateTransition(t);break}case"toggleTransitionMode":e.toggleTransitionMode();break;default:throw new Error(`Unknown action: ${t}`)}}catch(e){!function(e,t,n){window.postMessage({source:"markup-canvas-error",canvasName:e,action:t,error:n,timestamp:Date.now()},"*")}(r,t,e instanceof Error?e.message:String(e))}}function A(e,t){return{x:(e.clientX+t.clientX)/2,y:(e.clientY+t.clientY)/2}}function _(e,t){const n=e.clientX-t.clientX,r=e.clientY-t.clientY;return Math.sqrt(n*n+r*r)}function G(e,t,n,r){const o=s(n,r,e.transform,t,e.config);return e.updateTransform(o)}function K(e,t,n){e.preventDefault();const r=Array.from(e.touches);d((...e)=>{const r=e[0];if(1===r.length){if(1===n.touches.length){const e=r[0].clientX-n.touches[0].clientX,o=r[0].clientY-n.touches[0].clientY,a={translateX:t.transform.translateX+e,translateY:t.transform.translateY+o};t.updateTransform(a)}}else if(2===r.length){const e=_(r[0],r[1]),o=A(r[0],r[1]);if(n.lastDistance>0){const r=e/n.lastDistance,a=t.container.getBoundingClientRect();let s=o.x-a.left,i=o.y-a.top;const l=function(e,t,n,r){return h(e,t,e=>{const t={...n,x:n.x-e,y:n.y-e};return r(t)})}(t,t.config.rulerSize,{x:s,y:i},e=>e);s=l.x,i=l.y,G(t,r,s,i)}n.lastDistance=e,n.lastCenter=o}n.touches=r})(r)}function H(e){const t={touches:[],lastDistance:0,lastCenter:{}},n=e=>{!function(e,t){e.preventDefault(),t.touches=Array.from(e.touches),2===t.touches.length&&(t.lastDistance=_(t.touches[0],t.touches[1]),t.lastCenter=A(t.touches[0],t.touches[1]))}(e,t)},r=n=>{K(n,e,t)},o=e=>{!function(e,t){t.touches=Array.from(e.touches),t.touches.length<2&&(t.lastDistance=0)}(e,t)};return e.container.addEventListener("touchstart",n,{passive:!1}),e.container.addEventListener("touchmove",r,{passive:!1}),e.container.addEventListener("touchend",o,{passive:!1}),()=>{e.container.removeEventListener("touchstart",n),e.container.removeEventListener("touchmove",r),e.container.removeEventListener("touchend",o)}}function N(e){const t=e.ctrlKey||e.metaKey,n=[0===e.deltaMode,Math.abs(e.deltaY)<50,e.deltaY%1!=0,Math.abs(e.deltaX)>0&&Math.abs(e.deltaY)>0].filter(Boolean).length>=2;return{isTrackpad:n,isMouseWheel:!n,isTrackpadScroll:n&&!t,isTrackpadPinch:n&&t,isZoomGesture:t}}function q(e,t){const n=(e=>d((...t)=>{const n=t[0];if(!n||!e?.updateTransform)return!1;try{const t=e.transform,r=1,o=n.deltaX*r,a=n.deltaY*r,s={scale:t.scale,translateX:t.translateX-o,translateY:t.translateY-a};return b(e.transformLayer,e.config),e.updateTransform(s)}catch(e){return console.error("Error handling trackpad pan:",e),!1}}))(e),r=r=>N(r).isTrackpadScroll?n(r):function(e,t,n){if(!e||"number"!=typeof e.deltaY)return console.warn("Invalid wheel event provided"),!1;if(!t?.updateTransform)return console.warn("Invalid canvas provided to handleWheelEvent"),!1;try{e.preventDefault();const r=t.container.getBoundingClientRect(),o=e.clientX-r.left,a=e.clientY-r.top,{mouseX:s,mouseY:i}=g(t,o,a,n.rulerSize,(e,t)=>({mouseX:e,mouseY:t})),l=n.zoomSpeed,c=N(e);if(!c.isZoomGesture)return!1;let u=n.enableAdaptiveSpeed?$(t,l):l;if(c.isTrackpadPinch){const e=.05*n.zoomSpeed;u=n.enableAdaptiveSpeed?$(t,e):e}return G(t,(e.deltaY<0?1:-1)>0?1+u:1/(1+u),s,i)}catch(e){return console.error("Error handling wheel event:",e),!1}}(r,e,t);return e.container.addEventListener("wheel",r,{passive:!1}),()=>{e.container.removeEventListener("wheel",r)}}const U=100,W=1e3,j=1001,J=4,Q=4,ee=100,te=100,ne=20,re=200;function oe(e,t){const n=function(e){const t=document.createElement("div");return t.className="canvas-ruler horizontal-ruler",t.style.cssText=`\n\tposition: absolute;\n\ttop: 0;\n\tleft: ${e.rulerSize}px;\n\tright: 0;\n\theight: ${e.rulerSize}px;\n\tbackground: var(--ruler-background-color);\n\tborder-bottom: 1px solid var(--ruler-border-color);\n\tborder-right: 1px solid var(--ruler-border-color);\n\tz-index: ${W};\n\tpointer-events: none;\n\tfont-family: ${e.rulerFontFamily};\n\tfont-size: ${e.rulerFontSize}px;\n\tcolor: var(--ruler-text-color);\n\toverflow: hidden;\n `,t}(t),r=function(e){const t=document.createElement("div");return t.className="canvas-ruler vertical-ruler",t.style.cssText=`\n\tposition: absolute;\n\ttop: ${e.rulerSize}px;\n\tleft: 0;\n\tbottom: 0;\n\twidth: ${e.rulerSize}px;\n\tbackground: var(--ruler-background-color);\n\tborder-right: 1px solid var(--ruler-border-color);\n\tborder-bottom: 1px solid var(--ruler-border-color);\n\tz-index: ${W};\n\tpointer-events: none;\n\tfont-family: ${e.rulerFontFamily};\n\tfont-size: ${e.rulerFontSize}px;\n\tcolor: var(--ruler-text-color);\n\toverflow: hidden;\n `,t}(t),o=function(e){const t=document.createElement("div");return t.className="canvas-ruler corner-box",t.style.cssText=`\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\tleft: 0;\n\t\twidth: ${e.rulerSize}px;\n\t\theight: ${e.rulerSize}px;\n\t\tbackground: var(--ruler-background-color);\n\t\tborder-right: 1px solid var(--ruler-border-color);\n\t\tborder-bottom: 1px solid var(--ruler-border-color);\n\t\tz-index: ${j};\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tfont-family: ${e.rulerFontFamily};\n\t\tfont-size: ${e.rulerFontSize-2}px;\n\t\tcolor: var(--ruler-text-color);\n\t\tpointer-events: none;\n\t`,t.textContent=e.rulerUnits,t}(t),a=t.enableGrid?function(e){const t=document.createElement("div");return t.className="canvas-ruler grid-overlay",t.style.cssText=`\n\t\tposition: absolute;\n\t\ttop: ${e.rulerSize}px;\n\t\tleft: ${e.rulerSize}px;\n\t\tright: 0;\n\t\tbottom: 0;\n\t\tpointer-events: none;\n\t\tz-index: ${U};\n\t\tbackground-image: \n\t\t\tlinear-gradient(var(--grid-color) 1px, transparent 1px),\n\t\t\tlinear-gradient(90deg, var(--grid-color) 1px, transparent 1px);\n\t\tbackground-size: 100px 100px;\n\t\topacity: 0.5;\n\t`,t}(t):void 0;return e.appendChild(n),e.appendChild(r),e.appendChild(o),a&&e.appendChild(a),{horizontalRuler:n,verticalRuler:r,cornerBox:o,gridOverlay:a}}function ae(e,t){const n=e/Math.max(5,Math.min(20,t/50)),r=10**Math.floor(Math.log10(n)),o=n/r;let a;return a=o<=1?1:o<=2?2:o<=5?5:10,a*r}function se(e,t,n,r,o){const a=document.createElement("div");a.className="tick",a.style.cssText=`\n\t\tposition: absolute;\n\t\tleft: ${n}px;\n\t\tbottom: 0;\n\t\twidth: 1px;\n\t\theight: ${J}px;\n\t\tbackground: var(--ruler-tick-color);\n\t`,e.appendChild(a);if(t%ee===0){const r=document.createElement("div");r.style.cssText=`\n\t\t\tposition: absolute;\n\t\t\tleft: ${n}px;\n\t\t\tbottom: ${J+2}px;\n\t\t\tfont-size: ${o.rulerFontSize}px;\n\t\t\tline-height: 1;\n\t\t\tcolor: var(--ruler-text-color);\n\t\t\twhite-space: nowrap;\n\t\t\tpointer-events: none;\n\t\t`,r.textContent=Math.round(t).toString(),e.appendChild(r)}}function ie(e,t,n,r,o){const a=document.createElement("div");a.className="tick",a.style.cssText=`\n\t\tposition: absolute;\n\t\ttop: ${n}px;\n\t\tright: 0;\n\t\twidth: ${Q}px;\n\t\theight: 1px;\n\t\tbackground: var(--ruler-tick-color);\n\t`,e.appendChild(a);if(t%ee===0){const r=document.createElement("div");r.style.cssText=`\n\t\t\tposition: absolute;\n\t\t\ttop: ${n-6}px;\n\t\t\tright: ${Q+6}px;\n\t\t\tfont-size: ${o.rulerFontSize}px;\n\t\t\tline-height: 1;\n\t\t\tcolor: var(--ruler-text-color);\n\t\t\twhite-space: nowrap;\n\t\t\tpointer-events: none;\n\t\t\ttransform: rotate(-90deg);\n\t\t\ttransform-origin: right center;\n\t\t`,r.textContent=Math.round(t).toString(),e.appendChild(r)}}function le(e,t,n,r,o){const a=e.getBounds(),s=a.scale||1,i=a.translateX||0,l=a.translateY||0,c=a.width-o.rulerSize,u=a.height-o.rulerSize,d=-i/s,h=-l/s,g=h+u/s;!function(e,t,n,r,o,a){const s=r,i=ae(n-t,s),l=document.createDocumentFragment(),c=Math.floor(t/i)*i,u=Math.ceil(n/i)*i;for(let e=c;e<=u;e+=i){const n=(e-t)*o;n>=-50&&n<=s+50&&se(l,e,n,0,a)}e.innerHTML="",e.appendChild(l)}(t,d,d+c/s,c,s,o),function(e,t,n,r,o,a){const s=r,i=ae(n-t,s),l=document.createDocumentFragment(),c=Math.floor(t/i)*i,u=Math.ceil(n/i)*i;for(let e=c;e<=u;e+=i){const n=(e-t)*o;n>=-50&&n<=s+50&&ie(l,e,n,0,a)}e.innerHTML="",e.appendChild(l)}(n,h,g,u,s,o),r&&function(e,t,n,r){let o=te*t;for(;o<ne;)o*=2;for(;o>re;)o/=2;e.style.backgroundSize=`${o}px ${o}px`,e.style.backgroundPosition=`${n%o}px ${r%o}px`}(r,s,i,l)}function ce(e,t){const n=m(t,"rulerBackgroundColor"),r=m(t,"rulerBorderColor"),o=m(t,"rulerTextColor"),a=m(t,"rulerTickColor"),s=m(t,"gridColor");e.horizontalRuler&&(e.horizontalRuler.style.setProperty("--ruler-background-color",n),e.horizontalRuler.style.setProperty("--ruler-border-color",r),e.horizontalRuler.style.setProperty("--ruler-text-color",o),e.horizontalRuler.style.setProperty("--ruler-tick-color",a)),e.verticalRuler&&(e.verticalRuler.style.setProperty("--ruler-background-color",n),e.verticalRuler.style.setProperty("--ruler-border-color",r),e.verticalRuler.style.setProperty("--ruler-text-color",o),e.verticalRuler.style.setProperty("--ruler-tick-color",a)),e.cornerBox&&(e.cornerBox.style.setProperty("--ruler-background-color",n),e.cornerBox.style.setProperty("--ruler-border-color",r),e.cornerBox.style.setProperty("--ruler-text-color",o)),e.gridOverlay&&e.gridOverlay.style.setProperty("--grid-color",s)}function ue(e,t){if(!e?.container)return console.error("Invalid canvas provided to createRulers"),null;let n,r=null,o=!1;const a=()=>{!o&&n.horizontalRuler&&n.verticalRuler&&le(e,n.horizontalRuler,n.verticalRuler,n.gridOverlay,t)};try{return n=oe(e.container,t),r=function(e,t){const n=d(t),r=e.updateTransform;e.updateTransform=function(e){const t=r.call(this,e);return n(),t};const o=d(t);return window.addEventListener("resize",o),()=>{window.removeEventListener("resize",o),e.updateTransform=r,n.cleanup(),o.cleanup()}}(e,a),ce(n,t),a(),t.showRulers||(n.horizontalRuler.style.display="none",n.verticalRuler.style.display="none",n.cornerBox.style.display="none"),!t.showGrid&&n.gridOverlay&&(n.gridOverlay.style.display="none"),{horizontalRuler:n.horizontalRuler,verticalRuler:n.verticalRuler,cornerBox:n.cornerBox,gridOverlay:n.gridOverlay,update:a,updateTheme:e=>{o||ce(n,e)},show:()=>{n.horizontalRuler&&(n.horizontalRuler.style.display="block"),n.verticalRuler&&(n.verticalRuler.style.display="block"),n.cornerBox&&(n.cornerBox.style.display="flex")},hide:()=>{n.horizontalRuler&&(n.horizontalRuler.style.display="none"),n.verticalRuler&&(n.verticalRuler.style.display="none"),n.cornerBox&&(n.cornerBox.style.display="none"),n.gridOverlay&&(n.gridOverlay.style.display="none")},toggleGrid:()=>{if(n.gridOverlay){const e="none"!==n.gridOverlay.style.display;n.gridOverlay.style.display=e?"none":"block"}},destroy:()=>{o=!0,r&&r(),n.horizontalRuler?.parentNode&&n.horizontalRuler.parentNode.removeChild(n.horizontalRuler),n.verticalRuler?.parentNode&&n.verticalRuler.parentNode.removeChild(n.verticalRuler),n.cornerBox?.parentNode&&n.cornerBox.parentNode.removeChild(n.cornerBox),n.gridOverlay?.parentNode&&n.gridOverlay.parentNode.removeChild(n.gridOverlay)}}}catch(e){return console.error("Failed to create rulers:",e),null}}return class{constructor(e,t={}){if(this.cleanupCallbacks=[],this.rulers=null,this.dragSetup=null,this.keyboardCleanup=null,this.event=new P,this._isReady=!1,!e)throw new Error("Container element is required");this.config=M(t);const n=R(e,this.config);if(!n)throw new Error("Failed to create canvas");if(this.canvas=n,u(this.config,"enableRulers",()=>{this.rulers=ue(this,this.config),this.cleanupCallbacks.push(()=>{this.rulers&&this.rulers.destroy()})}),t.themeMode&&S(this.canvas.container,this.config,this.rulers,t.themeMode),this.event.setEmitInterceptor((e,t)=>{!function(e,t,n){if("undefined"==typeof window)return;let r=t;"ready"===e&&(r={ready:!0});const o=n.name||"markupCanvas";window.postMessage({source:"markup-canvas",action:e,data:r,timestamp:Date.now(),canvasName:o},"*"),window.parent&&window.parent.postMessage({source:"markup-canvas",action:e,data:r,timestamp:Date.now(),canvasName:o},"*")}(e,t,this.config)}),function(e,t){if("undefined"==typeof window)return;const n=t.name||"markupCanvas",r=window,o={config:{get current(){return e.config},get:e.getConfig.bind(e),update:e.updateConfig.bind(e)},transform:{update:e.updateTransform.bind(e),reset:e.reset.bind(e)},zoom:{get current(){return e.transform.scale||1},set:e.setZoom.bind(e),toPoint:e.zoomToPoint.bind(e),in:e.zoomIn.bind(e),out:e.zoomOut.bind(e),reset:e.resetZoom.bind(e),resetToCenter:e.resetViewToCenter.bind(e),fitToScreen:e.fitToScreen.bind(e)},pan:{left:e.panLeft.bind(e),right:e.panRight.bind(e),up:e.panUp.bind(e),down:e.panDown.bind(e),toPoint:e.panToPoint.bind(e),toCenter:e.centerContent.bind(e)},mouseDrag:{enable:e.enableMouseDrag.bind(e),disable:e.disableMouseDrag.bind(e),isEnabled:e.isMouseDragEnabled.bind(e)},keyboard:{enable:e.enableKeyboard.bind(e),disable:e.disableKeyboard.bind(e),isEnabled:e.isKeyboardEnabled.bind(e)},grid:{toggle:e.toggleGrid.bind(e),show:e.showGrid.bind(e),hide:e.hideGrid.bind(e),isVisible:e.isGridVisible.bind(e)},rulers:{toggle:e.toggleRulers.bind(e),show:e.showRulers.bind(e),hide:e.hideRulers.bind(e),isVisible:e.areRulersVisible.bind(e)},canvas:{canvasToContent:e.canvasToContent.bind(e),getVisibleArea:e.getVisibleArea.bind(e),isPointVisible:e.isPointVisible.bind(e),getBounds:e.getBounds.bind(e)},theme:{get current(){return e.config.themeMode},update:e.updateThemeMode.bind(e),toggle:e.toggleThemeMode.bind(e)},transition:{get current(){return e.config.enableTransition},set:e.updateTransition.bind(e),toggle:e.toggleTransitionMode.bind(e)},event:e.event,lifecycle:{cleanup:e.cleanup.bind(e),destroy:e.destroy.bind(e)},state:{get isReady(){return e.isReady},get isTransforming(){return e.isTransforming},get visibleBounds(){return e.visibleBounds},get transform(){return e.transform}}};r[n]=o,r.__markupCanvasInstances||(r.__markupCanvasInstances=new Map),r.__markupCanvasInstances.set(n,o)}(this,this.config),this.config.enablePostMessageAPI){const e=function(e){const t=t=>{const n=t.data;if(!["markup-canvas","application"].includes(n.source))return;const r=e.config.name||"markupCanvas";if(n.canvasName!==r)return;const o=n.action,a=n.data;V(e,o,a,r)};return"undefined"!=typeof window&&window.addEventListener("message",t),()=>{"undefined"!=typeof window&&window.removeEventListener("message",t)}}(this);this.cleanupCallbacks.push(e)}this.setupEventHandlers(),this._isReady=!0,this.event.emit("ready",this)}setupEventHandlers(){try{u(this.config,"enableZoom",()=>{const e=q(this,this.config);this.cleanupCallbacks.push(e)}),(this.config.enablePan||this.config.enableClickToZoom)&&(this.dragSetup=O(this,this.config,!0),this.cleanupCallbacks.push(this.dragSetup.cleanup)),u(this.config,"enableKeyboard",()=>{const e=I(this,this.config);this.keyboardCleanup=e,this.cleanupCallbacks.push(e)}),u(this.config,"enableTouch",()=>{const e=H(this);this.cleanupCallbacks.push(e)})}catch(e){throw console.error("Failed to set up event handlers:",e),this.cleanup(),e}}get container(){return this.canvas.container}get transformLayer(){return this.canvas.transformLayer}get contentLayer(){return this.canvas.contentLayer}get transform(){return this.canvas.transform}get isReady(){return this._isReady}get isTransforming(){return this.dragSetup?.isEnabled()||!1}get visibleBounds(){return i(this)}getBounds(){return f(this.canvas,this.config)}updateTransform(e){const t=C(this.canvas,e);return t&&E(this.event,this.canvas),t}reset(){const e=C(this.canvas,{scale:1,translateX:0,translateY:0});return e&&E(this.event,this.canvas),e}setZoom(e){return function(e,t,n,r,o){return y(t,n,()=>l(n,t=>{const n=t(o),a=D(e);return r(a.x,a.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this),e)}canvasToContent(t,r){return e(t,r,n(this.canvas.transform.scale,this.canvas.transform.translateX,this.canvas.transform.translateY))}zoomToPoint(e,t,n){const r=function(e,t,n,r,o,a){return y(t,n,()=>{const t=s(r,o,e.transform,a/e.transform.scale,n);return C(e,t)})}(this.canvas,this.transformLayer,this.config,e,t,n);return r&&E(this.event,this.canvas),r}resetView(){return e=this.canvas,t=this.transformLayer,n=this.config,y(t,n,()=>h(e,n.rulerSize,t=>C(e,{scale:1,translateX:-1*t,translateY:-1*t})));var e,t,n}resetViewToCenter(){return function(e,t,n,r){return y(t,n,()=>l(n,t=>{const n=t(1),o=D(e);return r(o.x,o.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this))}panLeft(e){return w(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&w(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}panRight(e){return k(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&k(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}panUp(e){return x(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&x(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}panDown(e){return v(this.canvas,this.config,this.updateTransform.bind(this))||!!e&&v(this.canvas,{...this.config,keyboardPanStep:e},this.updateTransform.bind(this))}zoomIn(e=.5){return function(e,t,n,r,o=.5){return y(t,n,()=>l(n,t=>{const n=t(e.transform.scale*(1+o)),a=D(e);return r(a.x,a.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this),e)}zoomOut(e=.5){return function(e,t,n,r,o=.5){return y(t,n,()=>l(n,t=>{const n=t(e.transform.scale*(1-o)),a=D(e);return r(a.x,a.y,n)}))}(this,this.transformLayer,this.config,this.zoomToPoint.bind(this),e)}resetZoom(){return this.resetViewToCenter()}enableMouseDrag(){return this.dragSetup?.enable()??!1}disableMouseDrag(){return this.dragSetup?.disable()??!1}isMouseDragEnabled(){return this.dragSetup?.isEnabled()??!1}enableKeyboard(){return this.keyboardCleanup||(this.keyboardCleanup=I(this,this.config),this.cleanupCallbacks.push(this.keyboardCleanup)),!0}disableKeyboard(){return!!this.keyboardCleanup&&(this.keyboardCleanup(),this.keyboardCleanup=null,!0)}isKeyboardEnabled(){return null!==this.keyboardCleanup}toggleGrid(){const e=(t=this.rulers,!!t?.toggleGrid&&(t.toggleGrid(),!0));var t;return e&&this.event.emit("gridVisibility",this.isGridVisible()),e}showGrid(){const e=(t=this.rulers,!!t?.gridOverlay&&(t.gridOverlay.style.display="block",!0));var t;return e&&this.event.emit("gridVisibility",!0),e}hideGrid(){const e=(t=this.rulers,!!t?.gridOverlay&&(t.gridOverlay.style.display="none",!0));var t;return e&&this.event.emit("gridVisibility",!1),e}isGridVisible(){return e=this.rulers,!!e?.gridOverlay&&"none"!==e.gridOverlay.style.display;var e}toggleRulers(){const e=function(e,t){if(e)return t()?e.hide():e.show(),!0;return!1}(this.rulers,()=>this.areRulersVisible());return e&&this.event.emit("rulersVisibility",this.areRulersVisible()),e}showRulers(){const e=!!(t=this.rulers)&&(t.show(),!0);var t;return e&&this.event.emit("rulersVisibility",!0),e}hideRulers(){const e=!!(t=this.rulers)&&(t.hide(),!0);var t;return e&&this.event.emit("rulersVisibility",!1),e}areRulersVisible(){return e=this.rulers,!!e?.horizontalRuler&&"none"!==e.horizontalRuler.style.display;var e}centerContent(){return e=this.canvas,t=this.config,n=this.updateTransform.bind(this),y(this.transformLayer,t,()=>{const r=f(e,t),o=(r.width-r.contentWidth*e.transform.scale)/2,a=(r.height-r.contentHeight*e.transform.scale)/2;return n({translateX:o,translateY:a})});var e,t,n}fitToScreen(){return e=this.canvas,t=this.transformLayer,n=this.config,y(t,n,()=>{const t=f(e,n),r=t.width/n.width,o=t.height/n.height,a=l(n,e=>e(.9*Math.min(r,o))),s=n.width*a,i=n.height*a,c=(t.width-s)/2,u=(t.height-i)/2;return C(e,{scale:a,translateX:c,translateY:u})});var e,t,n}getVisibleArea(){return i(this)}isPointVisible(e,t){return function(e,t,n){const r=i(e);return t>=r.x&&t<=r.x+r.width&&n>=r.y&&n<=r.y+r.height}(this,e,t)}panToPoint(e,t){return function(e,t,n,r,o,a){return y(a,t,()=>{const a=f(e,t),s=a.width/2,i=a.height/2,l=s-n*e.transform.scale,c=i-r*e.transform.scale;return o({translateX:l,translateY:c})})}(this.canvas,this.config,e,t,this.updateTransform.bind(this),this.transformLayer)}getConfig(){return{...this.config}}updateConfig(e){this.config=M({...this.config,...e})}updateThemeMode(e){this.config=M({...this.config,themeMode:e}),S(this.canvas.container,this.config,this.rulers,e)}toggleThemeMode(){const e="light"===this.config.themeMode?"dark":"light";return this.updateThemeMode(e),e}updateTransition(e){this.config=M({...this.config,enableTransition:e})}toggleTransitionMode(){const e=function(e){return!e}(this.config.enableTransition);return this.updateTransition(e),e}cleanup(){!function(e){if("undefined"==typeof window)return;const t=e.name||"markupCanvas",n=window;delete n[t],n.__markupCanvasInstances&&n.__markupCanvasInstances.delete(t)}(this.config),this.cleanupCallbacks.forEach(e=>{try{e()}catch(e){console.warn("Error during cleanup:",e)}}),this.cleanupCallbacks=[],this.removeAllListeners()}on(e,t){this.event.on(e,t)}off(e,t){this.event.off(e,t)}emit(e,t){this.event.emit(e,t)}removeAllListeners(){this.event.removeAllListeners()}destroy(){this.cleanup(),window.__markupCanvasTransitionTimeout&&clearTimeout(window.__markupCanvasTransitionTimeout)}}});
|
package/package.json
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { MarkupCanvas } from "@/lib/MarkupCanvas.js";
|
|
2
|
+
import type { PostMessageAction } from "@/types/events";
|
|
3
|
+
import { sendPostMessageError } from "./sendPostMessageError";
|
|
4
|
+
|
|
5
|
+
export function processPostMessage(
|
|
6
|
+
canvas: MarkupCanvas,
|
|
7
|
+
action: PostMessageAction,
|
|
8
|
+
payload: string | number | boolean | object,
|
|
9
|
+
canvasName: string
|
|
10
|
+
): void {
|
|
11
|
+
try {
|
|
12
|
+
// View methods
|
|
13
|
+
switch (action) {
|
|
14
|
+
case "zoomIn":
|
|
15
|
+
canvas.zoomIn(payload as number | undefined);
|
|
16
|
+
break;
|
|
17
|
+
case "zoomOut":
|
|
18
|
+
canvas.zoomOut(payload as number | undefined);
|
|
19
|
+
break;
|
|
20
|
+
case "setZoom": {
|
|
21
|
+
const zoomLevel = payload as number;
|
|
22
|
+
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
23
|
+
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
24
|
+
}
|
|
25
|
+
canvas.setZoom(zoomLevel);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case "resetZoom":
|
|
29
|
+
canvas.resetZoom();
|
|
30
|
+
break;
|
|
31
|
+
case "panLeft":
|
|
32
|
+
canvas.panLeft(payload as number | undefined);
|
|
33
|
+
break;
|
|
34
|
+
case "panRight":
|
|
35
|
+
canvas.panRight(payload as number | undefined);
|
|
36
|
+
break;
|
|
37
|
+
case "panUp":
|
|
38
|
+
canvas.panUp(payload as number | undefined);
|
|
39
|
+
break;
|
|
40
|
+
case "panDown":
|
|
41
|
+
canvas.panDown(payload as number | undefined);
|
|
42
|
+
break;
|
|
43
|
+
case "fitToScreen":
|
|
44
|
+
canvas.fitToScreen();
|
|
45
|
+
break;
|
|
46
|
+
case "centerContent":
|
|
47
|
+
canvas.centerContent();
|
|
48
|
+
break;
|
|
49
|
+
case "panToPoint": {
|
|
50
|
+
const point = payload as { x: number; y: number };
|
|
51
|
+
canvas.panToPoint(point.x, point.y);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case "resetView":
|
|
55
|
+
canvas.resetView();
|
|
56
|
+
break;
|
|
57
|
+
case "resetViewToCenter":
|
|
58
|
+
canvas.resetViewToCenter();
|
|
59
|
+
break;
|
|
60
|
+
// Ruler/Grid methods
|
|
61
|
+
case "toggleRulers":
|
|
62
|
+
canvas.toggleRulers();
|
|
63
|
+
break;
|
|
64
|
+
case "showRulers":
|
|
65
|
+
canvas.showRulers();
|
|
66
|
+
break;
|
|
67
|
+
case "hideRulers":
|
|
68
|
+
canvas.hideRulers();
|
|
69
|
+
break;
|
|
70
|
+
case "toggleGrid":
|
|
71
|
+
canvas.toggleGrid();
|
|
72
|
+
break;
|
|
73
|
+
case "showGrid":
|
|
74
|
+
canvas.showGrid();
|
|
75
|
+
break;
|
|
76
|
+
case "hideGrid":
|
|
77
|
+
canvas.hideGrid();
|
|
78
|
+
break;
|
|
79
|
+
// Config methods
|
|
80
|
+
case "updateThemeMode": {
|
|
81
|
+
const mode = payload as "light" | "dark";
|
|
82
|
+
if (mode !== "light" && mode !== "dark") {
|
|
83
|
+
throw new Error(`Invalid theme mode: ${mode}`);
|
|
84
|
+
}
|
|
85
|
+
canvas.updateThemeMode(mode);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "toggleThemeMode": {
|
|
89
|
+
const currentConfig = canvas.getConfig();
|
|
90
|
+
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
91
|
+
canvas.updateThemeMode(newMode);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
// Transition methods
|
|
95
|
+
case "updateTransition": {
|
|
96
|
+
const enabled = payload as boolean;
|
|
97
|
+
if (typeof enabled !== "boolean") {
|
|
98
|
+
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
99
|
+
}
|
|
100
|
+
canvas.updateTransition(enabled);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
case "toggleTransitionMode":
|
|
104
|
+
canvas.toggleTransitionMode();
|
|
105
|
+
break;
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unknown action: ${action}`);
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
111
|
+
sendPostMessageError(canvasName, action, errorMessage);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MarkupCanvas } from "@/lib/MarkupCanvas.js";
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { PostMessageRequest } from "@/types/events";
|
|
3
|
+
import { processPostMessage } from "./processPostMessages";
|
|
4
4
|
|
|
5
5
|
export function setupPostMessageEvents(canvas: MarkupCanvas): () => void {
|
|
6
6
|
const handleMessage = (event: MessageEvent): void => {
|
|
@@ -16,84 +16,10 @@ export function setupPostMessageEvents(canvas: MarkupCanvas): () => void {
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const action = data.action
|
|
19
|
+
const action = data.action;
|
|
20
20
|
const payload = data.data as string | number | boolean | object;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
// View methods
|
|
24
|
-
if (action === "zoomIn") {
|
|
25
|
-
canvas.zoomIn(payload as number | undefined);
|
|
26
|
-
} else if (action === "zoomOut") {
|
|
27
|
-
canvas.zoomOut(payload as number | undefined);
|
|
28
|
-
} else if (action === "setZoom") {
|
|
29
|
-
const zoomLevel = payload as number;
|
|
30
|
-
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
31
|
-
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
32
|
-
}
|
|
33
|
-
canvas.setZoom(zoomLevel);
|
|
34
|
-
} else if (action === "resetZoom") {
|
|
35
|
-
canvas.resetZoom();
|
|
36
|
-
} else if (action === "panLeft") {
|
|
37
|
-
canvas.panLeft(payload as number | undefined);
|
|
38
|
-
} else if (action === "panRight") {
|
|
39
|
-
canvas.panRight(payload as number | undefined);
|
|
40
|
-
} else if (action === "panUp") {
|
|
41
|
-
canvas.panUp(payload as number | undefined);
|
|
42
|
-
} else if (action === "panDown") {
|
|
43
|
-
canvas.panDown(payload as number | undefined);
|
|
44
|
-
} else if (action === "fitToScreen") {
|
|
45
|
-
canvas.fitToScreen();
|
|
46
|
-
} else if (action === "centerContent") {
|
|
47
|
-
canvas.centerContent();
|
|
48
|
-
} else if (action === "panToPoint") {
|
|
49
|
-
canvas.panToPoint((payload as { x: number; y: number }).x, (payload as { x: number; y: number }).y);
|
|
50
|
-
} else if (action === "resetView") {
|
|
51
|
-
canvas.resetView();
|
|
52
|
-
} else if (action === "resetViewToCenter") {
|
|
53
|
-
canvas.resetViewToCenter();
|
|
54
|
-
}
|
|
55
|
-
// Ruler/Grid methods
|
|
56
|
-
else if (action === "toggleRulers") {
|
|
57
|
-
canvas.toggleRulers();
|
|
58
|
-
} else if (action === "showRulers") {
|
|
59
|
-
canvas.showRulers();
|
|
60
|
-
} else if (action === "hideRulers") {
|
|
61
|
-
canvas.hideRulers();
|
|
62
|
-
} else if (action === "toggleGrid") {
|
|
63
|
-
canvas.toggleGrid();
|
|
64
|
-
} else if (action === "showGrid") {
|
|
65
|
-
canvas.showGrid();
|
|
66
|
-
} else if (action === "hideGrid") {
|
|
67
|
-
canvas.hideGrid();
|
|
68
|
-
}
|
|
69
|
-
// Config methods
|
|
70
|
-
else if (action === "updateThemeMode") {
|
|
71
|
-
const mode = payload as "light" | "dark";
|
|
72
|
-
if (mode !== "light" && mode !== "dark") {
|
|
73
|
-
throw new Error(`Invalid theme mode: ${mode}`);
|
|
74
|
-
}
|
|
75
|
-
canvas.updateThemeMode(mode);
|
|
76
|
-
} else if (action === "toggleThemeMode") {
|
|
77
|
-
const currentConfig = canvas.getConfig();
|
|
78
|
-
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
79
|
-
canvas.updateThemeMode(newMode);
|
|
80
|
-
}
|
|
81
|
-
// Transition methods
|
|
82
|
-
else if (action === "updateTransition") {
|
|
83
|
-
const enabled = payload as boolean;
|
|
84
|
-
if (typeof enabled !== "boolean") {
|
|
85
|
-
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
86
|
-
}
|
|
87
|
-
canvas.updateTransition(enabled);
|
|
88
|
-
} else if (action === "toggleTransitionMode") {
|
|
89
|
-
canvas.toggleTransitionMode();
|
|
90
|
-
} else {
|
|
91
|
-
throw new Error(`Unknown action: ${action}`);
|
|
92
|
-
}
|
|
93
|
-
} catch (error) {
|
|
94
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
95
|
-
sendPostMessageError(canvasName, action, errorMessage);
|
|
96
|
-
}
|
|
22
|
+
processPostMessage(canvas, action, payload, canvasName);
|
|
97
23
|
};
|
|
98
24
|
|
|
99
25
|
if (typeof window !== "undefined") {
|
|
File without changes
|
|
File without changes
|