@markup-canvas/core 1.3.2 → 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 -65
- package/dist/markup-canvas.esm.js +73 -65
- package/dist/markup-canvas.umd.js +73 -65
- 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 -82
- /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,117 +1330,125 @@ function sendPostMessageError(canvasName, action, error) {
|
|
|
1330
1330
|
}, "*");
|
|
1331
1331
|
}
|
|
1332
1332
|
|
|
1333
|
-
function
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
}
|
|
1339
|
-
console.log("data", event.data);
|
|
1340
|
-
const canvasName = canvas.config.name || "markupCanvas";
|
|
1341
|
-
if (data.canvasName !== canvasName) {
|
|
1342
|
-
console.log("canvasName", data.canvasName, "!==", canvasName);
|
|
1343
|
-
return;
|
|
1344
|
-
}
|
|
1345
|
-
const action = data.action;
|
|
1346
|
-
const payload = data.data;
|
|
1347
|
-
try {
|
|
1348
|
-
// View methods
|
|
1349
|
-
if (action === "zoomIn") {
|
|
1350
|
-
console.log("zoomIn", payload);
|
|
1333
|
+
function processPostMessage(canvas, action, payload, canvasName) {
|
|
1334
|
+
try {
|
|
1335
|
+
// View methods
|
|
1336
|
+
switch (action) {
|
|
1337
|
+
case "zoomIn":
|
|
1351
1338
|
canvas.zoomIn(payload);
|
|
1352
|
-
|
|
1353
|
-
|
|
1339
|
+
break;
|
|
1340
|
+
case "zoomOut":
|
|
1354
1341
|
canvas.zoomOut(payload);
|
|
1355
|
-
|
|
1356
|
-
|
|
1342
|
+
break;
|
|
1343
|
+
case "setZoom": {
|
|
1357
1344
|
const zoomLevel = payload;
|
|
1358
1345
|
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
1359
1346
|
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
1360
1347
|
}
|
|
1361
1348
|
canvas.setZoom(zoomLevel);
|
|
1349
|
+
break;
|
|
1362
1350
|
}
|
|
1363
|
-
|
|
1351
|
+
case "resetZoom":
|
|
1364
1352
|
canvas.resetZoom();
|
|
1365
|
-
|
|
1366
|
-
|
|
1353
|
+
break;
|
|
1354
|
+
case "panLeft":
|
|
1367
1355
|
canvas.panLeft(payload);
|
|
1368
|
-
|
|
1369
|
-
|
|
1356
|
+
break;
|
|
1357
|
+
case "panRight":
|
|
1370
1358
|
canvas.panRight(payload);
|
|
1371
|
-
|
|
1372
|
-
|
|
1359
|
+
break;
|
|
1360
|
+
case "panUp":
|
|
1373
1361
|
canvas.panUp(payload);
|
|
1374
|
-
|
|
1375
|
-
|
|
1362
|
+
break;
|
|
1363
|
+
case "panDown":
|
|
1376
1364
|
canvas.panDown(payload);
|
|
1377
|
-
|
|
1378
|
-
|
|
1365
|
+
break;
|
|
1366
|
+
case "fitToScreen":
|
|
1379
1367
|
canvas.fitToScreen();
|
|
1380
|
-
|
|
1381
|
-
|
|
1368
|
+
break;
|
|
1369
|
+
case "centerContent":
|
|
1382
1370
|
canvas.centerContent();
|
|
1371
|
+
break;
|
|
1372
|
+
case "panToPoint": {
|
|
1373
|
+
const point = payload;
|
|
1374
|
+
canvas.panToPoint(point.x, point.y);
|
|
1375
|
+
break;
|
|
1383
1376
|
}
|
|
1384
|
-
|
|
1385
|
-
canvas.panToPoint(payload.x, payload.y);
|
|
1386
|
-
}
|
|
1387
|
-
else if (action === "resetView") {
|
|
1377
|
+
case "resetView":
|
|
1388
1378
|
canvas.resetView();
|
|
1389
|
-
|
|
1390
|
-
|
|
1379
|
+
break;
|
|
1380
|
+
case "resetViewToCenter":
|
|
1391
1381
|
canvas.resetViewToCenter();
|
|
1392
|
-
|
|
1382
|
+
break;
|
|
1393
1383
|
// Ruler/Grid methods
|
|
1394
|
-
|
|
1384
|
+
case "toggleRulers":
|
|
1395
1385
|
canvas.toggleRulers();
|
|
1396
|
-
|
|
1397
|
-
|
|
1386
|
+
break;
|
|
1387
|
+
case "showRulers":
|
|
1398
1388
|
canvas.showRulers();
|
|
1399
|
-
|
|
1400
|
-
|
|
1389
|
+
break;
|
|
1390
|
+
case "hideRulers":
|
|
1401
1391
|
canvas.hideRulers();
|
|
1402
|
-
|
|
1403
|
-
|
|
1392
|
+
break;
|
|
1393
|
+
case "toggleGrid":
|
|
1404
1394
|
canvas.toggleGrid();
|
|
1405
|
-
|
|
1406
|
-
|
|
1395
|
+
break;
|
|
1396
|
+
case "showGrid":
|
|
1407
1397
|
canvas.showGrid();
|
|
1408
|
-
|
|
1409
|
-
|
|
1398
|
+
break;
|
|
1399
|
+
case "hideGrid":
|
|
1410
1400
|
canvas.hideGrid();
|
|
1411
|
-
|
|
1401
|
+
break;
|
|
1412
1402
|
// Config methods
|
|
1413
|
-
|
|
1403
|
+
case "updateThemeMode": {
|
|
1414
1404
|
const mode = payload;
|
|
1415
1405
|
if (mode !== "light" && mode !== "dark") {
|
|
1416
1406
|
throw new Error(`Invalid theme mode: ${mode}`);
|
|
1417
1407
|
}
|
|
1418
1408
|
canvas.updateThemeMode(mode);
|
|
1409
|
+
break;
|
|
1419
1410
|
}
|
|
1420
|
-
|
|
1411
|
+
case "toggleThemeMode": {
|
|
1421
1412
|
const currentConfig = canvas.getConfig();
|
|
1422
1413
|
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
1423
1414
|
canvas.updateThemeMode(newMode);
|
|
1415
|
+
break;
|
|
1424
1416
|
}
|
|
1425
1417
|
// Transition methods
|
|
1426
|
-
|
|
1418
|
+
case "updateTransition": {
|
|
1427
1419
|
const enabled = payload;
|
|
1428
1420
|
if (typeof enabled !== "boolean") {
|
|
1429
1421
|
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
1430
1422
|
}
|
|
1431
1423
|
canvas.updateTransition(enabled);
|
|
1424
|
+
break;
|
|
1432
1425
|
}
|
|
1433
|
-
|
|
1426
|
+
case "toggleTransitionMode":
|
|
1434
1427
|
canvas.toggleTransitionMode();
|
|
1435
|
-
|
|
1436
|
-
|
|
1428
|
+
break;
|
|
1429
|
+
default:
|
|
1437
1430
|
throw new Error(`Unknown action: ${action}`);
|
|
1438
|
-
}
|
|
1439
1431
|
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
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;
|
|
1443
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);
|
|
1444
1452
|
};
|
|
1445
1453
|
if (typeof window !== "undefined") {
|
|
1446
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,117 +1326,125 @@ function sendPostMessageError(canvasName, action, error) {
|
|
|
1326
1326
|
}, "*");
|
|
1327
1327
|
}
|
|
1328
1328
|
|
|
1329
|
-
function
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
}
|
|
1335
|
-
console.log("data", event.data);
|
|
1336
|
-
const canvasName = canvas.config.name || "markupCanvas";
|
|
1337
|
-
if (data.canvasName !== canvasName) {
|
|
1338
|
-
console.log("canvasName", data.canvasName, "!==", canvasName);
|
|
1339
|
-
return;
|
|
1340
|
-
}
|
|
1341
|
-
const action = data.action;
|
|
1342
|
-
const payload = data.data;
|
|
1343
|
-
try {
|
|
1344
|
-
// View methods
|
|
1345
|
-
if (action === "zoomIn") {
|
|
1346
|
-
console.log("zoomIn", payload);
|
|
1329
|
+
function processPostMessage(canvas, action, payload, canvasName) {
|
|
1330
|
+
try {
|
|
1331
|
+
// View methods
|
|
1332
|
+
switch (action) {
|
|
1333
|
+
case "zoomIn":
|
|
1347
1334
|
canvas.zoomIn(payload);
|
|
1348
|
-
|
|
1349
|
-
|
|
1335
|
+
break;
|
|
1336
|
+
case "zoomOut":
|
|
1350
1337
|
canvas.zoomOut(payload);
|
|
1351
|
-
|
|
1352
|
-
|
|
1338
|
+
break;
|
|
1339
|
+
case "setZoom": {
|
|
1353
1340
|
const zoomLevel = payload;
|
|
1354
1341
|
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
1355
1342
|
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
1356
1343
|
}
|
|
1357
1344
|
canvas.setZoom(zoomLevel);
|
|
1345
|
+
break;
|
|
1358
1346
|
}
|
|
1359
|
-
|
|
1347
|
+
case "resetZoom":
|
|
1360
1348
|
canvas.resetZoom();
|
|
1361
|
-
|
|
1362
|
-
|
|
1349
|
+
break;
|
|
1350
|
+
case "panLeft":
|
|
1363
1351
|
canvas.panLeft(payload);
|
|
1364
|
-
|
|
1365
|
-
|
|
1352
|
+
break;
|
|
1353
|
+
case "panRight":
|
|
1366
1354
|
canvas.panRight(payload);
|
|
1367
|
-
|
|
1368
|
-
|
|
1355
|
+
break;
|
|
1356
|
+
case "panUp":
|
|
1369
1357
|
canvas.panUp(payload);
|
|
1370
|
-
|
|
1371
|
-
|
|
1358
|
+
break;
|
|
1359
|
+
case "panDown":
|
|
1372
1360
|
canvas.panDown(payload);
|
|
1373
|
-
|
|
1374
|
-
|
|
1361
|
+
break;
|
|
1362
|
+
case "fitToScreen":
|
|
1375
1363
|
canvas.fitToScreen();
|
|
1376
|
-
|
|
1377
|
-
|
|
1364
|
+
break;
|
|
1365
|
+
case "centerContent":
|
|
1378
1366
|
canvas.centerContent();
|
|
1367
|
+
break;
|
|
1368
|
+
case "panToPoint": {
|
|
1369
|
+
const point = payload;
|
|
1370
|
+
canvas.panToPoint(point.x, point.y);
|
|
1371
|
+
break;
|
|
1379
1372
|
}
|
|
1380
|
-
|
|
1381
|
-
canvas.panToPoint(payload.x, payload.y);
|
|
1382
|
-
}
|
|
1383
|
-
else if (action === "resetView") {
|
|
1373
|
+
case "resetView":
|
|
1384
1374
|
canvas.resetView();
|
|
1385
|
-
|
|
1386
|
-
|
|
1375
|
+
break;
|
|
1376
|
+
case "resetViewToCenter":
|
|
1387
1377
|
canvas.resetViewToCenter();
|
|
1388
|
-
|
|
1378
|
+
break;
|
|
1389
1379
|
// Ruler/Grid methods
|
|
1390
|
-
|
|
1380
|
+
case "toggleRulers":
|
|
1391
1381
|
canvas.toggleRulers();
|
|
1392
|
-
|
|
1393
|
-
|
|
1382
|
+
break;
|
|
1383
|
+
case "showRulers":
|
|
1394
1384
|
canvas.showRulers();
|
|
1395
|
-
|
|
1396
|
-
|
|
1385
|
+
break;
|
|
1386
|
+
case "hideRulers":
|
|
1397
1387
|
canvas.hideRulers();
|
|
1398
|
-
|
|
1399
|
-
|
|
1388
|
+
break;
|
|
1389
|
+
case "toggleGrid":
|
|
1400
1390
|
canvas.toggleGrid();
|
|
1401
|
-
|
|
1402
|
-
|
|
1391
|
+
break;
|
|
1392
|
+
case "showGrid":
|
|
1403
1393
|
canvas.showGrid();
|
|
1404
|
-
|
|
1405
|
-
|
|
1394
|
+
break;
|
|
1395
|
+
case "hideGrid":
|
|
1406
1396
|
canvas.hideGrid();
|
|
1407
|
-
|
|
1397
|
+
break;
|
|
1408
1398
|
// Config methods
|
|
1409
|
-
|
|
1399
|
+
case "updateThemeMode": {
|
|
1410
1400
|
const mode = payload;
|
|
1411
1401
|
if (mode !== "light" && mode !== "dark") {
|
|
1412
1402
|
throw new Error(`Invalid theme mode: ${mode}`);
|
|
1413
1403
|
}
|
|
1414
1404
|
canvas.updateThemeMode(mode);
|
|
1405
|
+
break;
|
|
1415
1406
|
}
|
|
1416
|
-
|
|
1407
|
+
case "toggleThemeMode": {
|
|
1417
1408
|
const currentConfig = canvas.getConfig();
|
|
1418
1409
|
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
1419
1410
|
canvas.updateThemeMode(newMode);
|
|
1411
|
+
break;
|
|
1420
1412
|
}
|
|
1421
1413
|
// Transition methods
|
|
1422
|
-
|
|
1414
|
+
case "updateTransition": {
|
|
1423
1415
|
const enabled = payload;
|
|
1424
1416
|
if (typeof enabled !== "boolean") {
|
|
1425
1417
|
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
1426
1418
|
}
|
|
1427
1419
|
canvas.updateTransition(enabled);
|
|
1420
|
+
break;
|
|
1428
1421
|
}
|
|
1429
|
-
|
|
1422
|
+
case "toggleTransitionMode":
|
|
1430
1423
|
canvas.toggleTransitionMode();
|
|
1431
|
-
|
|
1432
|
-
|
|
1424
|
+
break;
|
|
1425
|
+
default:
|
|
1433
1426
|
throw new Error(`Unknown action: ${action}`);
|
|
1434
|
-
}
|
|
1435
1427
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
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;
|
|
1439
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);
|
|
1440
1448
|
};
|
|
1441
1449
|
if (typeof window !== "undefined") {
|
|
1442
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,117 +1271,125 @@
|
|
|
1271
1271
|
}, "*");
|
|
1272
1272
|
}
|
|
1273
1273
|
|
|
1274
|
-
function
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
}
|
|
1280
|
-
console.log("data", event.data);
|
|
1281
|
-
const canvasName = canvas.config.name || "markupCanvas";
|
|
1282
|
-
if (data.canvasName !== canvasName) {
|
|
1283
|
-
console.log("canvasName", data.canvasName, "!==", canvasName);
|
|
1284
|
-
return;
|
|
1285
|
-
}
|
|
1286
|
-
const action = data.action;
|
|
1287
|
-
const payload = data.data;
|
|
1288
|
-
try {
|
|
1289
|
-
// View methods
|
|
1290
|
-
if (action === "zoomIn") {
|
|
1291
|
-
console.log("zoomIn", payload);
|
|
1274
|
+
function processPostMessage(canvas, action, payload, canvasName) {
|
|
1275
|
+
try {
|
|
1276
|
+
// View methods
|
|
1277
|
+
switch (action) {
|
|
1278
|
+
case "zoomIn":
|
|
1292
1279
|
canvas.zoomIn(payload);
|
|
1293
|
-
|
|
1294
|
-
|
|
1280
|
+
break;
|
|
1281
|
+
case "zoomOut":
|
|
1295
1282
|
canvas.zoomOut(payload);
|
|
1296
|
-
|
|
1297
|
-
|
|
1283
|
+
break;
|
|
1284
|
+
case "setZoom": {
|
|
1298
1285
|
const zoomLevel = payload;
|
|
1299
1286
|
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
1300
1287
|
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
1301
1288
|
}
|
|
1302
1289
|
canvas.setZoom(zoomLevel);
|
|
1290
|
+
break;
|
|
1303
1291
|
}
|
|
1304
|
-
|
|
1292
|
+
case "resetZoom":
|
|
1305
1293
|
canvas.resetZoom();
|
|
1306
|
-
|
|
1307
|
-
|
|
1294
|
+
break;
|
|
1295
|
+
case "panLeft":
|
|
1308
1296
|
canvas.panLeft(payload);
|
|
1309
|
-
|
|
1310
|
-
|
|
1297
|
+
break;
|
|
1298
|
+
case "panRight":
|
|
1311
1299
|
canvas.panRight(payload);
|
|
1312
|
-
|
|
1313
|
-
|
|
1300
|
+
break;
|
|
1301
|
+
case "panUp":
|
|
1314
1302
|
canvas.panUp(payload);
|
|
1315
|
-
|
|
1316
|
-
|
|
1303
|
+
break;
|
|
1304
|
+
case "panDown":
|
|
1317
1305
|
canvas.panDown(payload);
|
|
1318
|
-
|
|
1319
|
-
|
|
1306
|
+
break;
|
|
1307
|
+
case "fitToScreen":
|
|
1320
1308
|
canvas.fitToScreen();
|
|
1321
|
-
|
|
1322
|
-
|
|
1309
|
+
break;
|
|
1310
|
+
case "centerContent":
|
|
1323
1311
|
canvas.centerContent();
|
|
1312
|
+
break;
|
|
1313
|
+
case "panToPoint": {
|
|
1314
|
+
const point = payload;
|
|
1315
|
+
canvas.panToPoint(point.x, point.y);
|
|
1316
|
+
break;
|
|
1324
1317
|
}
|
|
1325
|
-
|
|
1326
|
-
canvas.panToPoint(payload.x, payload.y);
|
|
1327
|
-
}
|
|
1328
|
-
else if (action === "resetView") {
|
|
1318
|
+
case "resetView":
|
|
1329
1319
|
canvas.resetView();
|
|
1330
|
-
|
|
1331
|
-
|
|
1320
|
+
break;
|
|
1321
|
+
case "resetViewToCenter":
|
|
1332
1322
|
canvas.resetViewToCenter();
|
|
1333
|
-
|
|
1323
|
+
break;
|
|
1334
1324
|
// Ruler/Grid methods
|
|
1335
|
-
|
|
1325
|
+
case "toggleRulers":
|
|
1336
1326
|
canvas.toggleRulers();
|
|
1337
|
-
|
|
1338
|
-
|
|
1327
|
+
break;
|
|
1328
|
+
case "showRulers":
|
|
1339
1329
|
canvas.showRulers();
|
|
1340
|
-
|
|
1341
|
-
|
|
1330
|
+
break;
|
|
1331
|
+
case "hideRulers":
|
|
1342
1332
|
canvas.hideRulers();
|
|
1343
|
-
|
|
1344
|
-
|
|
1333
|
+
break;
|
|
1334
|
+
case "toggleGrid":
|
|
1345
1335
|
canvas.toggleGrid();
|
|
1346
|
-
|
|
1347
|
-
|
|
1336
|
+
break;
|
|
1337
|
+
case "showGrid":
|
|
1348
1338
|
canvas.showGrid();
|
|
1349
|
-
|
|
1350
|
-
|
|
1339
|
+
break;
|
|
1340
|
+
case "hideGrid":
|
|
1351
1341
|
canvas.hideGrid();
|
|
1352
|
-
|
|
1342
|
+
break;
|
|
1353
1343
|
// Config methods
|
|
1354
|
-
|
|
1344
|
+
case "updateThemeMode": {
|
|
1355
1345
|
const mode = payload;
|
|
1356
1346
|
if (mode !== "light" && mode !== "dark") {
|
|
1357
1347
|
throw new Error(`Invalid theme mode: ${mode}`);
|
|
1358
1348
|
}
|
|
1359
1349
|
canvas.updateThemeMode(mode);
|
|
1350
|
+
break;
|
|
1360
1351
|
}
|
|
1361
|
-
|
|
1352
|
+
case "toggleThemeMode": {
|
|
1362
1353
|
const currentConfig = canvas.getConfig();
|
|
1363
1354
|
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
1364
1355
|
canvas.updateThemeMode(newMode);
|
|
1356
|
+
break;
|
|
1365
1357
|
}
|
|
1366
1358
|
// Transition methods
|
|
1367
|
-
|
|
1359
|
+
case "updateTransition": {
|
|
1368
1360
|
const enabled = payload;
|
|
1369
1361
|
if (typeof enabled !== "boolean") {
|
|
1370
1362
|
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
1371
1363
|
}
|
|
1372
1364
|
canvas.updateTransition(enabled);
|
|
1365
|
+
break;
|
|
1373
1366
|
}
|
|
1374
|
-
|
|
1367
|
+
case "toggleTransitionMode":
|
|
1375
1368
|
canvas.toggleTransitionMode();
|
|
1376
|
-
|
|
1377
|
-
|
|
1369
|
+
break;
|
|
1370
|
+
default:
|
|
1378
1371
|
throw new Error(`Unknown action: ${action}`);
|
|
1379
|
-
}
|
|
1380
1372
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
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;
|
|
1384
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);
|
|
1385
1393
|
};
|
|
1386
1394
|
if (typeof window !== "undefined") {
|
|
1387
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;console.log("data",t.data);const r=e.config.name||"markupCanvas";if(n.canvasName!==r)return void console.log("canvasName",n.canvasName,"!==",r);const o=n.action,a=n.data;try{if("zoomIn"===o)console.log("zoomIn",a),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 N(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 H(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=>H(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=H(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=N(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 => {
|
|
@@ -10,94 +10,16 @@ export function setupPostMessageEvents(canvas: MarkupCanvas): () => void {
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
console.log("data", event.data);
|
|
14
|
-
|
|
15
13
|
const canvasName = canvas.config.name || "markupCanvas";
|
|
16
14
|
|
|
17
15
|
if (data.canvasName !== canvasName) {
|
|
18
|
-
console.log("canvasName", data.canvasName, "!==", canvasName);
|
|
19
16
|
return;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
|
-
const action = data.action
|
|
19
|
+
const action = data.action;
|
|
23
20
|
const payload = data.data as string | number | boolean | object;
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
// View methods
|
|
27
|
-
if (action === "zoomIn") {
|
|
28
|
-
console.log("zoomIn", payload);
|
|
29
|
-
canvas.zoomIn(payload as number | undefined);
|
|
30
|
-
} else if (action === "zoomOut") {
|
|
31
|
-
canvas.zoomOut(payload as number | undefined);
|
|
32
|
-
} else if (action === "setZoom") {
|
|
33
|
-
const zoomLevel = payload as number;
|
|
34
|
-
if (typeof zoomLevel !== "number" || zoomLevel <= 0) {
|
|
35
|
-
throw new Error(`Invalid zoom level: ${zoomLevel}. Must be a positive number.`);
|
|
36
|
-
}
|
|
37
|
-
canvas.setZoom(zoomLevel);
|
|
38
|
-
} else if (action === "resetZoom") {
|
|
39
|
-
canvas.resetZoom();
|
|
40
|
-
} else if (action === "panLeft") {
|
|
41
|
-
canvas.panLeft(payload as number | undefined);
|
|
42
|
-
} else if (action === "panRight") {
|
|
43
|
-
canvas.panRight(payload as number | undefined);
|
|
44
|
-
} else if (action === "panUp") {
|
|
45
|
-
canvas.panUp(payload as number | undefined);
|
|
46
|
-
} else if (action === "panDown") {
|
|
47
|
-
canvas.panDown(payload as number | undefined);
|
|
48
|
-
} else if (action === "fitToScreen") {
|
|
49
|
-
canvas.fitToScreen();
|
|
50
|
-
} else if (action === "centerContent") {
|
|
51
|
-
canvas.centerContent();
|
|
52
|
-
} else if (action === "panToPoint") {
|
|
53
|
-
canvas.panToPoint((payload as { x: number; y: number }).x, (payload as { x: number; y: number }).y);
|
|
54
|
-
} else if (action === "resetView") {
|
|
55
|
-
canvas.resetView();
|
|
56
|
-
} else if (action === "resetViewToCenter") {
|
|
57
|
-
canvas.resetViewToCenter();
|
|
58
|
-
}
|
|
59
|
-
// Ruler/Grid methods
|
|
60
|
-
else if (action === "toggleRulers") {
|
|
61
|
-
canvas.toggleRulers();
|
|
62
|
-
} else if (action === "showRulers") {
|
|
63
|
-
canvas.showRulers();
|
|
64
|
-
} else if (action === "hideRulers") {
|
|
65
|
-
canvas.hideRulers();
|
|
66
|
-
} else if (action === "toggleGrid") {
|
|
67
|
-
canvas.toggleGrid();
|
|
68
|
-
} else if (action === "showGrid") {
|
|
69
|
-
canvas.showGrid();
|
|
70
|
-
} else if (action === "hideGrid") {
|
|
71
|
-
canvas.hideGrid();
|
|
72
|
-
}
|
|
73
|
-
// Config methods
|
|
74
|
-
else if (action === "updateThemeMode") {
|
|
75
|
-
const mode = payload as "light" | "dark";
|
|
76
|
-
if (mode !== "light" && mode !== "dark") {
|
|
77
|
-
throw new Error(`Invalid theme mode: ${mode}`);
|
|
78
|
-
}
|
|
79
|
-
canvas.updateThemeMode(mode);
|
|
80
|
-
} else if (action === "toggleThemeMode") {
|
|
81
|
-
const currentConfig = canvas.getConfig();
|
|
82
|
-
const newMode = currentConfig.themeMode === "light" ? "dark" : "light";
|
|
83
|
-
canvas.updateThemeMode(newMode);
|
|
84
|
-
}
|
|
85
|
-
// Transition methods
|
|
86
|
-
else if (action === "updateTransition") {
|
|
87
|
-
const enabled = payload as boolean;
|
|
88
|
-
if (typeof enabled !== "boolean") {
|
|
89
|
-
throw new Error(`Invalid transition enabled value: ${enabled}. Must be a boolean.`);
|
|
90
|
-
}
|
|
91
|
-
canvas.updateTransition(enabled);
|
|
92
|
-
} else if (action === "toggleTransitionMode") {
|
|
93
|
-
canvas.toggleTransitionMode();
|
|
94
|
-
} else {
|
|
95
|
-
throw new Error(`Unknown action: ${action}`);
|
|
96
|
-
}
|
|
97
|
-
} catch (error) {
|
|
98
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
99
|
-
sendPostMessageError(canvasName, action, errorMessage);
|
|
100
|
-
}
|
|
22
|
+
processPostMessage(canvas, action, payload, canvasName);
|
|
101
23
|
};
|
|
102
24
|
|
|
103
25
|
if (typeof window !== "undefined") {
|
|
File without changes
|
|
File without changes
|