kritzel-stencil 0.0.162 → 0.0.163
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/cjs/{default-line-tool.config-D1Ns0NmM.js → default-line-tool.config-DJMYrkSu.js} +340 -9
- package/dist/cjs/default-line-tool.config-DJMYrkSu.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/kritzel-color_22.cjs.entry.js +761 -28
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/stencil.cjs.js +1 -1
- package/dist/collection/classes/core/core.class.js +19 -3
- package/dist/collection/classes/core/core.class.js.map +1 -1
- package/dist/collection/classes/core/reviver.class.js +16 -0
- package/dist/collection/classes/core/reviver.class.js.map +1 -1
- package/dist/collection/classes/core/store.class.js +5 -0
- package/dist/collection/classes/core/store.class.js.map +1 -1
- package/dist/collection/classes/core/viewport.class.js +8 -0
- package/dist/collection/classes/core/viewport.class.js.map +1 -1
- package/dist/collection/classes/managers/anchor.manager.js +181 -3
- package/dist/collection/classes/managers/anchor.manager.js.map +1 -1
- package/dist/collection/classes/objects/path.class.js +85 -0
- package/dist/collection/classes/objects/path.class.js.map +1 -1
- package/dist/collection/classes/objects/shape.class.js +372 -0
- package/dist/collection/classes/objects/shape.class.js.map +1 -0
- package/dist/collection/classes/registries/icon-registry.class.js +4 -0
- package/dist/collection/classes/registries/icon-registry.class.js.map +1 -1
- package/dist/collection/classes/tools/brush-tool.class.js +2 -2
- package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/line-tool.class.js +2 -2
- package/dist/collection/classes/tools/line-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/shape-tool.class.js +204 -0
- package/dist/collection/classes/tools/shape-tool.class.js.map +1 -0
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +17 -6
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +44 -8
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +143 -5
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +76 -12
- package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -1
- package/dist/collection/configs/default-engine-config.js +1 -1
- package/dist/collection/configs/default-engine-config.js.map +1 -1
- package/dist/collection/configs/default-shape-tool.config.js +26 -0
- package/dist/collection/configs/default-shape-tool.config.js.map +1 -0
- package/dist/collection/enums/shape-type.enum.js +7 -0
- package/dist/collection/enums/shape-type.enum.js.map +1 -0
- package/dist/collection/helpers/geometry.helper.js +55 -0
- package/dist/collection/helpers/geometry.helper.js.map +1 -1
- package/dist/collection/interfaces/toolbar-control.interface.js.map +1 -1
- package/dist/components/index.js +3 -3
- package/dist/components/kritzel-brush-style.js +1 -1
- package/dist/components/kritzel-context-menu.js +1 -1
- package/dist/components/kritzel-control-brush-config.js +1 -1
- package/dist/components/kritzel-control-text-config.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-editor.js +49 -16
- package/dist/components/kritzel-editor.js.map +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-icon.js +1 -1
- package/dist/components/kritzel-menu-item.js +1 -1
- package/dist/components/kritzel-menu.js +1 -1
- package/dist/components/kritzel-split-button.js +1 -1
- package/dist/components/kritzel-utility-panel.js +1 -1
- package/dist/components/kritzel-workspace-manager.js +1 -1
- package/dist/components/{p-Cqr0Bah5.js → p-5OECjGHq.js} +3 -3
- package/dist/components/{p-Cqr0Bah5.js.map → p-5OECjGHq.js.map} +1 -1
- package/dist/components/{p-CvLFRlQU.js → p-BSBMBjhq.js} +3 -3
- package/dist/components/{p-CvLFRlQU.js.map → p-BSBMBjhq.js.map} +1 -1
- package/dist/components/{p-7_lwv0zQ.js → p-BuS7MM1j.js} +4 -4
- package/dist/components/{p-7_lwv0zQ.js.map → p-BuS7MM1j.js.map} +1 -1
- package/dist/components/{p-CuhOrcET.js → p-CnRfQsIC.js} +838 -22
- package/dist/components/p-CnRfQsIC.js.map +1 -0
- package/dist/components/{p-BixlbUD7.js → p-Cv4BGNPb.js} +6 -2
- package/dist/components/p-Cv4BGNPb.js.map +1 -0
- package/dist/components/{p-dMCB4tJA.js → p-D1YAsWrL.js} +3 -3
- package/dist/components/{p-dMCB4tJA.js.map → p-D1YAsWrL.js.map} +1 -1
- package/dist/components/{p-CDteBYm9.js → p-D8L0t-Ro.js} +3 -3
- package/dist/components/{p-CDteBYm9.js.map → p-D8L0t-Ro.js.map} +1 -1
- package/dist/components/{p-DZ7kxJUx.js → p-DguzZn_x.js} +3 -3
- package/dist/components/{p-DZ7kxJUx.js.map → p-DguzZn_x.js.map} +1 -1
- package/dist/components/{p-sokRZ7Vn.js → p-Dz2XHHqa.js} +145 -5
- package/dist/components/p-Dz2XHHqa.js.map +1 -0
- package/dist/components/{p-CkD1PQQX.js → p-I3iPEDpx.js} +5 -5
- package/dist/components/{p-CkD1PQQX.js.map → p-I3iPEDpx.js.map} +1 -1
- package/dist/components/{p-DKwJJuFb.js → p-tp96UZ0l.js} +83 -19
- package/dist/components/p-tp96UZ0l.js.map +1 -0
- package/dist/esm/{default-line-tool.config-C35m-d1Y.js → default-line-tool.config-C35P3XfD.js} +332 -10
- package/dist/esm/default-line-tool.config-C35P3XfD.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/kritzel-color_22.entry.js +761 -28
- package/dist/esm/loader.js +1 -1
- package/dist/esm/stencil.js +1 -1
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-9d43b708.entry.js +10 -0
- package/dist/stencil/p-9d43b708.entry.js.map +1 -0
- package/dist/stencil/p-C35P3XfD.js +2 -0
- package/dist/stencil/p-C35P3XfD.js.map +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/core/core.class.d.ts +1 -0
- package/dist/types/classes/core/store.class.d.ts +2 -0
- package/dist/types/classes/core/viewport.class.d.ts +6 -0
- package/dist/types/classes/managers/anchor.manager.d.ts +20 -0
- package/dist/types/classes/objects/path.class.d.ts +7 -0
- package/dist/types/classes/objects/shape.class.d.ts +116 -0
- package/dist/types/classes/tools/shape-tool.class.d.ts +37 -0
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -2
- package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +16 -1
- package/dist/types/components.d.ts +5 -5
- package/dist/types/configs/default-shape-tool.config.d.ts +2 -0
- package/dist/types/enums/shape-type.enum.d.ts +5 -0
- package/dist/types/helpers/geometry.helper.d.ts +21 -0
- package/dist/types/interfaces/toolbar-control.interface.d.ts +21 -3
- package/package.json +1 -1
- package/dist/cjs/default-line-tool.config-D1Ns0NmM.js.map +0 -1
- package/dist/components/p-BixlbUD7.js.map +0 -1
- package/dist/components/p-CuhOrcET.js.map +0 -1
- package/dist/components/p-DKwJJuFb.js.map +0 -1
- package/dist/components/p-sokRZ7Vn.js.map +0 -1
- package/dist/esm/default-line-tool.config-C35m-d1Y.js.map +0 -1
- package/dist/stencil/p-C35m-d1Y.js +0 -2
- package/dist/stencil/p-C35m-d1Y.js.map +0 -1
- package/dist/stencil/p-d142ef46.entry.js +0 -10
- package/dist/stencil/p-d142ef46.entry.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { p as proxyCustomElement, H, c as createEvent, h, d as Host } from './p-CwkUrTy1.js';
|
|
2
2
|
import { K as KritzelMouseButton } from './p-D8W6LE-c.js';
|
|
3
|
-
import { e as KritzelBaseObject, f as KritzelGeometryHelper, g as KritzelBaseTool, h as KritzelEventHelper, i as KritzelToolRegistry, c as KritzelTextTool, b as KritzelBrushTool, K as KritzelText, a as KritzelPath
|
|
4
|
-
import { K as KritzelContextMenu, d as defineCustomElement$3 } from './p-
|
|
3
|
+
import { e as KritzelBaseObject, f as KritzelGeometryHelper, g as KritzelBaseTool, h as KritzelEventHelper, i as KritzelToolRegistry, S as Schema, s as schema, j as addListNodes, E as EditorView, k as EditorState, l as keymap, T as TextSelection, d as KritzelKeyboardHelper, m as baseKeymap, c as KritzelTextTool, b as KritzelBrushTool, K as KritzelText, a as KritzelPath } from './p-Dz2XHHqa.js';
|
|
4
|
+
import { K as KritzelContextMenu, d as defineCustomElement$3 } from './p-D1YAsWrL.js';
|
|
5
5
|
import { O as ObjectHelper } from './p-B0kd2rUI.js';
|
|
6
|
-
import { K as KritzelIconRegistry, d as defineCustomElement$1 } from './p-BixlbUD7.js';
|
|
7
|
-
import { K as KritzelWorkspace } from './p-n789Y3S-.js';
|
|
8
6
|
import { K as KritzelDevicesHelper } from './p-l10It7Nm.js';
|
|
7
|
+
import { K as KritzelIconRegistry, d as defineCustomElement$1 } from './p-Cv4BGNPb.js';
|
|
8
|
+
import { K as KritzelWorkspace } from './p-n789Y3S-.js';
|
|
9
9
|
import { d as defineCustomElement$2 } from './p-B_3OZeom.js';
|
|
10
10
|
|
|
11
11
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -1018,6 +1018,7 @@ class KritzelLineTool extends KritzelBaseTool {
|
|
|
1018
1018
|
});
|
|
1019
1019
|
updatedLine.id = currentLine.id;
|
|
1020
1020
|
updatedLine.workspaceId = currentLine.workspaceId;
|
|
1021
|
+
updatedLine.zIndex = currentLine.zIndex;
|
|
1021
1022
|
updatedLine.isCompleted = false;
|
|
1022
1023
|
this._core.store.state.objects.update(updatedLine);
|
|
1023
1024
|
}
|
|
@@ -1044,6 +1045,7 @@ class KritzelLineTool extends KritzelBaseTool {
|
|
|
1044
1045
|
});
|
|
1045
1046
|
updatedLine.id = currentLine.id;
|
|
1046
1047
|
updatedLine.workspaceId = currentLine.workspaceId;
|
|
1048
|
+
updatedLine.zIndex = currentLine.zIndex;
|
|
1047
1049
|
updatedLine.isCompleted = false;
|
|
1048
1050
|
this._core.store.state.objects.update(updatedLine);
|
|
1049
1051
|
}
|
|
@@ -1060,7 +1062,6 @@ class KritzelLineTool extends KritzelBaseTool {
|
|
|
1060
1062
|
const currentLine = this._core.store.currentLine;
|
|
1061
1063
|
if (currentLine) {
|
|
1062
1064
|
currentLine.isCompleted = true;
|
|
1063
|
-
currentLine.zIndex = this._core.store.currentZIndex;
|
|
1064
1065
|
this._core.store.state.objects.update(currentLine);
|
|
1065
1066
|
this._core.engine.emitObjectsChange();
|
|
1066
1067
|
// Switch to selection tool and select the drawn line
|
|
@@ -1074,7 +1075,6 @@ class KritzelLineTool extends KritzelBaseTool {
|
|
|
1074
1075
|
const currentLine = this._core.store.currentLine;
|
|
1075
1076
|
if (currentLine) {
|
|
1076
1077
|
currentLine.isCompleted = true;
|
|
1077
|
-
currentLine.zIndex = this._core.store.currentZIndex;
|
|
1078
1078
|
this._core.store.state.objects.update(currentLine);
|
|
1079
1079
|
this._core.engine.emitObjectsChange();
|
|
1080
1080
|
// Switch to selection tool and select the drawn line
|
|
@@ -18281,7 +18281,34 @@ class KritzelAnchorManager {
|
|
|
18281
18281
|
const reference = endpoint === 'start'
|
|
18282
18282
|
? this.lineLocalToWorld(line, line.endX, line.endY)
|
|
18283
18283
|
: this.lineLocalToWorld(line, line.startX, line.startY);
|
|
18284
|
-
|
|
18284
|
+
// Check for path object (uses stroke edge detection)
|
|
18285
|
+
const pathClipPoint = this.getPathClipPoint(targetObject, reference);
|
|
18286
|
+
if (pathClipPoint) {
|
|
18287
|
+
const localEdge = this.lineWorldToLocal(line, pathClipPoint.x, pathClipPoint.y);
|
|
18288
|
+
const totalLength = Math.sqrt(Math.pow(line.endX - line.startX, 2) +
|
|
18289
|
+
Math.pow(line.endY - line.startY, 2));
|
|
18290
|
+
const distanceFromStart = Math.sqrt(Math.pow(localEdge.x - line.startX, 2) +
|
|
18291
|
+
Math.pow(localEdge.y - line.startY, 2));
|
|
18292
|
+
const t = totalLength > 0 ? distanceFromStart / totalLength : endpoint === 'start' ? 0 : 1;
|
|
18293
|
+
return {
|
|
18294
|
+
localX: localEdge.x,
|
|
18295
|
+
localY: localEdge.y,
|
|
18296
|
+
worldX: pathClipPoint.x,
|
|
18297
|
+
worldY: pathClipPoint.y,
|
|
18298
|
+
t,
|
|
18299
|
+
};
|
|
18300
|
+
}
|
|
18301
|
+
// Check for custom clip polygon (ellipse, triangle shapes)
|
|
18302
|
+
const customClipPolygon = this.getClipPolygonForObject(targetObject);
|
|
18303
|
+
let edgeIntersection;
|
|
18304
|
+
if (customClipPolygon) {
|
|
18305
|
+
// Use custom polygon for non-rectangular shapes
|
|
18306
|
+
edgeIntersection = KritzelGeometryHelper.getLinePointsArrayIntersection(reference, { x: targetObject.centerX, y: targetObject.centerY }, customClipPolygon);
|
|
18307
|
+
}
|
|
18308
|
+
else {
|
|
18309
|
+
// Fall back to bounding box for rectangles and other objects
|
|
18310
|
+
edgeIntersection = KritzelGeometryHelper.getLinePolygonIntersection(reference, { x: targetObject.centerX, y: targetObject.centerY }, targetObject.rotatedPolygon);
|
|
18311
|
+
}
|
|
18285
18312
|
if (!edgeIntersection) {
|
|
18286
18313
|
return null;
|
|
18287
18314
|
}
|
|
@@ -18300,7 +18327,15 @@ class KritzelAnchorManager {
|
|
|
18300
18327
|
};
|
|
18301
18328
|
}
|
|
18302
18329
|
computeCurvedClipInfo(line, endpoint, targetObject) {
|
|
18303
|
-
|
|
18330
|
+
// Check for path object (uses stroke edge detection via sampling)
|
|
18331
|
+
if (KritzelClassHelper.isInstanceOf(targetObject, 'KritzelPath')) {
|
|
18332
|
+
// For curved lines to paths, sample along the curve to find stroke edge
|
|
18333
|
+
const path = targetObject;
|
|
18334
|
+
return this.findCurveExitPointForPath(line, endpoint, path);
|
|
18335
|
+
}
|
|
18336
|
+
// Check for custom clip polygon (ellipse, triangle shapes)
|
|
18337
|
+
const customClipPolygon = this.getClipPolygonForObject(targetObject);
|
|
18338
|
+
const polygonPoints = customClipPolygon ?? this.getPolygonPoints(targetObject.rotatedPolygon);
|
|
18304
18339
|
const exitPoint = this.findCurveExitPoint(line, endpoint, polygonPoints);
|
|
18305
18340
|
if (exitPoint) {
|
|
18306
18341
|
return exitPoint;
|
|
@@ -18308,7 +18343,13 @@ class KritzelAnchorManager {
|
|
|
18308
18343
|
const reference = endpoint === 'start'
|
|
18309
18344
|
? this.lineLocalToWorld(line, line.endX, line.endY)
|
|
18310
18345
|
: this.lineLocalToWorld(line, line.startX, line.startY);
|
|
18311
|
-
|
|
18346
|
+
let fallbackIntersection;
|
|
18347
|
+
if (customClipPolygon) {
|
|
18348
|
+
fallbackIntersection = KritzelGeometryHelper.getLinePointsArrayIntersection(reference, { x: targetObject.centerX, y: targetObject.centerY }, customClipPolygon);
|
|
18349
|
+
}
|
|
18350
|
+
else {
|
|
18351
|
+
fallbackIntersection = KritzelGeometryHelper.getLinePolygonIntersection(reference, { x: targetObject.centerX, y: targetObject.centerY }, targetObject.rotatedPolygon);
|
|
18352
|
+
}
|
|
18312
18353
|
if (!fallbackIntersection) {
|
|
18313
18354
|
return null;
|
|
18314
18355
|
}
|
|
@@ -18348,6 +18389,119 @@ class KritzelAnchorManager {
|
|
|
18348
18389
|
}
|
|
18349
18390
|
return null;
|
|
18350
18391
|
}
|
|
18392
|
+
/**
|
|
18393
|
+
* Finds the exit point for a curved line going to a Path object.
|
|
18394
|
+
* Uses distance-to-stroke sampling instead of polygon containment.
|
|
18395
|
+
*/
|
|
18396
|
+
findCurveExitPointForPath(line, endpoint, path) {
|
|
18397
|
+
const steps = 64;
|
|
18398
|
+
const initialT = endpoint === 'start' ? 0 : 1;
|
|
18399
|
+
const halfStroke = path.strokeWidth / path.scale / 2;
|
|
18400
|
+
// Ensure path has computed points
|
|
18401
|
+
const pathPoints = this.getPathAdjustedPoints(path);
|
|
18402
|
+
if (pathPoints.length < 1) {
|
|
18403
|
+
return null;
|
|
18404
|
+
}
|
|
18405
|
+
// Check if starting point is inside the stroke
|
|
18406
|
+
const initialSample = this.evaluateLineAtT(line, initialT);
|
|
18407
|
+
let prevInside = this.isPointInPathStroke(initialSample.worldX, initialSample.worldY, pathPoints, halfStroke);
|
|
18408
|
+
let prevT = initialT;
|
|
18409
|
+
for (let i = 1; i <= steps; i++) {
|
|
18410
|
+
const t = endpoint === 'start' ? i / steps : 1 - i / steps;
|
|
18411
|
+
const sample = this.evaluateLineAtT(line, t);
|
|
18412
|
+
const inside = this.isPointInPathStroke(sample.worldX, sample.worldY, pathPoints, halfStroke);
|
|
18413
|
+
if (prevInside && !inside) {
|
|
18414
|
+
// Refine using binary search
|
|
18415
|
+
const refinedT = this.refineCurveExitParameterForPath(line, pathPoints, halfStroke, prevT, t);
|
|
18416
|
+
const refinedPoint = this.evaluateLineAtT(line, refinedT);
|
|
18417
|
+
return {
|
|
18418
|
+
localX: refinedPoint.localX,
|
|
18419
|
+
localY: refinedPoint.localY,
|
|
18420
|
+
worldX: refinedPoint.worldX,
|
|
18421
|
+
worldY: refinedPoint.worldY,
|
|
18422
|
+
t: refinedT,
|
|
18423
|
+
};
|
|
18424
|
+
}
|
|
18425
|
+
prevInside = inside;
|
|
18426
|
+
prevT = t;
|
|
18427
|
+
}
|
|
18428
|
+
return null;
|
|
18429
|
+
}
|
|
18430
|
+
refineCurveExitParameterForPath(line, pathPoints, halfStroke, insideT, outsideT) {
|
|
18431
|
+
let tInside = insideT;
|
|
18432
|
+
let tOutside = outsideT;
|
|
18433
|
+
for (let i = 0; i < 8; i++) {
|
|
18434
|
+
const mid = (tInside + tOutside) / 2;
|
|
18435
|
+
const sample = this.evaluateLineAtT(line, mid);
|
|
18436
|
+
const inside = this.isPointInPathStroke(sample.worldX, sample.worldY, pathPoints, halfStroke);
|
|
18437
|
+
if (inside) {
|
|
18438
|
+
tInside = mid;
|
|
18439
|
+
}
|
|
18440
|
+
else {
|
|
18441
|
+
tOutside = mid;
|
|
18442
|
+
}
|
|
18443
|
+
}
|
|
18444
|
+
return (tInside + tOutside) / 2;
|
|
18445
|
+
}
|
|
18446
|
+
getPathAdjustedPoints(path) {
|
|
18447
|
+
// Access the path's adjusted points through its internal computation
|
|
18448
|
+
// We'll need to manually compute them since they're private
|
|
18449
|
+
return this.computePathAdjustedPoints(path);
|
|
18450
|
+
}
|
|
18451
|
+
computePathAdjustedPoints(path) {
|
|
18452
|
+
if (!path.points?.length) {
|
|
18453
|
+
return [];
|
|
18454
|
+
}
|
|
18455
|
+
const angle = path.rotation;
|
|
18456
|
+
const cos = Math.cos(angle);
|
|
18457
|
+
const sin = Math.sin(angle);
|
|
18458
|
+
const xs = path.points.map(p => p[0]);
|
|
18459
|
+
const ys = path.points.map(p => p[1]);
|
|
18460
|
+
const pivot = {
|
|
18461
|
+
x: (Math.min(...xs) + Math.max(...xs)) / 2,
|
|
18462
|
+
y: (Math.min(...ys) + Math.max(...ys)) / 2,
|
|
18463
|
+
};
|
|
18464
|
+
const { x: cx, y: cy } = pivot;
|
|
18465
|
+
const rotatedPoints = path.points.map(([x, y]) => {
|
|
18466
|
+
const dx = x - cx;
|
|
18467
|
+
const dy = y - cy;
|
|
18468
|
+
return [cx + dx * cos - dy * sin, cy + dx * sin + dy * cos];
|
|
18469
|
+
});
|
|
18470
|
+
return rotatedPoints.map(([px, py]) => [
|
|
18471
|
+
Math.abs(px - path.x) / path.scale + path.translateX,
|
|
18472
|
+
Math.abs(py - path.y) / path.scale + path.translateY,
|
|
18473
|
+
]);
|
|
18474
|
+
}
|
|
18475
|
+
isPointInPathStroke(x, y, pathPoints, halfStroke) {
|
|
18476
|
+
if (pathPoints.length === 1) {
|
|
18477
|
+
const p = pathPoints[0];
|
|
18478
|
+
const dx = x - p[0];
|
|
18479
|
+
const dy = y - p[1];
|
|
18480
|
+
return Math.sqrt(dx * dx + dy * dy) <= halfStroke;
|
|
18481
|
+
}
|
|
18482
|
+
for (let i = 0; i < pathPoints.length - 1; i++) {
|
|
18483
|
+
const p1 = pathPoints[i];
|
|
18484
|
+
const p2 = pathPoints[i + 1];
|
|
18485
|
+
const dist = this.pointToSegmentDistance(x, y, p1[0], p1[1], p2[0], p2[1]);
|
|
18486
|
+
if (dist <= halfStroke) {
|
|
18487
|
+
return true;
|
|
18488
|
+
}
|
|
18489
|
+
}
|
|
18490
|
+
return false;
|
|
18491
|
+
}
|
|
18492
|
+
pointToSegmentDistance(px, py, x1, y1, x2, y2) {
|
|
18493
|
+
const dx = x2 - x1;
|
|
18494
|
+
const dy = y2 - y1;
|
|
18495
|
+
const lengthSquared = dx * dx + dy * dy;
|
|
18496
|
+
if (lengthSquared === 0) {
|
|
18497
|
+
return Math.sqrt((px - x1) * (px - x1) + (py - y1) * (py - y1));
|
|
18498
|
+
}
|
|
18499
|
+
let t = ((px - x1) * dx + (py - y1) * dy) / lengthSquared;
|
|
18500
|
+
t = Math.max(0, Math.min(1, t));
|
|
18501
|
+
const nearestX = x1 + t * dx;
|
|
18502
|
+
const nearestY = y1 + t * dy;
|
|
18503
|
+
return Math.sqrt((px - nearestX) * (px - nearestX) + (py - nearestY) * (py - nearestY));
|
|
18504
|
+
}
|
|
18351
18505
|
refineCurveExitParameter(line, polygonPoints, insideT, outsideT) {
|
|
18352
18506
|
let tInside = insideT;
|
|
18353
18507
|
let tOutside = outsideT;
|
|
@@ -18481,6 +18635,30 @@ class KritzelAnchorManager {
|
|
|
18481
18635
|
getPolygonPoints(polygon) {
|
|
18482
18636
|
return [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
|
|
18483
18637
|
}
|
|
18638
|
+
/**
|
|
18639
|
+
* Gets the custom clip polygon for an object if it has one.
|
|
18640
|
+
* Returns null for objects that should use the default rotatedPolygon.
|
|
18641
|
+
*/
|
|
18642
|
+
getClipPolygonForObject(object) {
|
|
18643
|
+
// Check if the object is a KritzelShape with a custom clip polygon
|
|
18644
|
+
if (KritzelClassHelper.isInstanceOf(object, 'KritzelShape')) {
|
|
18645
|
+
const shape = object;
|
|
18646
|
+
return shape.getClipPolygon();
|
|
18647
|
+
}
|
|
18648
|
+
// Path objects use getPathClipPoint instead of polygon
|
|
18649
|
+
return null;
|
|
18650
|
+
}
|
|
18651
|
+
/**
|
|
18652
|
+
* Gets the clip point for a Path object (stroke edge intersection).
|
|
18653
|
+
* Returns null if the object is not a Path or no intersection found.
|
|
18654
|
+
*/
|
|
18655
|
+
getPathClipPoint(object, outsidePoint) {
|
|
18656
|
+
if (KritzelClassHelper.isInstanceOf(object, 'KritzelPath')) {
|
|
18657
|
+
const path = object;
|
|
18658
|
+
return path.getClipPoint(outsidePoint);
|
|
18659
|
+
}
|
|
18660
|
+
return null;
|
|
18661
|
+
}
|
|
18484
18662
|
/**
|
|
18485
18663
|
* Converts local line coordinates to world coordinates.
|
|
18486
18664
|
*/
|
|
@@ -18532,6 +18710,571 @@ class KritzelAnchorManager {
|
|
|
18532
18710
|
}
|
|
18533
18711
|
}
|
|
18534
18712
|
|
|
18713
|
+
var ShapeType;
|
|
18714
|
+
(function (ShapeType) {
|
|
18715
|
+
ShapeType["Rectangle"] = "rectangle";
|
|
18716
|
+
ShapeType["Ellipse"] = "ellipse";
|
|
18717
|
+
ShapeType["Triangle"] = "triangle";
|
|
18718
|
+
})(ShapeType || (ShapeType = {}));
|
|
18719
|
+
|
|
18720
|
+
class KritzelShape extends KritzelBaseObject {
|
|
18721
|
+
__class__ = 'KritzelShape';
|
|
18722
|
+
shapeType = ShapeType.Rectangle;
|
|
18723
|
+
fillColor = 'transparent';
|
|
18724
|
+
strokeColor = '#000000';
|
|
18725
|
+
strokeWidth = 4;
|
|
18726
|
+
fontFamily = 'Arial';
|
|
18727
|
+
fontSize = 16;
|
|
18728
|
+
fontColor = '#000000';
|
|
18729
|
+
/** Screen-space x coordinate of the shape's top-left corner (like Path.x) */
|
|
18730
|
+
x = 0;
|
|
18731
|
+
/** Screen-space y coordinate of the shape's top-left corner (like Path.y) */
|
|
18732
|
+
y = 0;
|
|
18733
|
+
scale = 1;
|
|
18734
|
+
scaleFactor = 1;
|
|
18735
|
+
isDebugInfoVisible = true;
|
|
18736
|
+
isEditable = true;
|
|
18737
|
+
isEditing = false;
|
|
18738
|
+
editor = null;
|
|
18739
|
+
content = null;
|
|
18740
|
+
_schema = new Schema({
|
|
18741
|
+
nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
|
|
18742
|
+
marks: schema.spec.marks,
|
|
18743
|
+
});
|
|
18744
|
+
uneditedObject = null;
|
|
18745
|
+
/**
|
|
18746
|
+
* Returns the viewBox for the shape's SVG, using screen-space coordinates.
|
|
18747
|
+
* This follows the same pattern as KritzelPath.viewBox.
|
|
18748
|
+
*/
|
|
18749
|
+
get viewBox() {
|
|
18750
|
+
return `${this.x} ${this.y} ${this.width} ${this.height}`;
|
|
18751
|
+
}
|
|
18752
|
+
constructor(config) {
|
|
18753
|
+
super();
|
|
18754
|
+
if (config) {
|
|
18755
|
+
this.x = config.x ?? 0;
|
|
18756
|
+
this.y = config.y ?? 0;
|
|
18757
|
+
this.translateX = config.translateX ?? 0;
|
|
18758
|
+
this.translateY = config.translateY ?? 0;
|
|
18759
|
+
this.width = config.width ?? 100;
|
|
18760
|
+
this.height = config.height ?? 100;
|
|
18761
|
+
this.shapeType = config.shapeType ?? ShapeType.Rectangle;
|
|
18762
|
+
this.fillColor = config.fillColor ?? 'transparent';
|
|
18763
|
+
this.strokeColor = config.strokeColor ?? '#000000';
|
|
18764
|
+
this.strokeWidth = config.strokeWidth ?? 4;
|
|
18765
|
+
this.fontSize = config.fontSize ?? 16;
|
|
18766
|
+
this.fontFamily = config.fontFamily ?? 'Arial';
|
|
18767
|
+
this.fontColor = config.fontColor ?? '#000000';
|
|
18768
|
+
this.scale = config.scale ?? 1;
|
|
18769
|
+
this.scaleFactor = config.scaleX ?? 1;
|
|
18770
|
+
}
|
|
18771
|
+
}
|
|
18772
|
+
/**
|
|
18773
|
+
* Creates a new KritzelShape with screen-space coordinates.
|
|
18774
|
+
* Following the same pattern as KritzelPath.create():
|
|
18775
|
+
* - x, y are screen-space coordinates of the shape's top-left corner
|
|
18776
|
+
* - translateX, translateY should be set to -viewportTranslateX, -viewportTranslateY
|
|
18777
|
+
* - width, height are in screen-space
|
|
18778
|
+
* - scale is the viewport scale at creation time
|
|
18779
|
+
*/
|
|
18780
|
+
static create(core, config) {
|
|
18781
|
+
const object = new KritzelShape();
|
|
18782
|
+
object._core = core;
|
|
18783
|
+
object.id = object.generateId();
|
|
18784
|
+
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
18785
|
+
object.x = config?.x ?? 0;
|
|
18786
|
+
object.y = config?.y ?? 0;
|
|
18787
|
+
object.translateX = config?.translateX ?? 0;
|
|
18788
|
+
object.translateY = config?.translateY ?? 0;
|
|
18789
|
+
object.width = config?.width ?? 100;
|
|
18790
|
+
object.height = config?.height ?? 100;
|
|
18791
|
+
object.shapeType = config?.shapeType ?? ShapeType.Rectangle;
|
|
18792
|
+
object.fillColor = config?.fillColor ?? 'transparent';
|
|
18793
|
+
object.strokeColor = config?.strokeColor ?? '#000000';
|
|
18794
|
+
object.strokeWidth = config?.strokeWidth ?? 4;
|
|
18795
|
+
object.fontSize = config?.fontSize ?? 16;
|
|
18796
|
+
object.fontFamily = config?.fontFamily ?? 'Arial';
|
|
18797
|
+
object.fontColor = config?.fontColor ?? '#000000';
|
|
18798
|
+
object.backgroundColor = 'transparent';
|
|
18799
|
+
object.scaleFactor = 1;
|
|
18800
|
+
object.scale = core.store.state.scale;
|
|
18801
|
+
object.zIndex = core.store.currentZIndex;
|
|
18802
|
+
object.editor = object.createEditor();
|
|
18803
|
+
// Compute world-space translateX/Y from screen-space coordinates
|
|
18804
|
+
// This follows the same pattern as KritzelPath.updateDimensions()
|
|
18805
|
+
object.updateDimensions();
|
|
18806
|
+
return object;
|
|
18807
|
+
}
|
|
18808
|
+
/**
|
|
18809
|
+
* Updates the translateX/Y to world coordinates based on screen-space x, y.
|
|
18810
|
+
* This follows the same pattern as KritzelPath.updateDimensions().
|
|
18811
|
+
*
|
|
18812
|
+
* The formula: translateX = (x + initialTranslateX) / scale
|
|
18813
|
+
* where initialTranslateX was -viewportTranslateX
|
|
18814
|
+
*
|
|
18815
|
+
* This converts screen-space position to world coordinates.
|
|
18816
|
+
*/
|
|
18817
|
+
updateDimensions() {
|
|
18818
|
+
this.translateX = (this.x + this.translateX) / this.scale;
|
|
18819
|
+
this.translateY = (this.y + this.translateY) / this.scale;
|
|
18820
|
+
}
|
|
18821
|
+
mount(element) {
|
|
18822
|
+
if (element === null || this.isInViewport() === false) {
|
|
18823
|
+
return;
|
|
18824
|
+
}
|
|
18825
|
+
if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
|
|
18826
|
+
return;
|
|
18827
|
+
}
|
|
18828
|
+
this.elementRef = element;
|
|
18829
|
+
this.isMounted = true;
|
|
18830
|
+
}
|
|
18831
|
+
mountTextEditor(element) {
|
|
18832
|
+
if (element === null) {
|
|
18833
|
+
return;
|
|
18834
|
+
}
|
|
18835
|
+
if (this.editor.dom.parentElement === element) {
|
|
18836
|
+
return;
|
|
18837
|
+
}
|
|
18838
|
+
element.style.fontFamily = this.fontFamily;
|
|
18839
|
+
element.style.fontSize = `${this.fontSize}pt`;
|
|
18840
|
+
element.style.color = this.fontColor;
|
|
18841
|
+
element.style.whiteSpace = 'pre-wrap';
|
|
18842
|
+
element.style.wordWrap = 'break-word';
|
|
18843
|
+
element.innerHTML = '';
|
|
18844
|
+
element.appendChild(this.editor.dom);
|
|
18845
|
+
}
|
|
18846
|
+
createEditor() {
|
|
18847
|
+
const doc = this._schema.node('doc', null, [this._schema.node('paragraph')]);
|
|
18848
|
+
return new EditorView(null, {
|
|
18849
|
+
state: EditorState.create({
|
|
18850
|
+
doc: doc,
|
|
18851
|
+
plugins: [keymap(baseKeymap)],
|
|
18852
|
+
}),
|
|
18853
|
+
editable: () => false,
|
|
18854
|
+
dispatchTransaction: transaction => {
|
|
18855
|
+
const newState = this.editor.state.apply(transaction);
|
|
18856
|
+
this.editor.updateState(newState);
|
|
18857
|
+
if (transaction.docChanged) {
|
|
18858
|
+
this.content = newState.doc.toJSON();
|
|
18859
|
+
if (!transaction.getMeta('fromRemote')) {
|
|
18860
|
+
this._core.store.state.objects.update(this, { temporary: true });
|
|
18861
|
+
}
|
|
18862
|
+
}
|
|
18863
|
+
},
|
|
18864
|
+
});
|
|
18865
|
+
}
|
|
18866
|
+
setContent(content) {
|
|
18867
|
+
this.content = content;
|
|
18868
|
+
if (this.editor && content) {
|
|
18869
|
+
const newDoc = this.editor.state.schema.nodeFromJSON(content);
|
|
18870
|
+
const tr = this.editor.state.tr.replaceWith(0, this.editor.state.doc.content.size, newDoc.content);
|
|
18871
|
+
tr.setMeta('fromRemote', true);
|
|
18872
|
+
this.editor.dispatch(tr);
|
|
18873
|
+
}
|
|
18874
|
+
}
|
|
18875
|
+
resize(x, y, width, height) {
|
|
18876
|
+
if (width <= 1 || height <= 1) {
|
|
18877
|
+
return;
|
|
18878
|
+
}
|
|
18879
|
+
this.width = width;
|
|
18880
|
+
this.height = height;
|
|
18881
|
+
this.translateX = x;
|
|
18882
|
+
this.translateY = y;
|
|
18883
|
+
this._core.store.state.objects.update(this);
|
|
18884
|
+
}
|
|
18885
|
+
focus(coords) {
|
|
18886
|
+
if (this.editor) {
|
|
18887
|
+
const doc = this.editor.state.doc;
|
|
18888
|
+
if (coords?.x && coords?.y) {
|
|
18889
|
+
const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
|
|
18890
|
+
if (pos) {
|
|
18891
|
+
this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
|
|
18892
|
+
this.editor.focus();
|
|
18893
|
+
if (KritzelDevicesHelper.isIOS()) {
|
|
18894
|
+
this.scrollIntoViewOnIOS();
|
|
18895
|
+
}
|
|
18896
|
+
return;
|
|
18897
|
+
}
|
|
18898
|
+
}
|
|
18899
|
+
const end = Math.max(1, doc.content.size - 1);
|
|
18900
|
+
this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
|
|
18901
|
+
this.editor.focus();
|
|
18902
|
+
if (KritzelDevicesHelper.isIOS()) {
|
|
18903
|
+
this.scrollIntoViewOnIOS();
|
|
18904
|
+
}
|
|
18905
|
+
}
|
|
18906
|
+
}
|
|
18907
|
+
scrollIntoViewOnIOS() {
|
|
18908
|
+
setTimeout(() => {
|
|
18909
|
+
if (this.editor && this.editor.dom) {
|
|
18910
|
+
this.editor.dom.scrollIntoView({
|
|
18911
|
+
behavior: 'smooth',
|
|
18912
|
+
block: 'center',
|
|
18913
|
+
inline: 'nearest',
|
|
18914
|
+
});
|
|
18915
|
+
}
|
|
18916
|
+
}, 300);
|
|
18917
|
+
}
|
|
18918
|
+
edit(event) {
|
|
18919
|
+
KritzelKeyboardHelper.disableInteractiveWidget();
|
|
18920
|
+
this.uneditedObject = this.clone();
|
|
18921
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('shape'));
|
|
18922
|
+
this.editor.setProps({ editable: () => true });
|
|
18923
|
+
this.isEditing = true;
|
|
18924
|
+
this._core.rerender();
|
|
18925
|
+
this.focus({ x: event?.clientX, y: event?.clientY });
|
|
18926
|
+
KritzelKeyboardHelper.enableInteractiveWidget();
|
|
18927
|
+
}
|
|
18928
|
+
save() {
|
|
18929
|
+
this.content = this.editor.state.doc.toJSON();
|
|
18930
|
+
this.editor.setProps({ editable: () => false });
|
|
18931
|
+
this.editor.dom.blur();
|
|
18932
|
+
this.isEditing = false;
|
|
18933
|
+
this._core.store.state.objects.consolidateTemporaryItems();
|
|
18934
|
+
this._core.store.state.objects.update(this);
|
|
18935
|
+
this._core.engine.emitObjectsChange();
|
|
18936
|
+
}
|
|
18937
|
+
handlePointerDown(event) {
|
|
18938
|
+
if (!this.isEditing) {
|
|
18939
|
+
return;
|
|
18940
|
+
}
|
|
18941
|
+
event.stopPropagation();
|
|
18942
|
+
}
|
|
18943
|
+
handlePointerMove(event) {
|
|
18944
|
+
if (!this.isEditing) {
|
|
18945
|
+
return;
|
|
18946
|
+
}
|
|
18947
|
+
event.stopPropagation();
|
|
18948
|
+
}
|
|
18949
|
+
handlePointerUp(event) {
|
|
18950
|
+
if (!this.isEditing) {
|
|
18951
|
+
return;
|
|
18952
|
+
}
|
|
18953
|
+
event.stopPropagation();
|
|
18954
|
+
}
|
|
18955
|
+
copy() {
|
|
18956
|
+
const copiedObject = super.copy();
|
|
18957
|
+
copiedObject.editor = copiedObject.createEditor();
|
|
18958
|
+
if (this.content) {
|
|
18959
|
+
copiedObject.setContent(this.content);
|
|
18960
|
+
}
|
|
18961
|
+
return copiedObject;
|
|
18962
|
+
}
|
|
18963
|
+
serialize() {
|
|
18964
|
+
const { _core, _elementRef, _schema, element, totalWidth, totalHeight, editor, uneditedObject, ...remainingProps } = this;
|
|
18965
|
+
const clonedProps = structuredClone(remainingProps);
|
|
18966
|
+
if (element && typeof element === 'object' && 'nodeType' in element && element.nodeType === 1) {
|
|
18967
|
+
clonedProps.element = element.cloneNode(true);
|
|
18968
|
+
}
|
|
18969
|
+
return clonedProps;
|
|
18970
|
+
}
|
|
18971
|
+
deserialize(object) {
|
|
18972
|
+
super.deserialize(object);
|
|
18973
|
+
if (object.content) {
|
|
18974
|
+
this.setContent(object.content);
|
|
18975
|
+
}
|
|
18976
|
+
return this;
|
|
18977
|
+
}
|
|
18978
|
+
/**
|
|
18979
|
+
* Returns the clipping polygon for arrow intersection.
|
|
18980
|
+
* For ellipse: returns a many-sided polygon approximation
|
|
18981
|
+
* For triangle: returns the 3 corners
|
|
18982
|
+
* For rectangle: returns null (uses default rotatedPolygon)
|
|
18983
|
+
*
|
|
18984
|
+
* Includes padding for half the stroke width so arrow heads don't overlap the stroke.
|
|
18985
|
+
*/
|
|
18986
|
+
getClipPolygon() {
|
|
18987
|
+
// Calculate world-space center and dimensions
|
|
18988
|
+
const worldWidth = this.totalWidth / this.scale;
|
|
18989
|
+
const worldHeight = this.totalHeight / this.scale;
|
|
18990
|
+
const centerX = this.translateX + worldWidth / 2;
|
|
18991
|
+
const centerY = this.translateY + worldHeight / 2;
|
|
18992
|
+
// Add padding for stroke width so arrows don't overlap the stroke
|
|
18993
|
+
const strokePadding = (this.strokeWidth / this.scale) / 2;
|
|
18994
|
+
switch (this.shapeType) {
|
|
18995
|
+
case ShapeType.Ellipse:
|
|
18996
|
+
// Return a 32-segment polygon approximation of the ellipse
|
|
18997
|
+
// Add stroke padding to radii
|
|
18998
|
+
return KritzelGeometryHelper.getEllipsePolygonApproximation(centerX, centerY, worldWidth / 2 + strokePadding, worldHeight / 2 + strokePadding, 32, this.rotation);
|
|
18999
|
+
case ShapeType.Triangle:
|
|
19000
|
+
// Return the 3 corners of the triangle in world coordinates
|
|
19001
|
+
// Triangle: top-center, bottom-right, bottom-left
|
|
19002
|
+
// Expand each vertex outward from center by strokePadding
|
|
19003
|
+
const expandVertex = (vx, vy) => {
|
|
19004
|
+
const dx = vx - centerX;
|
|
19005
|
+
const dy = vy - centerY;
|
|
19006
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
19007
|
+
if (dist === 0)
|
|
19008
|
+
return { x: vx, y: vy };
|
|
19009
|
+
const scale = (dist + strokePadding) / dist;
|
|
19010
|
+
return {
|
|
19011
|
+
x: centerX + dx * scale,
|
|
19012
|
+
y: centerY + dy * scale
|
|
19013
|
+
};
|
|
19014
|
+
};
|
|
19015
|
+
const topX = this.translateX + worldWidth / 2;
|
|
19016
|
+
const topY = this.translateY;
|
|
19017
|
+
const bottomLeftX = this.translateX;
|
|
19018
|
+
const bottomLeftY = this.translateY + worldHeight;
|
|
19019
|
+
const bottomRightX = this.translateX + worldWidth;
|
|
19020
|
+
const bottomRightY = this.translateY + worldHeight;
|
|
19021
|
+
const expandedTop = expandVertex(topX, topY);
|
|
19022
|
+
const expandedBottomRight = expandVertex(bottomRightX, bottomRightY);
|
|
19023
|
+
const expandedBottomLeft = expandVertex(bottomLeftX, bottomLeftY);
|
|
19024
|
+
// Apply rotation around center if rotated
|
|
19025
|
+
if (this.rotation !== 0) {
|
|
19026
|
+
const cos = Math.cos(this.rotation);
|
|
19027
|
+
const sin = Math.sin(this.rotation);
|
|
19028
|
+
const rotate = (p) => {
|
|
19029
|
+
const dx = p.x - centerX;
|
|
19030
|
+
const dy = p.y - centerY;
|
|
19031
|
+
return {
|
|
19032
|
+
x: centerX + dx * cos - dy * sin,
|
|
19033
|
+
y: centerY + dx * sin + dy * cos
|
|
19034
|
+
};
|
|
19035
|
+
};
|
|
19036
|
+
return [
|
|
19037
|
+
rotate(expandedTop),
|
|
19038
|
+
rotate(expandedBottomRight),
|
|
19039
|
+
rotate(expandedBottomLeft)
|
|
19040
|
+
];
|
|
19041
|
+
}
|
|
19042
|
+
return [expandedTop, expandedBottomRight, expandedBottomLeft];
|
|
19043
|
+
case ShapeType.Rectangle:
|
|
19044
|
+
default:
|
|
19045
|
+
// For rectangles, return null to use the default rotatedPolygon
|
|
19046
|
+
return null;
|
|
19047
|
+
}
|
|
19048
|
+
}
|
|
19049
|
+
/**
|
|
19050
|
+
* Returns the SVG path for rendering the shape.
|
|
19051
|
+
* The path uses screen-space coordinates relative to (x, y).
|
|
19052
|
+
*/
|
|
19053
|
+
getSvgPath() {
|
|
19054
|
+
const w = this.width;
|
|
19055
|
+
const h = this.height;
|
|
19056
|
+
switch (this.shapeType) {
|
|
19057
|
+
case ShapeType.Rectangle:
|
|
19058
|
+
return `M ${this.x} ${this.y} L ${this.x + w} ${this.y} L ${this.x + w} ${this.y + h} L ${this.x} ${this.y + h} Z`;
|
|
19059
|
+
case ShapeType.Ellipse:
|
|
19060
|
+
const cx = this.x + w / 2;
|
|
19061
|
+
const cy = this.y + h / 2;
|
|
19062
|
+
const rx = w / 2;
|
|
19063
|
+
const ry = h / 2;
|
|
19064
|
+
return `M ${cx - rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx + rx} ${cy} A ${rx} ${ry} 0 1 0 ${cx - rx} ${cy}`;
|
|
19065
|
+
case ShapeType.Triangle:
|
|
19066
|
+
const topX = this.x + w / 2;
|
|
19067
|
+
const topY = this.y;
|
|
19068
|
+
const bottomLeftX = this.x;
|
|
19069
|
+
const bottomLeftY = this.y + h;
|
|
19070
|
+
const bottomRightX = this.x + w;
|
|
19071
|
+
const bottomRightY = this.y + h;
|
|
19072
|
+
return `M ${topX} ${topY} L ${bottomRightX} ${bottomRightY} L ${bottomLeftX} ${bottomLeftY} Z`;
|
|
19073
|
+
default:
|
|
19074
|
+
return `M ${this.x} ${this.y} L ${this.x + w} ${this.y} L ${this.x + w} ${this.y + h} L ${this.x} ${this.y + h} Z`;
|
|
19075
|
+
}
|
|
19076
|
+
}
|
|
19077
|
+
}
|
|
19078
|
+
|
|
19079
|
+
class KritzelShapeTool extends KritzelBaseTool {
|
|
19080
|
+
shapeType = ShapeType.Rectangle;
|
|
19081
|
+
fillColor = 'transparent';
|
|
19082
|
+
strokeColor = '#000000';
|
|
19083
|
+
strokeWidth = 4;
|
|
19084
|
+
fontFamily = 'Arial';
|
|
19085
|
+
fontSize = 16;
|
|
19086
|
+
fontColor = '#000000';
|
|
19087
|
+
palette = [
|
|
19088
|
+
'#000000',
|
|
19089
|
+
'#FFFFFF',
|
|
19090
|
+
'#FF0000',
|
|
19091
|
+
'#00FF00',
|
|
19092
|
+
'#0000FF',
|
|
19093
|
+
'#FFFF00',
|
|
19094
|
+
'#FF00FF',
|
|
19095
|
+
'#00FFFF',
|
|
19096
|
+
'#808080',
|
|
19097
|
+
'#C0C0C0',
|
|
19098
|
+
'#800000',
|
|
19099
|
+
'#008000',
|
|
19100
|
+
'#000080',
|
|
19101
|
+
'#808000',
|
|
19102
|
+
'#800080',
|
|
19103
|
+
];
|
|
19104
|
+
startX = 0;
|
|
19105
|
+
startY = 0;
|
|
19106
|
+
isDrawing = false;
|
|
19107
|
+
currentShape = null;
|
|
19108
|
+
constructor(core) {
|
|
19109
|
+
super(core);
|
|
19110
|
+
}
|
|
19111
|
+
handlePointerDown(event) {
|
|
19112
|
+
if (event.cancelable) {
|
|
19113
|
+
event.preventDefault();
|
|
19114
|
+
}
|
|
19115
|
+
if (event.pointerType === 'mouse') {
|
|
19116
|
+
const path = event.composedPath().slice(1);
|
|
19117
|
+
const objectElement = path.find(element => element.classList && element.classList.contains('object'));
|
|
19118
|
+
const object = this._core.findObjectById(objectElement?.id);
|
|
19119
|
+
const activeShape = this._core.store.activeShape;
|
|
19120
|
+
if (activeShape === null && object instanceof KritzelShape) {
|
|
19121
|
+
object.edit(event);
|
|
19122
|
+
return;
|
|
19123
|
+
}
|
|
19124
|
+
if (activeShape !== null && object instanceof KritzelShape) {
|
|
19125
|
+
activeShape.save();
|
|
19126
|
+
object.edit(event);
|
|
19127
|
+
return;
|
|
19128
|
+
}
|
|
19129
|
+
if (activeShape !== null && object instanceof KritzelShape === false) {
|
|
19130
|
+
this._core.resetActiveShape();
|
|
19131
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
19132
|
+
return;
|
|
19133
|
+
}
|
|
19134
|
+
if (KritzelEventHelper.isLeftClick(event) === false) {
|
|
19135
|
+
return;
|
|
19136
|
+
}
|
|
19137
|
+
this.startDrawing(event.clientX, event.clientY);
|
|
19138
|
+
}
|
|
19139
|
+
if (event.pointerType === 'touch') {
|
|
19140
|
+
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
19141
|
+
const path = event.composedPath().slice(1);
|
|
19142
|
+
const objectElement = path.find(element => element.classList && element.classList.contains('object'));
|
|
19143
|
+
const object = this._core.findObjectById(objectElement?.id);
|
|
19144
|
+
const activeShape = this._core.store.activeShape;
|
|
19145
|
+
if (activeShape === null && object instanceof KritzelShape) {
|
|
19146
|
+
object.edit(event);
|
|
19147
|
+
return;
|
|
19148
|
+
}
|
|
19149
|
+
if (activeShape !== null && object instanceof KritzelShape) {
|
|
19150
|
+
activeShape.save();
|
|
19151
|
+
object.edit(event);
|
|
19152
|
+
return;
|
|
19153
|
+
}
|
|
19154
|
+
if (activeShape !== null && object instanceof KritzelShape === false) {
|
|
19155
|
+
this._core.resetActiveShape();
|
|
19156
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
19157
|
+
return;
|
|
19158
|
+
}
|
|
19159
|
+
if (activePointers.length > 1) {
|
|
19160
|
+
return;
|
|
19161
|
+
}
|
|
19162
|
+
const clientX = Math.round(activePointers[0].clientX);
|
|
19163
|
+
const clientY = Math.round(activePointers[0].clientY);
|
|
19164
|
+
this.startDrawing(clientX, clientY);
|
|
19165
|
+
}
|
|
19166
|
+
}
|
|
19167
|
+
handlePointerMove(event) {
|
|
19168
|
+
if (event.cancelable) {
|
|
19169
|
+
event.preventDefault();
|
|
19170
|
+
}
|
|
19171
|
+
if (!this.isDrawing || !this.currentShape) {
|
|
19172
|
+
return;
|
|
19173
|
+
}
|
|
19174
|
+
if (event.pointerType === 'mouse') {
|
|
19175
|
+
this.updateShapeSize(event.clientX, event.clientY);
|
|
19176
|
+
}
|
|
19177
|
+
if (event.pointerType === 'touch') {
|
|
19178
|
+
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
19179
|
+
if (activePointers.length === 1) {
|
|
19180
|
+
const clientX = Math.round(activePointers[0].clientX);
|
|
19181
|
+
const clientY = Math.round(activePointers[0].clientY);
|
|
19182
|
+
this.updateShapeSize(clientX, clientY);
|
|
19183
|
+
}
|
|
19184
|
+
}
|
|
19185
|
+
}
|
|
19186
|
+
handlePointerUp(event) {
|
|
19187
|
+
if (event.cancelable) {
|
|
19188
|
+
event.preventDefault();
|
|
19189
|
+
}
|
|
19190
|
+
if (!this.isDrawing || !this.currentShape) {
|
|
19191
|
+
return;
|
|
19192
|
+
}
|
|
19193
|
+
this.finishDrawing();
|
|
19194
|
+
}
|
|
19195
|
+
/**
|
|
19196
|
+
* Start drawing a shape. Following the same pattern as LineTool/BrushTool:
|
|
19197
|
+
* - Store screen coordinates for startX, startY
|
|
19198
|
+
* - Set translateX/Y to -viewportTranslateX/Y (viewport offset)
|
|
19199
|
+
* - Set x, y to the actual screen position
|
|
19200
|
+
* - Let updateDimensions() convert to world coordinates
|
|
19201
|
+
*/
|
|
19202
|
+
startDrawing(clientX, clientY) {
|
|
19203
|
+
// Store screen coordinates (relative to host element)
|
|
19204
|
+
this.startX = clientX - this._core.store.offsetX;
|
|
19205
|
+
this.startY = clientY - this._core.store.offsetY;
|
|
19206
|
+
this.isDrawing = true;
|
|
19207
|
+
// Create shape using screen coordinates, following Path/Line pattern
|
|
19208
|
+
this.currentShape = KritzelShape.create(this._core, {
|
|
19209
|
+
x: this.startX,
|
|
19210
|
+
y: this.startY,
|
|
19211
|
+
translateX: -this._core.store.state.translateX,
|
|
19212
|
+
translateY: -this._core.store.state.translateY,
|
|
19213
|
+
width: 1,
|
|
19214
|
+
height: 1,
|
|
19215
|
+
shapeType: this.shapeType,
|
|
19216
|
+
fillColor: this.fillColor,
|
|
19217
|
+
strokeColor: this.strokeColor,
|
|
19218
|
+
strokeWidth: this.strokeWidth,
|
|
19219
|
+
fontSize: this.fontSize,
|
|
19220
|
+
fontFamily: this.fontFamily,
|
|
19221
|
+
fontColor: this.fontColor,
|
|
19222
|
+
});
|
|
19223
|
+
this._core.store.state.objects.insert(this.currentShape);
|
|
19224
|
+
this._core.rerender();
|
|
19225
|
+
}
|
|
19226
|
+
/**
|
|
19227
|
+
* Update shape size during drawing. Following the same pattern as LineTool:
|
|
19228
|
+
* - Use screen coordinates directly
|
|
19229
|
+
* - The shape's x, y, width, height are all in screen space
|
|
19230
|
+
* - updateDimensions() handles conversion to world coordinates
|
|
19231
|
+
*/
|
|
19232
|
+
updateShapeSize(clientX, clientY) {
|
|
19233
|
+
if (!this.currentShape) {
|
|
19234
|
+
return;
|
|
19235
|
+
}
|
|
19236
|
+
const currentX = clientX - this._core.store.offsetX;
|
|
19237
|
+
const currentY = clientY - this._core.store.offsetY;
|
|
19238
|
+
// Calculate bounding box in screen coordinates
|
|
19239
|
+
const minX = Math.min(this.startX, currentX);
|
|
19240
|
+
const minY = Math.min(this.startY, currentY);
|
|
19241
|
+
const width = Math.abs(currentX - this.startX);
|
|
19242
|
+
const height = Math.abs(currentY - this.startY);
|
|
19243
|
+
// Update shape with screen coordinates
|
|
19244
|
+
this.currentShape.x = minX;
|
|
19245
|
+
this.currentShape.y = minY;
|
|
19246
|
+
this.currentShape.width = Math.max(1, width);
|
|
19247
|
+
this.currentShape.height = Math.max(1, height);
|
|
19248
|
+
// Recalculate world-space translateX/Y
|
|
19249
|
+
// Reset translateX/Y to initial value before updateDimensions
|
|
19250
|
+
this.currentShape.translateX = -this._core.store.state.translateX;
|
|
19251
|
+
this.currentShape.translateY = -this._core.store.state.translateY;
|
|
19252
|
+
this.currentShape.updateDimensions();
|
|
19253
|
+
this._core.store.state.objects.update(this.currentShape);
|
|
19254
|
+
}
|
|
19255
|
+
finishDrawing() {
|
|
19256
|
+
if (!this.currentShape) {
|
|
19257
|
+
return;
|
|
19258
|
+
}
|
|
19259
|
+
// Remove shape if it's too small (likely an accidental click)
|
|
19260
|
+
// Compare in screen space
|
|
19261
|
+
if (this.currentShape.width < 10 && this.currentShape.height < 10) {
|
|
19262
|
+
const shapeId = this.currentShape.id;
|
|
19263
|
+
this._core.store.state.objects.remove(o => o.id === shapeId);
|
|
19264
|
+
}
|
|
19265
|
+
else {
|
|
19266
|
+
this.currentShape.zIndex = this._core.store.currentZIndex;
|
|
19267
|
+
this._core.store.state.objects.update(this.currentShape);
|
|
19268
|
+
this._core.engine.emitObjectsChange();
|
|
19269
|
+
this._core.selectObjects([this.currentShape]);
|
|
19270
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
19271
|
+
}
|
|
19272
|
+
this.isDrawing = false;
|
|
19273
|
+
this.currentShape = null;
|
|
19274
|
+
this._core.rerender();
|
|
19275
|
+
}
|
|
19276
|
+
}
|
|
19277
|
+
|
|
18535
19278
|
const ABSOLUTE_SCALE_MAX = 1000;
|
|
18536
19279
|
const ABSOLUTE_SCALE_MIN = 0.0001;
|
|
18537
19280
|
|
|
@@ -35770,6 +36513,14 @@ class KritzelViewport {
|
|
|
35770
36513
|
this._core.rerender();
|
|
35771
36514
|
}, 100);
|
|
35772
36515
|
}
|
|
36516
|
+
/**
|
|
36517
|
+
* Cancels any pending debounced viewport updates.
|
|
36518
|
+
* Should be called before switching workspaces to prevent the old workspace's
|
|
36519
|
+
* viewport state from being saved to the new workspace.
|
|
36520
|
+
*/
|
|
36521
|
+
cancelPendingUpdates() {
|
|
36522
|
+
this._debounceUpdate.cancel();
|
|
36523
|
+
}
|
|
35773
36524
|
handleResize() {
|
|
35774
36525
|
this._core.store.state.viewportWidth = this._core.store.state.host.clientWidth;
|
|
35775
36526
|
this._core.store.state.viewportHeight = this._core.store.state.host.clientHeight;
|
|
@@ -36082,7 +36833,7 @@ const DEFAULT_ENGINE_CONFIG = {
|
|
|
36082
36833
|
contextMenuY: 0,
|
|
36083
36834
|
skipContextMenu: false,
|
|
36084
36835
|
debugInfo: {
|
|
36085
|
-
showObjectInfo:
|
|
36836
|
+
showObjectInfo: true,
|
|
36086
36837
|
showViewportInfo: false
|
|
36087
36838
|
},
|
|
36088
36839
|
host: null,
|
|
@@ -36191,6 +36942,17 @@ class KritzelReviver {
|
|
|
36191
36942
|
case 'KritzelText':
|
|
36192
36943
|
revivedObj = KritzelText.create(this._core, obj.fontSize, obj.fontFamily).deserialize(obj);
|
|
36193
36944
|
break;
|
|
36945
|
+
case 'KritzelShape':
|
|
36946
|
+
revivedObj = KritzelShape.create(this._core, {
|
|
36947
|
+
shapeType: obj.shapeType,
|
|
36948
|
+
fillColor: obj.fillColor,
|
|
36949
|
+
strokeColor: obj.strokeColor,
|
|
36950
|
+
strokeWidth: obj.strokeWidth,
|
|
36951
|
+
fontSize: obj.fontSize,
|
|
36952
|
+
fontFamily: obj.fontFamily,
|
|
36953
|
+
fontColor: obj.fontColor,
|
|
36954
|
+
}).deserialize(obj);
|
|
36955
|
+
break;
|
|
36194
36956
|
case 'KritzelImage':
|
|
36195
36957
|
revivedObj = KritzelImage.create(this._core).deserialize(obj);
|
|
36196
36958
|
break;
|
|
@@ -36221,6 +36983,9 @@ class KritzelReviver {
|
|
|
36221
36983
|
case 'KritzelLineTool':
|
|
36222
36984
|
revivedObj = new KritzelLineTool(this._core);
|
|
36223
36985
|
break;
|
|
36986
|
+
case 'KritzelShapeTool':
|
|
36987
|
+
revivedObj = new KritzelShapeTool(this._core);
|
|
36988
|
+
break;
|
|
36224
36989
|
default:
|
|
36225
36990
|
revivedObj = obj;
|
|
36226
36991
|
}
|
|
@@ -36696,6 +37461,10 @@ class KritzelStore {
|
|
|
36696
37461
|
const activeTexts = this._state.objects.filter(o => o instanceof KritzelText && o.isEditing);
|
|
36697
37462
|
return activeTexts.length > 0 ? activeTexts[0] : null;
|
|
36698
37463
|
}
|
|
37464
|
+
get activeShape() {
|
|
37465
|
+
const activeShapes = this._state.objects.filter(o => o instanceof KritzelShape && o.isEditing);
|
|
37466
|
+
return activeShapes.length > 0 ? activeShapes[0] : null;
|
|
37467
|
+
}
|
|
36699
37468
|
get currentPath() {
|
|
36700
37469
|
const drawingPaths = this._state.objects.filter(o => o instanceof KritzelPath && o.isCompleted === false);
|
|
36701
37470
|
return drawingPaths.length > 0 ? drawingPaths[0] : null;
|
|
@@ -36944,6 +37713,11 @@ class KritzelCore {
|
|
|
36944
37713
|
if (this._store.state.objects && this._store.state.objects.isReady) {
|
|
36945
37714
|
this._store.state.objects.destroy();
|
|
36946
37715
|
}
|
|
37716
|
+
// Create new ObjectMap with its own Y.Doc for this workspace
|
|
37717
|
+
const objectsMap = new KritzelObjectMap();
|
|
37718
|
+
// Assign immediately so the UI shows an empty state while loading,
|
|
37719
|
+
// instead of showing the old workspace's objects with the new workspace's viewport
|
|
37720
|
+
this._store.state.objects = objectsMap;
|
|
36947
37721
|
// Set active workspace
|
|
36948
37722
|
this._store.state.activeWorkspace = activeWorkspace;
|
|
36949
37723
|
this._store.state.workspaces = this.loadWorkspacesFromAppState();
|
|
@@ -36952,10 +37726,7 @@ class KritzelCore {
|
|
|
36952
37726
|
this._store.state.translateX = viewport.translateX ?? 0;
|
|
36953
37727
|
this._store.state.translateY = viewport.translateY ?? 0;
|
|
36954
37728
|
this._store.state.scale = viewport.scale ?? 1;
|
|
36955
|
-
// Create new ObjectMap with its own Y.Doc for this workspace
|
|
36956
|
-
const objectsMap = new KritzelObjectMap();
|
|
36957
37729
|
await objectsMap.initialize(this, activeWorkspace.id, this._syncConfig);
|
|
36958
|
-
this._store.state.objects = objectsMap;
|
|
36959
37730
|
// Rebuild anchor index after loading objects
|
|
36960
37731
|
this._anchorManager.rebuildIndex();
|
|
36961
37732
|
this.engine.emitObjectsChange();
|
|
@@ -37332,6 +38103,12 @@ class KritzelCore {
|
|
|
37332
38103
|
}
|
|
37333
38104
|
}
|
|
37334
38105
|
}
|
|
38106
|
+
resetActiveShape() {
|
|
38107
|
+
const activeShape = this._store.activeShape;
|
|
38108
|
+
if (activeShape) {
|
|
38109
|
+
activeShape.save();
|
|
38110
|
+
}
|
|
38111
|
+
}
|
|
37335
38112
|
getObjectFromPointerEvent(event, selector = '.object') {
|
|
37336
38113
|
const shadowRoot = this._store.state.host?.shadowRoot;
|
|
37337
38114
|
if (!shadowRoot)
|
|
@@ -37404,6 +38181,14 @@ class KritzelCore {
|
|
|
37404
38181
|
return { x: worldX, y: worldY };
|
|
37405
38182
|
}
|
|
37406
38183
|
beforeWorkspaceChange() {
|
|
38184
|
+
// Cancel any pending debounced viewport updates to prevent them from
|
|
38185
|
+
// saving the old workspace's viewport to the new workspace
|
|
38186
|
+
this._kritzelEngine.viewport?.cancelPendingUpdates();
|
|
38187
|
+
// Immediately save the current workspace's viewport before switching
|
|
38188
|
+
const currentWorkspace = this._store.state.activeWorkspace;
|
|
38189
|
+
if (currentWorkspace) {
|
|
38190
|
+
this.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
|
|
38191
|
+
}
|
|
37407
38192
|
this.resetActiveText();
|
|
37408
38193
|
this.clearSelection();
|
|
37409
38194
|
this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
@@ -37833,9 +38618,9 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
|
|
|
37833
38618
|
height: this.core.store.state.viewportHeight / this.core.store.state.scale,
|
|
37834
38619
|
depth: 100,
|
|
37835
38620
|
};
|
|
37836
|
-
const visibleObjects = this.core.store.state.objects.query(viewportBounds);
|
|
38621
|
+
const visibleObjects = this.core.store.state.objects.query(viewportBounds).sort((a, b) => a.zIndex - b.zIndex);
|
|
37837
38622
|
this.core.cursorManager.applyCursor();
|
|
37838
|
-
return (h(Host, { key: '
|
|
38623
|
+
return (h(Host, { key: '209ccf8414c635c9e04ca4807c95a29c629071ec' }, this.core.store.state.debugInfo.showViewportInfo && (h("div", { key: 'df6a03d1341887960bb91cbaa0a5dca6880a9293', class: "debug-panel" }, h("div", { key: '65157757ec6549ad2af311085a9618ab661f5ac0' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: '20137b6c651a9aa8df15bce66d5bfe870a7af139' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: '49dd30286641236ae428c731bb181cb06269852e' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: 'd8ee431a10335e99aec40a596817765d7ee3f67b' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '34b1f31146080780433d6c1718d13bbfe397cb9b' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: '4c279a106101cf808c91a2be4987569b21ae52b3' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: '6ebd7ad3c803ef45d58a74180c52e8be8af8bca3' }, "PointerCount: ", this.core.store.state.pointers.size), h("div", { key: '345970c8b2b54f3a0d8fe1d9bb1b7b33023db386' }, "Scale: ", this.core.store.state?.scale), h("div", { key: 'fc265ae0e71cf22311cab3006dfc29b9d24397d2' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '9f921032a58b55e60f82d11a76f269051357d3e1' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: '6d197e06cc362a9ecb8bfe00d272aecfec2b49e1' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: '5313589ba2a509c95a5730dcf29c4003d9884cbf' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: '8af9f9d6e33a2897c20962048bbf2a058f9d4a45' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: '81aec0050d3e2122643b61fd725e71b25d97bc27' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: 'c9956f05c01b74ee1666d9395a2715c3463fe401' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: 'ae0a01c8f8aafc08326b136720c6a75b6aec6299' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: '7816d40d73248a55120440e6d721325e1894178e' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: 'c22383bacca0ada584f2e8a8577523c905d74ae2' }, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", { key: '8185a7318c6cdfde558cc372b79582d58b706f9e' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: '2d56b05377693ef032ab2316fa753ecedf264b9c' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: '2e2bf9fd321ef04dc0ac6dc21539eb0117c9fb23' }, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", { key: '3118ab970d5d37e01405c42308fc051d675d4bfa' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: 'd8a31065843f89552f2d9c03dcbca960a716fa6c' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: 'cb8d28b6ea63cbb6572f761011fccb847b748227' }, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", { key: 'd112a7e833c265085246817423557bfdc5b30b74' }, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { key: 'df4f302192a8fc9644b7f883618b0a0f8a600dc8', id: "origin", class: "origin", style: {
|
|
37839
38624
|
transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
|
|
37840
38625
|
} }, visibleObjects?.map(object => {
|
|
37841
38626
|
return (h("div", { key: object.id, style: {
|
|
@@ -37881,7 +38666,32 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
|
|
|
37881
38666
|
backgroundColor: object.backgroundColor,
|
|
37882
38667
|
overflow: 'visible',
|
|
37883
38668
|
textRendering: this.core.store.state.isScaling || this.core.store.state.isPanning ? 'optimizeSpeed' : 'auto',
|
|
37884
|
-
} })), KritzelClassHelper.isInstanceOf(object, '
|
|
38669
|
+
} })), KritzelClassHelper.isInstanceOf(object, 'KritzelShape') && (h("div", { ref: el => object.mount(el), onPointerDown: e => object.handlePointerDown(e), onPointerMove: e => object.handlePointerMove(e), onPointerUp: e => object.handlePointerUp(e), style: {
|
|
38670
|
+
width: '100%',
|
|
38671
|
+
height: '100%',
|
|
38672
|
+
position: 'relative',
|
|
38673
|
+
overflow: 'visible',
|
|
38674
|
+
} }, h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
|
|
38675
|
+
position: 'absolute',
|
|
38676
|
+
top: '0',
|
|
38677
|
+
left: '0',
|
|
38678
|
+
width: '100%',
|
|
38679
|
+
height: '100%',
|
|
38680
|
+
overflow: 'visible',
|
|
38681
|
+
pointerEvents: 'none',
|
|
38682
|
+
}, viewBox: object.viewBox, preserveAspectRatio: "none" }, h("path", { d: object.getSvgPath(), fill: object.fillColor, stroke: object.strokeColor, "stroke-width": object.strokeWidth })), h("div", { ref: el => object.mountTextEditor(el), style: {
|
|
38683
|
+
position: 'absolute',
|
|
38684
|
+
top: '0',
|
|
38685
|
+
left: '0',
|
|
38686
|
+
width: '100%',
|
|
38687
|
+
height: '100%',
|
|
38688
|
+
display: 'flex',
|
|
38689
|
+
alignItems: 'center',
|
|
38690
|
+
justifyContent: 'center',
|
|
38691
|
+
textAlign: 'center',
|
|
38692
|
+
overflow: 'hidden',
|
|
38693
|
+
pointerEvents: object.isEditing ? 'auto' : 'none',
|
|
38694
|
+
} }))), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (h("div", { ref: el => object.mount(el), style: {
|
|
37885
38695
|
width: '100%',
|
|
37886
38696
|
height: '100%',
|
|
37887
38697
|
pointerEvents: 'auto',
|
|
@@ -37897,7 +38707,13 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
|
|
|
37897
38707
|
borderWidth: KritzelDevicesHelper.isFirefox() ? object.borderWidth + 'px' : '0',
|
|
37898
38708
|
borderStyle: KritzelDevicesHelper.isFirefox() ? 'solid' : 'none',
|
|
37899
38709
|
borderColor: KritzelDevicesHelper.isFirefox() ? object.borderColor : 'transparent',
|
|
37900
|
-
} }))), this.core.store.state.debugInfo.showObjectInfo && object.isDebugInfoVisible && (h("
|
|
38710
|
+
} })))), this.core.store.state.debugInfo.showObjectInfo && object.isDebugInfoVisible && (h("div", { style: {
|
|
38711
|
+
pointerEvents: 'none',
|
|
38712
|
+
position: 'absolute',
|
|
38713
|
+
left: `${object.totalWidth}px`,
|
|
38714
|
+
top: '0',
|
|
38715
|
+
zIndex: (object.zIndex + 2).toString(),
|
|
38716
|
+
} }, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "rotationDegrees: ", object.rotationDegrees), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "zIndex: ", object.zIndex))), h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
|
|
37901
38717
|
zIndex: (object.zIndex + 1).toString(),
|
|
37902
38718
|
height: object?.totalHeight.toString(),
|
|
37903
38719
|
width: object?.totalWidth.toString(),
|
|
@@ -38053,7 +38869,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
|
|
|
38053
38869
|
stroke: 'var(--kritzel-snap-indicator-stroke, #3b82f6)',
|
|
38054
38870
|
strokeWidth: data.indicatorStrokeWidth,
|
|
38055
38871
|
} }))));
|
|
38056
|
-
})()), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '
|
|
38872
|
+
})()), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '81b44614c23f4016a1daa914ef8ea73eda0869eb', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
|
|
38057
38873
|
position: 'fixed',
|
|
38058
38874
|
left: `${this.core.store.state.contextMenuX}px`,
|
|
38059
38875
|
top: `${this.core.store.state.contextMenuY}px`,
|
|
@@ -38064,7 +38880,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
|
|
|
38064
38880
|
y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
|
|
38065
38881
|
}, this.core.store.selectionGroup?.objects);
|
|
38066
38882
|
this.hideContextMenu();
|
|
38067
|
-
}, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: '
|
|
38883
|
+
}, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: 'f748cd15c916d9fcb5fbf445167c69c1cc8aea63', core: this.core })));
|
|
38068
38884
|
}
|
|
38069
38885
|
static get watchers() { return {
|
|
38070
38886
|
"workspace": ["onWorkspaceChange"],
|
|
@@ -38147,7 +38963,7 @@ function defineCustomElement() {
|
|
|
38147
38963
|
} });
|
|
38148
38964
|
}
|
|
38149
38965
|
|
|
38150
|
-
export { isNode as A, min$2 as B, pow as C, HocuspocusProviderWebsocket as D, KritzelLine as E, KritzelLineTool as F, KritzelEraserTool as G, HocuspocusProvider as H, KritzelImageTool as I, KritzelCursorHelper as J, KritzelImage as K, KritzelSelectionTool as L, IndexedDBSyncProvider as M, KritzelAppStateMap as N, Observable$1 as O, KritzelAnchorManager as P, ABSOLUTE_SCALE_MAX as Q, ABSOLUTE_SCALE_MIN as R,
|
|
38151
|
-
//# sourceMappingURL=p-
|
|
38966
|
+
export { isNode as A, min$2 as B, pow as C, HocuspocusProviderWebsocket as D, KritzelLine as E, KritzelLineTool as F, KritzelEraserTool as G, HocuspocusProvider as H, KritzelImageTool as I, KritzelCursorHelper as J, KritzelImage as K, KritzelSelectionTool as L, IndexedDBSyncProvider as M, KritzelAppStateMap as N, Observable$1 as O, KritzelAnchorManager as P, ABSOLUTE_SCALE_MAX as Q, ABSOLUTE_SCALE_MIN as R, ShapeType as S, KritzelShapeTool as T, defineCustomElement as U, KritzelEngine as V, writeVarUint8Array$2 as a, readVarUint8Array$2 as b, applyUpdate as c, encodeStateVector as d, encodeStateAsUpdate as e, createEncoder$1 as f, createDecoder$1 as g, create$8 as h, fromBase64 as i, toBase64 as j, createUint8ArrayFromArrayBuffer as k, offChange as l, readVarString$2 as m, floor$2 as n, onChange as o, getUnixTime$1 as p, equalityDeep$1 as q, readVarUint$2 as r, setIfUndefined$1 as s, toUint8Array$1 as t, writeVarString$2 as u, varStorage as v, writeVarUint$2 as w, map as x, ObservableV2 as y, length$3 as z };
|
|
38967
|
+
//# sourceMappingURL=p-CnRfQsIC.js.map
|
|
38152
38968
|
|
|
38153
|
-
//# sourceMappingURL=p-
|
|
38969
|
+
//# sourceMappingURL=p-CnRfQsIC.js.map
|