kritzel-stencil 0.0.168 → 0.0.170
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-CK85ewK0.js → default-line-tool.config-JuTDR6PF.js} +515 -10
- package/dist/cjs/default-line-tool.config-JuTDR6PF.js.map +1 -0
- package/dist/cjs/index.cjs.js +2 -1
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/kritzel-color_22.cjs.entry.js +120 -6
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/stencil.cjs.js +1 -1
- package/dist/collection/classes/core/core.class.js +89 -1
- package/dist/collection/classes/core/core.class.js.map +1 -1
- package/dist/collection/classes/core/reviver.class.js +4 -0
- package/dist/collection/classes/core/reviver.class.js.map +1 -1
- package/dist/collection/classes/handlers/key.handler.js +3 -0
- package/dist/collection/classes/handlers/key.handler.js.map +1 -1
- package/dist/collection/classes/handlers/move.handler.js +63 -0
- package/dist/collection/classes/handlers/move.handler.js.map +1 -1
- package/dist/collection/classes/handlers/rotation.handler.js +2 -0
- package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
- package/dist/collection/classes/handlers/selection.handler.js +23 -5
- package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
- package/dist/collection/classes/objects/group.class.js +394 -0
- package/dist/collection/classes/objects/group.class.js.map +1 -0
- package/dist/collection/classes/objects/line.class.js +2 -1
- package/dist/collection/classes/objects/line.class.js.map +1 -1
- package/dist/collection/classes/objects/selection-group.class.js +20 -0
- package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
- package/dist/collection/classes/registries/icon-registry.class.js +2 -0
- package/dist/collection/classes/registries/icon-registry.class.js.map +1 -1
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +17 -2
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +43 -3
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/helpers/event.helper.js +10 -2
- package/dist/collection/helpers/event.helper.js.map +1 -1
- package/dist/collection/index.js +1 -0
- package/dist/collection/index.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 +27 -12
- 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-BG2m-Sq9.js → p-9Sbn9-7-.js} +611 -16
- package/dist/components/p-9Sbn9-7-.js.map +1 -0
- package/dist/components/{p-Bwv1dxAB.js → p-BUsg2vtg.js} +12 -4
- package/dist/components/{p-Bwv1dxAB.js.map → p-BUsg2vtg.js.map} +1 -1
- package/dist/components/{p-BoazmhlG.js → p-C6-tSCMR.js} +3 -3
- package/dist/components/{p-BoazmhlG.js.map → p-C6-tSCMR.js.map} +1 -1
- package/dist/components/{p-Cv4BGNPb.js → p-CIts5Uma.js} +4 -2
- package/dist/components/p-CIts5Uma.js.map +1 -0
- package/dist/components/{p-BSBMBjhq.js → p-CQd5oYXp.js} +3 -3
- package/dist/components/{p-BSBMBjhq.js.map → p-CQd5oYXp.js.map} +1 -1
- package/dist/components/{p-D8L0t-Ro.js → p-Co5HWjr6.js} +3 -3
- package/dist/components/{p-D8L0t-Ro.js.map → p-Co5HWjr6.js.map} +1 -1
- package/dist/components/{p-5OECjGHq.js → p-DG7VXGxX.js} +3 -3
- package/dist/components/{p-5OECjGHq.js.map → p-DG7VXGxX.js.map} +1 -1
- package/dist/components/{p-D1YAsWrL.js → p-D_uh1RUI.js} +3 -3
- package/dist/components/{p-D1YAsWrL.js.map → p-D_uh1RUI.js.map} +1 -1
- package/dist/components/{p-xcQV8l_c.js → p-cv2RCdI1.js} +7 -7
- package/dist/components/{p-xcQV8l_c.js.map → p-cv2RCdI1.js.map} +1 -1
- package/dist/components/{p-BmdYFhLx.js → p-nZdy-Ii5.js} +4 -4
- package/dist/components/{p-BmdYFhLx.js.map → p-nZdy-Ii5.js.map} +1 -1
- package/dist/components/{p-CiM-IPaD.js → p-y25EBKEA.js} +5 -5
- package/dist/components/{p-CiM-IPaD.js.map → p-y25EBKEA.js.map} +1 -1
- package/dist/esm/{default-line-tool.config-kK3fdCJH.js → default-line-tool.config-CuBm2vpW.js} +515 -11
- package/dist/esm/default-line-tool.config-CuBm2vpW.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/kritzel-color_22.entry.js +120 -6
- 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-CuBm2vpW.js +2 -0
- package/dist/stencil/p-CuBm2vpW.js.map +1 -0
- package/dist/stencil/p-c9201236.entry.js +10 -0
- package/dist/stencil/p-c9201236.entry.js.map +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/core/core.class.d.ts +11 -1
- package/dist/types/classes/handlers/move.handler.d.ts +11 -0
- package/dist/types/classes/objects/group.class.d.ts +97 -0
- package/dist/types/classes/objects/selection-group.class.d.ts +5 -0
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -0
- package/dist/types/components.d.ts +4 -2
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
- package/dist/cjs/default-line-tool.config-CK85ewK0.js.map +0 -1
- package/dist/components/p-BG2m-Sq9.js.map +0 -1
- package/dist/components/p-Cv4BGNPb.js.map +0 -1
- package/dist/esm/default-line-tool.config-kK3fdCJH.js.map +0 -1
- package/dist/stencil/p-8ee3959e.entry.js +0 -10
- package/dist/stencil/p-8ee3959e.entry.js.map +0 -1
- package/dist/stencil/p-kK3fdCJH.js +0 -2
- package/dist/stencil/p-kK3fdCJH.js.map +0 -1
package/dist/cjs/{default-line-tool.config-CK85ewK0.js → default-line-tool.config-JuTDR6PF.js}
RENAMED
|
@@ -14768,7 +14768,8 @@ class KritzelLine extends KritzelBaseObject {
|
|
|
14768
14768
|
this._core.store.state.objects.update(this);
|
|
14769
14769
|
}
|
|
14770
14770
|
hitTest(x, y) {
|
|
14771
|
-
const
|
|
14771
|
+
const minHitThreshold = 20;
|
|
14772
|
+
const strokeWidth = Math.max(this.strokeWidth, minHitThreshold);
|
|
14772
14773
|
const halfStroke = strokeWidth / this.scale / 2;
|
|
14773
14774
|
if (this._adjustedPoints === null) {
|
|
14774
14775
|
this._adjustedPoints = this.computeAdjustedPoints();
|
|
@@ -15201,6 +15202,399 @@ class KritzelLine extends KritzelBaseObject {
|
|
|
15201
15202
|
}
|
|
15202
15203
|
}
|
|
15203
15204
|
|
|
15205
|
+
/**
|
|
15206
|
+
* KritzelGroup represents a permanent grouping of objects that act as a single unit.
|
|
15207
|
+
*
|
|
15208
|
+
* Unlike KritzelSelectionGroup (which is ephemeral and used for temporary multi-selection),
|
|
15209
|
+
* KritzelGroup is persisted and saved with the workspace. Grouped objects move, resize,
|
|
15210
|
+
* rotate, copy, and delete together as one unit.
|
|
15211
|
+
*
|
|
15212
|
+
* Key features:
|
|
15213
|
+
* - Supports nested groups (groups can contain other groups)
|
|
15214
|
+
* - Clicking any child selects the entire group
|
|
15215
|
+
* - Can be ungrouped to restore children to top-level objects
|
|
15216
|
+
*/
|
|
15217
|
+
class KritzelGroup extends KritzelBaseObject {
|
|
15218
|
+
__class__ = 'KritzelGroup';
|
|
15219
|
+
/**
|
|
15220
|
+
* IDs of child objects within this group.
|
|
15221
|
+
* Children can be any KritzelBaseObject, including other KritzelGroups for nesting.
|
|
15222
|
+
*/
|
|
15223
|
+
childIds = [];
|
|
15224
|
+
/**
|
|
15225
|
+
* Snapshots of child states for transformation operations (resize, rotate).
|
|
15226
|
+
* Similar pattern to KritzelSelectionGroup.
|
|
15227
|
+
*/
|
|
15228
|
+
unchangedChildSnapshots = new Map();
|
|
15229
|
+
snapshotRotation = 0;
|
|
15230
|
+
snapshotTranslateX = 0;
|
|
15231
|
+
snapshotTranslateY = 0;
|
|
15232
|
+
snapshotTotalWidth = 0;
|
|
15233
|
+
snapshotTotalHeight = 0;
|
|
15234
|
+
snapshotScale = 1;
|
|
15235
|
+
/**
|
|
15236
|
+
* Retrieves the actual child objects from the store by their IDs.
|
|
15237
|
+
*/
|
|
15238
|
+
get children() {
|
|
15239
|
+
return this.childIds
|
|
15240
|
+
.map(id => {
|
|
15241
|
+
const found = this._core.store.state.objects.filter(obj => obj.id === id);
|
|
15242
|
+
return found.length > 0 ? found[0] : null;
|
|
15243
|
+
})
|
|
15244
|
+
.filter((obj) => obj !== null);
|
|
15245
|
+
}
|
|
15246
|
+
/**
|
|
15247
|
+
* Returns the number of children in this group.
|
|
15248
|
+
*/
|
|
15249
|
+
get length() {
|
|
15250
|
+
return this.childIds.length;
|
|
15251
|
+
}
|
|
15252
|
+
/**
|
|
15253
|
+
* Creates a new empty KritzelGroup.
|
|
15254
|
+
*/
|
|
15255
|
+
static create(core) {
|
|
15256
|
+
const group = new KritzelGroup();
|
|
15257
|
+
group._core = core;
|
|
15258
|
+
group.id = group.generateId();
|
|
15259
|
+
group.workspaceId = core.store.state.activeWorkspace.id;
|
|
15260
|
+
group.scale = core.store.state.scale;
|
|
15261
|
+
group.zIndex = core.store.currentZIndex;
|
|
15262
|
+
return group;
|
|
15263
|
+
}
|
|
15264
|
+
/**
|
|
15265
|
+
* Creates a KritzelGroup from an array of objects.
|
|
15266
|
+
* The objects are added as children and their bounding box is calculated.
|
|
15267
|
+
*/
|
|
15268
|
+
static createFromObjects(core, objects) {
|
|
15269
|
+
const group = KritzelGroup.create(core);
|
|
15270
|
+
// Add all objects as children
|
|
15271
|
+
objects.forEach(obj => {
|
|
15272
|
+
group.childIds.push(obj.id);
|
|
15273
|
+
});
|
|
15274
|
+
// Calculate bounding box from children
|
|
15275
|
+
group.refreshBoundingBox();
|
|
15276
|
+
group.captureChildSnapshots();
|
|
15277
|
+
return group;
|
|
15278
|
+
}
|
|
15279
|
+
/**
|
|
15280
|
+
* Finds the parent KritzelGroup that contains the given object as a child.
|
|
15281
|
+
* Returns null if the object is not a child of any group.
|
|
15282
|
+
*/
|
|
15283
|
+
static findParentGroup(core, objectId) {
|
|
15284
|
+
const allGroups = core.store.state.objects
|
|
15285
|
+
.filter(obj => obj.__class__ === 'KritzelGroup');
|
|
15286
|
+
for (const group of allGroups) {
|
|
15287
|
+
if (group.childIds.includes(objectId)) {
|
|
15288
|
+
return group;
|
|
15289
|
+
}
|
|
15290
|
+
}
|
|
15291
|
+
return null;
|
|
15292
|
+
}
|
|
15293
|
+
/**
|
|
15294
|
+
* Adds a child object to this group.
|
|
15295
|
+
*/
|
|
15296
|
+
addChild(object) {
|
|
15297
|
+
if (!this.childIds.includes(object.id)) {
|
|
15298
|
+
this.childIds.push(object.id);
|
|
15299
|
+
this.refreshBoundingBox();
|
|
15300
|
+
this.captureChildSnapshots();
|
|
15301
|
+
}
|
|
15302
|
+
}
|
|
15303
|
+
/**
|
|
15304
|
+
* Removes a child object from this group.
|
|
15305
|
+
*/
|
|
15306
|
+
removeChild(objectId) {
|
|
15307
|
+
const index = this.childIds.indexOf(objectId);
|
|
15308
|
+
if (index !== -1) {
|
|
15309
|
+
this.childIds.splice(index, 1);
|
|
15310
|
+
this.refreshBoundingBox();
|
|
15311
|
+
this.captureChildSnapshots();
|
|
15312
|
+
}
|
|
15313
|
+
}
|
|
15314
|
+
/**
|
|
15315
|
+
* Ungroups this group, returning all children to top-level objects.
|
|
15316
|
+
* The group itself should be removed after calling this.
|
|
15317
|
+
*/
|
|
15318
|
+
ungroup() {
|
|
15319
|
+
return this.children;
|
|
15320
|
+
}
|
|
15321
|
+
/**
|
|
15322
|
+
* Finalizes the group after children have been positioned (e.g., after paste).
|
|
15323
|
+
* Refreshes the bounding box and captures child snapshots.
|
|
15324
|
+
*/
|
|
15325
|
+
finalize() {
|
|
15326
|
+
this.refreshBoundingBox();
|
|
15327
|
+
this.captureChildSnapshots();
|
|
15328
|
+
}
|
|
15329
|
+
/**
|
|
15330
|
+
* Recalculates the group's bounding box based on its children.
|
|
15331
|
+
*/
|
|
15332
|
+
refreshBoundingBox() {
|
|
15333
|
+
if (this.children.length === 0) {
|
|
15334
|
+
this.width = 0;
|
|
15335
|
+
this.height = 0;
|
|
15336
|
+
this.translateX = 0;
|
|
15337
|
+
this.translateY = 0;
|
|
15338
|
+
return;
|
|
15339
|
+
}
|
|
15340
|
+
if (this.children.length === 1) {
|
|
15341
|
+
// Single child: inherit its bounding box
|
|
15342
|
+
const child = this.children[0];
|
|
15343
|
+
this.translateX = child.boundingBox.x;
|
|
15344
|
+
this.translateY = child.boundingBox.y;
|
|
15345
|
+
this.width = child.boundingBox.width * this.scale;
|
|
15346
|
+
this.height = child.boundingBox.height * this.scale;
|
|
15347
|
+
return;
|
|
15348
|
+
}
|
|
15349
|
+
// Multiple children: calculate encompassing bounding box
|
|
15350
|
+
const rotation = this.rotation;
|
|
15351
|
+
const cos = Math.cos(-rotation);
|
|
15352
|
+
const sin = Math.sin(-rotation);
|
|
15353
|
+
let minX = Infinity;
|
|
15354
|
+
let maxX = -Infinity;
|
|
15355
|
+
let minY = Infinity;
|
|
15356
|
+
let maxY = -Infinity;
|
|
15357
|
+
this.children.forEach(child => {
|
|
15358
|
+
const polygon = child.rotatedPolygon;
|
|
15359
|
+
const corners = [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
|
|
15360
|
+
corners.forEach(corner => {
|
|
15361
|
+
// Rotate corner into local space (aligned with group rotation)
|
|
15362
|
+
const rx = corner.x * cos - corner.y * sin;
|
|
15363
|
+
const ry = corner.x * sin + corner.y * cos;
|
|
15364
|
+
if (rx < minX)
|
|
15365
|
+
minX = rx;
|
|
15366
|
+
if (rx > maxX)
|
|
15367
|
+
maxX = rx;
|
|
15368
|
+
if (ry < minY)
|
|
15369
|
+
minY = ry;
|
|
15370
|
+
if (ry > maxY)
|
|
15371
|
+
maxY = ry;
|
|
15372
|
+
});
|
|
15373
|
+
});
|
|
15374
|
+
// Dimensions in world units (unrotated)
|
|
15375
|
+
const worldWidth = maxX - minX;
|
|
15376
|
+
const worldHeight = maxY - minY;
|
|
15377
|
+
this.width = (worldWidth - this.padding) * this.scale;
|
|
15378
|
+
this.height = (worldHeight - this.padding) * this.scale;
|
|
15379
|
+
// Center of the box in rotated space
|
|
15380
|
+
const cRx = (minX + maxX) / 2;
|
|
15381
|
+
const cRy = (minY + maxY) / 2;
|
|
15382
|
+
// Rotate center back to world space
|
|
15383
|
+
const cosR = Math.cos(rotation);
|
|
15384
|
+
const sinR = Math.sin(rotation);
|
|
15385
|
+
const cx = cRx * cosR - cRy * sinR;
|
|
15386
|
+
const cy = cRx * sinR + cRy * cosR;
|
|
15387
|
+
this.translateX = cx - (this.width / this.scale + 2 * this.padding) / 2;
|
|
15388
|
+
this.translateY = cy - (this.height / this.scale + 2 * this.padding) / 2;
|
|
15389
|
+
}
|
|
15390
|
+
/**
|
|
15391
|
+
* Captures snapshots of child states for transformation operations.
|
|
15392
|
+
*/
|
|
15393
|
+
captureChildSnapshots() {
|
|
15394
|
+
this.unchangedChildSnapshots.clear();
|
|
15395
|
+
this.snapshotRotation = this.rotation;
|
|
15396
|
+
this.snapshotTranslateX = this.translateX;
|
|
15397
|
+
this.snapshotTranslateY = this.translateY;
|
|
15398
|
+
this.snapshotTotalWidth = this.totalWidth;
|
|
15399
|
+
this.snapshotTotalHeight = this.totalHeight;
|
|
15400
|
+
this.snapshotScale = this.scale || 1;
|
|
15401
|
+
this.children.forEach(child => {
|
|
15402
|
+
this.unchangedChildSnapshots.set(child.id, {
|
|
15403
|
+
id: child.id,
|
|
15404
|
+
translateX: child.translateX,
|
|
15405
|
+
translateY: child.translateY,
|
|
15406
|
+
rotation: child.rotation,
|
|
15407
|
+
width: child.width,
|
|
15408
|
+
height: child.height,
|
|
15409
|
+
totalWidth: child.totalWidth,
|
|
15410
|
+
totalHeight: child.totalHeight,
|
|
15411
|
+
scale: child.scale,
|
|
15412
|
+
});
|
|
15413
|
+
});
|
|
15414
|
+
}
|
|
15415
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15416
|
+
// TRANSFORMATION METHODS
|
|
15417
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15418
|
+
move(startX, startY, endX, endY) {
|
|
15419
|
+
const deltaX = (startX - endX) / this._core.store.state.scale;
|
|
15420
|
+
const deltaY = (startY - endY) / this._core.store.state.scale;
|
|
15421
|
+
this.translateX += deltaX;
|
|
15422
|
+
this.translateY += deltaY;
|
|
15423
|
+
this._core.store.state.objects.transaction(() => {
|
|
15424
|
+
this._core.store.state.objects.update(this);
|
|
15425
|
+
this.children.forEach(child => {
|
|
15426
|
+
child.move(startX, startY, endX, endY);
|
|
15427
|
+
// Update any lines anchored to this child
|
|
15428
|
+
this._core.anchorManager.updateAnchorsForObject(child.id);
|
|
15429
|
+
});
|
|
15430
|
+
});
|
|
15431
|
+
// Update snapshots
|
|
15432
|
+
this.unchangedChildSnapshots.forEach(snapshot => {
|
|
15433
|
+
snapshot.translateX += deltaX;
|
|
15434
|
+
snapshot.translateY += deltaY;
|
|
15435
|
+
});
|
|
15436
|
+
}
|
|
15437
|
+
resize(x, y, width, height) {
|
|
15438
|
+
const widthScaleFactor = width / this.width;
|
|
15439
|
+
const heightScaleFactor = height / this.height;
|
|
15440
|
+
// Calculate old center
|
|
15441
|
+
const oldCenterX = this.translateX + this.totalWidth / 2 / this.scale;
|
|
15442
|
+
const oldCenterY = this.translateY + this.totalHeight / 2 / this.scale;
|
|
15443
|
+
// Calculate new center
|
|
15444
|
+
const newTotalWidth = width + this.padding * 2;
|
|
15445
|
+
const newTotalHeight = height + this.padding * 2;
|
|
15446
|
+
const newCenterX = x + newTotalWidth / 2 / this.scale;
|
|
15447
|
+
const newCenterY = y + newTotalHeight / 2 / this.scale;
|
|
15448
|
+
const rotation = this.rotation;
|
|
15449
|
+
const cos = Math.cos(-rotation);
|
|
15450
|
+
const sin = Math.sin(-rotation);
|
|
15451
|
+
const cosR = Math.cos(rotation);
|
|
15452
|
+
const sinR = Math.sin(rotation);
|
|
15453
|
+
this._core.store.state.objects.transaction(() => {
|
|
15454
|
+
this.children.forEach(child => {
|
|
15455
|
+
// Calculate child center
|
|
15456
|
+
const childCenterX = child.translateX + child.totalWidth / 2 / child.scale;
|
|
15457
|
+
const childCenterY = child.translateY + child.totalHeight / 2 / child.scale;
|
|
15458
|
+
// Vector from old group center to child center
|
|
15459
|
+
const dx = childCenterX - oldCenterX;
|
|
15460
|
+
const dy = childCenterY - oldCenterY;
|
|
15461
|
+
// Rotate to local space
|
|
15462
|
+
const localX = dx * cos - dy * sin;
|
|
15463
|
+
const localY = dx * sin + dy * cos;
|
|
15464
|
+
// Scale in local space
|
|
15465
|
+
const scaledLocalX = localX * widthScaleFactor;
|
|
15466
|
+
const scaledLocalY = localY * heightScaleFactor;
|
|
15467
|
+
// Rotate back to world space
|
|
15468
|
+
const rotatedX = scaledLocalX * cosR - scaledLocalY * sinR;
|
|
15469
|
+
const rotatedY = scaledLocalX * sinR + scaledLocalY * cosR;
|
|
15470
|
+
// New child center
|
|
15471
|
+
const newChildCenterX = newCenterX + rotatedX;
|
|
15472
|
+
const newChildCenterY = newCenterY + rotatedY;
|
|
15473
|
+
// Calculate relative rotation for scaling
|
|
15474
|
+
const relativeRotation = child.rotation - rotation;
|
|
15475
|
+
const cosRel = Math.cos(relativeRotation);
|
|
15476
|
+
const sinRel = Math.sin(relativeRotation);
|
|
15477
|
+
const newChildWidthScale = Math.sqrt(Math.pow(widthScaleFactor * cosRel, 2) + Math.pow(heightScaleFactor * sinRel, 2));
|
|
15478
|
+
const newChildHeightScale = Math.sqrt(Math.pow(widthScaleFactor * sinRel, 2) + Math.pow(heightScaleFactor * cosRel, 2));
|
|
15479
|
+
const updatedWidth = child.width * newChildWidthScale;
|
|
15480
|
+
const updatedHeight = child.height * newChildHeightScale;
|
|
15481
|
+
const updatedTotalWidth = updatedWidth + child.padding * 2;
|
|
15482
|
+
const updatedTotalHeight = updatedHeight + child.padding * 2;
|
|
15483
|
+
const updatedX = newChildCenterX - updatedTotalWidth / 2 / child.scale;
|
|
15484
|
+
const updatedY = newChildCenterY - updatedTotalHeight / 2 / child.scale;
|
|
15485
|
+
child.resize(updatedX, updatedY, updatedWidth, updatedHeight);
|
|
15486
|
+
// Update anchored lines
|
|
15487
|
+
this._core.anchorManager.updateAnchorsForObject(child.id);
|
|
15488
|
+
});
|
|
15489
|
+
this.refreshBoundingBox();
|
|
15490
|
+
this.captureChildSnapshots();
|
|
15491
|
+
this._core.store.state.objects.update(this);
|
|
15492
|
+
});
|
|
15493
|
+
}
|
|
15494
|
+
rotate(value) {
|
|
15495
|
+
this.rotation = value;
|
|
15496
|
+
const centerX = this.translateX + this.totalWidth / 2 / this.scale;
|
|
15497
|
+
const centerY = this.translateY + this.totalHeight / 2 / this.scale;
|
|
15498
|
+
const angle = value - this.snapshotRotation;
|
|
15499
|
+
const cos = Math.cos(angle);
|
|
15500
|
+
const sin = Math.sin(angle);
|
|
15501
|
+
this._core.store.state.objects.transaction(() => {
|
|
15502
|
+
this._core.store.state.objects.update(this);
|
|
15503
|
+
this.children.forEach(child => {
|
|
15504
|
+
const unchangedSnapshot = this.unchangedChildSnapshots.get(child.id);
|
|
15505
|
+
if (!unchangedSnapshot)
|
|
15506
|
+
return;
|
|
15507
|
+
const offsetX = this.getOffsetXToCenterFromSnapshot(unchangedSnapshot);
|
|
15508
|
+
const offsetY = this.getOffsetYToCenterFromSnapshot(unchangedSnapshot);
|
|
15509
|
+
const rotatedX = cos * offsetX - sin * offsetY;
|
|
15510
|
+
const rotatedY = sin * offsetX + cos * offsetY;
|
|
15511
|
+
child.translateX = centerX + rotatedX - child.totalWidth / 2 / child.scale;
|
|
15512
|
+
child.translateY = centerY + rotatedY - child.totalHeight / 2 / child.scale;
|
|
15513
|
+
child.rotate(this.children.length === 1 ? value : unchangedSnapshot.rotation + angle);
|
|
15514
|
+
});
|
|
15515
|
+
});
|
|
15516
|
+
}
|
|
15517
|
+
getOffsetXToCenterFromSnapshot(snapshot) {
|
|
15518
|
+
const childCenterX = snapshot.translateX + snapshot.totalWidth / snapshot.scale / 2;
|
|
15519
|
+
const groupScale = this.snapshotScale || this.scale || 1;
|
|
15520
|
+
const groupCenterX = this.snapshotTranslateX + this.snapshotTotalWidth / groupScale / 2;
|
|
15521
|
+
return childCenterX - groupCenterX;
|
|
15522
|
+
}
|
|
15523
|
+
getOffsetYToCenterFromSnapshot(snapshot) {
|
|
15524
|
+
const childCenterY = snapshot.translateY + snapshot.totalHeight / snapshot.scale / 2;
|
|
15525
|
+
const groupScale = this.snapshotScale || this.scale || 1;
|
|
15526
|
+
const groupCenterY = this.snapshotTranslateY + this.snapshotTotalHeight / groupScale / 2;
|
|
15527
|
+
return childCenterY - groupCenterY;
|
|
15528
|
+
}
|
|
15529
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15530
|
+
// HIT TESTING
|
|
15531
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15532
|
+
hitTest(x, y) {
|
|
15533
|
+
// Check if point is inside any child
|
|
15534
|
+
return this.children.some(child => child.hitTest(x, y));
|
|
15535
|
+
}
|
|
15536
|
+
hitTestPolygon(polygon) {
|
|
15537
|
+
// Check if polygon intersects with any child
|
|
15538
|
+
return this.children.some(child => child.hitTestPolygon(polygon));
|
|
15539
|
+
}
|
|
15540
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15541
|
+
// COPY & SERIALIZATION
|
|
15542
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15543
|
+
copy() {
|
|
15544
|
+
const copiedGroup = KritzelGroup.create(this._core);
|
|
15545
|
+
// Deep copy all children but DON'T add to store yet
|
|
15546
|
+
// Store the copied children temporarily for paste() to handle
|
|
15547
|
+
const copiedChildren = [];
|
|
15548
|
+
this.children
|
|
15549
|
+
.sort((a, b) => a.zIndex - b.zIndex)
|
|
15550
|
+
.forEach(child => {
|
|
15551
|
+
const copiedChild = child.copy();
|
|
15552
|
+
copiedChildren.push(copiedChild);
|
|
15553
|
+
copiedGroup.childIds.push(copiedChild.id);
|
|
15554
|
+
});
|
|
15555
|
+
// Store copied children on the group for paste() to access
|
|
15556
|
+
copiedGroup._pendingChildren = copiedChildren;
|
|
15557
|
+
// Copy group properties
|
|
15558
|
+
copiedGroup.rotation = this.rotation;
|
|
15559
|
+
copiedGroup.translateX = this.translateX;
|
|
15560
|
+
copiedGroup.translateY = this.translateY;
|
|
15561
|
+
copiedGroup.width = this.width;
|
|
15562
|
+
copiedGroup.height = this.height;
|
|
15563
|
+
return copiedGroup;
|
|
15564
|
+
}
|
|
15565
|
+
serialize() {
|
|
15566
|
+
const { _core, _elementRef, element, totalWidth, totalHeight, unchangedChildSnapshots, ...remainingProps } = this;
|
|
15567
|
+
const clonedProps = structuredClone(remainingProps);
|
|
15568
|
+
// Convert Map to plain object for serialization
|
|
15569
|
+
clonedProps.unchangedChildSnapshots = Object.fromEntries(this.unchangedChildSnapshots);
|
|
15570
|
+
return clonedProps;
|
|
15571
|
+
}
|
|
15572
|
+
deserialize(object) {
|
|
15573
|
+
super.deserialize(object);
|
|
15574
|
+
// Restore the Map from serialized object
|
|
15575
|
+
if (object.unchangedChildSnapshots) {
|
|
15576
|
+
this.unchangedChildSnapshots = new Map(Object.entries(object.unchangedChildSnapshots));
|
|
15577
|
+
}
|
|
15578
|
+
return this;
|
|
15579
|
+
}
|
|
15580
|
+
update() {
|
|
15581
|
+
this._core.store.state.objects.update(this);
|
|
15582
|
+
}
|
|
15583
|
+
/**
|
|
15584
|
+
* Updates the workspace ID for this group and all its children.
|
|
15585
|
+
*/
|
|
15586
|
+
updateWorkspaceId(workspaceId) {
|
|
15587
|
+
this.workspaceId = workspaceId;
|
|
15588
|
+
this.children.forEach(child => {
|
|
15589
|
+
child.workspaceId = workspaceId;
|
|
15590
|
+
// Recursively update nested groups
|
|
15591
|
+
if (child instanceof KritzelGroup) {
|
|
15592
|
+
child.updateWorkspaceId(workspaceId);
|
|
15593
|
+
}
|
|
15594
|
+
});
|
|
15595
|
+
}
|
|
15596
|
+
}
|
|
15597
|
+
|
|
15204
15598
|
exports.KritzelMouseButton = void 0;
|
|
15205
15599
|
(function (KritzelMouseButton) {
|
|
15206
15600
|
KritzelMouseButton[KritzelMouseButton["Left"] = 0] = "Left";
|
|
@@ -15221,11 +15615,19 @@ class KritzelEventHelper {
|
|
|
15221
15615
|
return !!contextMenu;
|
|
15222
15616
|
}
|
|
15223
15617
|
static onLongPress(event, onSuccess, onCancel) {
|
|
15224
|
-
|
|
15225
|
-
|
|
15618
|
+
if (event.pointerType !== 'touch') {
|
|
15619
|
+
onCancel?.();
|
|
15620
|
+
return () => { };
|
|
15621
|
+
}
|
|
15226
15622
|
const startX = event.clientX;
|
|
15227
15623
|
const startY = event.clientY;
|
|
15228
15624
|
const target = event.target;
|
|
15625
|
+
if (!target) {
|
|
15626
|
+
onCancel?.();
|
|
15627
|
+
return () => { };
|
|
15628
|
+
}
|
|
15629
|
+
const longPressTimeout = 400;
|
|
15630
|
+
const moveThreshold = 10;
|
|
15229
15631
|
const timer = setTimeout(() => {
|
|
15230
15632
|
removeListeners();
|
|
15231
15633
|
onSuccess(event);
|
|
@@ -15483,6 +15885,21 @@ class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
15483
15885
|
this.captureUnchangedSnapshots();
|
|
15484
15886
|
this.refreshObjectDimensions();
|
|
15485
15887
|
}
|
|
15888
|
+
/**
|
|
15889
|
+
* Prepares the selection group and its children for a transform interaction (rotate/resize).
|
|
15890
|
+
* Ensures snapshot state is aligned with the current visual state.
|
|
15891
|
+
*/
|
|
15892
|
+
beginTransform() {
|
|
15893
|
+
// Keep the selection group's bounding box current before snapshotting.
|
|
15894
|
+
this.refreshObjectDimensions();
|
|
15895
|
+
this.captureUnchangedSnapshots();
|
|
15896
|
+
// Groups need their own child snapshots aligned with the current transform.
|
|
15897
|
+
this.objects.forEach(obj => {
|
|
15898
|
+
if (obj instanceof KritzelGroup) {
|
|
15899
|
+
obj.finalize();
|
|
15900
|
+
}
|
|
15901
|
+
});
|
|
15902
|
+
}
|
|
15486
15903
|
deselectAllChildren() {
|
|
15487
15904
|
this.objects.forEach(obj => (obj.isSelected = false));
|
|
15488
15905
|
}
|
|
@@ -15743,6 +16160,10 @@ class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
15743
16160
|
return objCenterY - groupCenterY;
|
|
15744
16161
|
}
|
|
15745
16162
|
hitTest(x, y) {
|
|
16163
|
+
const isSingleLine = this.objects.length === 1 && this.objects[0].__class__ === 'KritzelLine';
|
|
16164
|
+
if (isSingleLine) {
|
|
16165
|
+
return this.objects[0].hitTest(x, y);
|
|
16166
|
+
}
|
|
15746
16167
|
const polygon = this.rotatedPolygon;
|
|
15747
16168
|
const polyPoints = [polygon.topLeft, polygon.topRight, polygon.bottomRight, polygon.bottomLeft];
|
|
15748
16169
|
if (KritzelGeometryHelper.isPointInPolygon({ x, y }, polyPoints)) {
|
|
@@ -16244,6 +16665,8 @@ KritzelIconRegistry.registerIcons({
|
|
|
16244
16665
|
'ellipsis-vertical': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ellipsis-vertical-icon lucide-ellipsis-vertical"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>',
|
|
16245
16666
|
'x': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>',
|
|
16246
16667
|
'check': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5"/></svg>',
|
|
16668
|
+
'group': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-group-icon lucide-group"><path d="M3 7V5c0-1.1.9-2 2-2h2"/><path d="M17 3h2c1.1 0 2 .9 2 2v2"/><path d="M21 17v2c0 1.1-.9 2-2 2h-2"/><path d="M7 21H5c-1.1 0-2-.9-2-2v-2"/><rect width="7" height="5" x="7" y="7" rx="1"/><rect width="7" height="5" x="10" y="12" rx="1"/></svg>',
|
|
16669
|
+
'ungroup': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ungroup-icon lucide-ungroup"><rect width="8" height="6" x="5" y="4" rx="1"/><rect width="8" height="6" x="11" y="14" rx="1"/></svg>',
|
|
16247
16670
|
'move-vertical': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-move-vertical-icon lucide-move-vertical" version="1.1" id="svg3"> <defs id="defs3" /> <path d="M12 2v20" id="path1" /> <path style="fill:#ffffff;stroke-width:2.5;stroke-dasharray:none;stroke-linejoin:round;paint-order:stroke fill markers" d="m 11.735575,22.661865 c -0.09259,-0.02798 -0.204674,-0.07661 -0.249076,-0.108068 -0.04441,-0.03147 -1.167275,-0.979853 -2.4952713,-2.10755 -1.8557024,-1.57581 -2.4300904,-2.079639 -2.4817336,-2.17687 -0.086514,-0.162885 -0.089504,-0.422449 -0.00664,-0.576334 0.1483053,-0.275409 0.437667,-0.436207 0.7830634,-0.435147 0.3692925,0.0011 0.3517326,-0.01122 2.168748,1.525599 L 11.12348,20.194964 V 11.999996 3.8050256 L 9.4546663,5.2164943 C 7.6376509,6.7533118 7.6552109,6.7409594 7.2859184,6.7420935 6.6681409,6.7439906 6.253658,6.1955854 6.5159903,5.723396 6.5738626,5.6192278 7.1368766,5.1267427 9.0629381,3.4955044 11.738128,1.2298067 11.640395,1.3026868 12.00355,1.3026868 c 0.363154,0 0.265421,-0.07288 2.940611,2.1928176 1.926062,1.6312383 2.489076,2.1237234 2.546948,2.2278916 0.262332,0.4721894 -0.15215,1.0205946 -0.769928,1.0186975 -0.369293,-0.00114 -0.351733,0.011218 -2.168748,-1.5255992 L 12.88362,3.8050256 v 8.1949704 8.194968 l 1.668813,-1.411469 c 1.817015,-1.536817 1.799455,-1.524464 2.168748,-1.525599 0.617772,-0.0019 1.032269,0.546521 0.769928,1.018687 -0.103474,0.18623 -4.919006,4.273935 -5.130582,4.355136 -0.20796,0.07981 -0.425829,0.09033 -0.624952,0.03014 z" id="path4" /> </svg>',
|
|
16248
16671
|
'hand': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hand-icon lucide-hand" version="1.1" id="svg4"> <defs id="defs4" /> <path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2" id="path1" /> <path d="M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" id="path2" /> <path d="M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8" id="path3" /> <path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15" id="path4" /> <path style="fill:#ffffff;stroke-width:0.0423032" d="M 11.478261,21.222477 C 9.6854059,21.139331 8.3341788,20.647346 7.1297169,19.639159 6.9698298,19.505327 5.949644,18.508708 4.8626374,17.42445 3.0780314,15.644357 2.8775851,15.435367 2.7968392,15.270602 2.5896561,14.847836 2.616354,14.436649 2.8771894,14.033085 c 0.136522,-0.211226 0.3837159,-0.398688 0.6367632,-0.482897 0.1529977,-0.05091 0.2326803,-0.05992 0.4470908,-0.05054 0.2250407,0.0098 0.2876577,0.02439 0.4554568,0.105827 0.1747854,0.08483 0.2933718,0.192702 1.1675186,1.062064 0.7182021,0.714271 1.0062041,0.982633 1.0998825,1.024878 0.1680197,0.07577 0.4756439,0.07817 0.6368269,0.005 0.1370772,-0.06226 0.2976691,-0.220818 0.3691296,-0.364463 0.072561,-0.145855 0.071573,-0.543545 -0.00169,-0.681911 -0.028747,-0.05429 -0.2476439,-0.296131 -0.4864385,-0.537426 l -0.4341716,-0.438718 0.00753,-3.989014 0.00753,-3.9890137 0.089246,-0.1883791 c 0.244787,-0.516692 0.7711718,-0.809716 1.3059705,-0.7269981 0.3973687,0.061462 0.7569953,0.3284904 0.9363122,0.6952277 l 0.093853,0.1919473 0.014101,2.4958872 0.014101,2.4958877 0.067385,0.149123 c 0.1186861,0.262654 0.4140438,0.457222 0.6940724,0.457222 0.2764172,0 0.5690532,-0.187563 0.6965992,-0.446482 l 0.06486,-0.131661 0.0141,-3.4970626 0.0141,-3.4970623 0.08982,-0.1896121 C 11.096301,3.0422103 11.506844,2.7755634 12,2.7755634 c 0.493156,0 0.903699,0.2666469 1.122868,0.7293016 l 0.08982,0.1896121 0.0141,3.2432432 c 0.01405,3.2315947 0.01432,3.2437077 0.07397,3.3726737 0.124721,0.269649 0.355908,0.424566 0.661411,0.443206 0.237954,0.01452 0.429018,-0.0627 0.591626,-0.239109 0.223655,-0.242637 0.208338,-0.06565 0.224113,-2.5896966 l 0.0141,-2.2561693 0.09385,-0.1919473 c 0.179317,-0.3667373 0.538944,-0.6337662 0.936313,-0.6952277 0.609359,-0.09425 1.208067,0.3054956 1.370981,0.9153772 0.03013,0.1127929 0.03773,0.6662436 0.038,2.7657391 3.74e-4,2.9328416 -0.008,2.8034316 0.197044,3.0364016 0.234927,0.266892 0.603828,0.337117 0.920407,0.175213 0.181933,-0.09304 0.329759,-0.261686 0.376309,-0.4293 0.01848,-0.06654 0.02929,-0.683932 0.0295,-1.684364 1.78e-4,-0.8783075 0.01239,-1.6530128 0.02751,-1.745346 0.08579,-0.5238478 0.505382,-0.9420803 1.039546,-1.0361716 0.607538,-0.1070155 1.25615,0.3485846 1.385876,0.973471 0.02211,0.1064847 0.02843,1.1397236 0.02169,3.5455556 -0.0093,3.324725 -0.01078,3.403075 -0.07062,3.770606 -0.126399,0.776213 -0.328814,1.41352 -0.669031,2.106456 -0.36657,0.746612 -0.72118,1.250303 -1.297841,1.843464 -1.185731,1.21966 -2.604527,1.933174 -4.300822,2.162889 -0.38234,0.05178 -2.604621,0.0785 -3.412456,0.04104 z" id="path16" /> </svg>',
|
|
16249
16672
|
'hand-grab': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hand-grab-icon lucide-hand-grab" version="1.1" id="svg5"> <defs id="defs5" /> <path d="M18 11.5V9a2 2 0 0 0-2-2a2 2 0 0 0-2 2v1.4" id="path1" /> <path d="M14 10V8a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2" id="path2" /> <path d="M10 9.9V9a2 2 0 0 0-2-2a2 2 0 0 0-2 2v5" id="path3" /> <path d="M6 14a2 2 0 0 0-2-2a2 2 0 0 0-2 2" id="path4" /> <path d="M18 11a2 2 0 1 1 4 0v3a8 8 0 0 1-8 8h-4a8 8 0 0 1-8-8 2 2 0 1 1 4 0" id="path5" /> <path style="fill:#ffffff;stroke-width:0.0423032" d="M 9.5887192,21.221364 C 8.0526856,21.128375 6.6533474,20.587008 5.4571093,19.622953 5.3019976,19.497947 5.0101058,19.225967 4.8084606,19.018552 4.2300382,18.423579 3.8474097,17.879011 3.4960953,17.150756 3.1017715,16.333345 2.9014937,15.633198 2.8052391,14.735605 c -0.097577,-0.909922 -0.019834,-1.263323 0.3569794,-1.622742 0.753018,-0.718257 1.9463784,-0.256949 2.0619296,0.797066 0.037839,0.345154 0.089701,0.477674 0.2472582,0.631806 0.2464521,0.241095 0.5958008,0.287445 0.9036474,0.119894 0.1478567,-0.08047 0.2303871,-0.16866 0.3266699,-0.349056 0.050118,-0.0939 0.05337,-0.2326 0.066784,-2.848413 L 6.7826087,8.7144536 6.8458627,8.559342 C 6.9736603,8.2459558 7.2463773,7.9734987 7.5581669,7.8477164 c 0.1253804,-0.050581 0.2118709,-0.062705 0.4512338,-0.063254 0.275392,-6.312e-4 0.3094658,0.00564 0.4867271,0.089609 0.264676,0.1253746 0.4771417,0.334346 0.6070085,0.5970252 l 0.1048543,0.212087 0.017338,0.7488899 c 0.019395,0.8377165 0.026343,0.8713745 0.2242006,1.0860245 0.1591067,0.172611 0.3522021,0.249908 0.5883018,0.235502 0.305503,-0.01864 0.53669,-0.173557 0.661411,-0.443206 0.05734,-0.123963 0.0605,-0.181852 0.07486,-1.3703236 0.01626,-1.3456629 0.0141,-1.3267758 0.182667,-1.5938092 0.257891,-0.4085268 0.77099,-0.6442307 1.228943,-0.5645435 0.471012,0.08196 0.850379,0.4102836 0.989676,0.8565175 0.04663,0.149383 0.0514,0.2860903 0.0514,1.4721724 0,0.8344844 0.01108,1.3591794 0.03064,1.4503554 0.04109,0.191585 0.179844,0.390224 0.342505,0.490321 0.27721,0.170587 0.693425,0.126085 0.92529,-0.09893 0.228986,-0.222224 0.234357,-0.25046 0.251582,-1.3227071 l 0.0152,-0.9463484 0.104855,-0.2120434 c 0.129872,-0.2626357 0.342372,-0.471626 0.607008,-0.5969817 0.177262,-0.083967 0.211335,-0.09024 0.486727,-0.089609 0.239363,5.486e-4 0.325854,0.012673 0.451234,0.063254 0.31179,0.1257823 0.584507,0.3982394 0.712304,0.7116256 0.0621,0.1522783 0.06351,0.1824139 0.07736,1.649824 0.01408,1.492435 0.0142,1.494914 0.07947,1.627432 0.0771,0.156535 0.2216,0.291061 0.395058,0.367789 0.09695,0.04289 0.169789,0.05275 0.325757,0.04411 0.230544,-0.01277 0.363779,-0.06826 0.506411,-0.21089 0.177062,-0.177061 0.198302,-0.25307 0.219359,-0.784959 0.02002,-0.505773 0.05012,-0.6549 0.175297,-0.868492 0.498409,-0.850471 1.728484,-0.8041941 2.173478,0.08177 0.131751,0.262312 0.134447,0.313526 0.122615,2.328965 -0.0104,1.771638 -0.01517,1.923481 -0.0714,2.273746 -0.123689,0.770512 -0.327108,1.411813 -0.668163,2.106456 -0.36657,0.746612 -0.72118,1.250303 -1.297841,1.843464 -1.180268,1.214041 -2.600612,1.930754 -4.287083,2.163284 -0.28697,0.03957 -0.685446,0.04782 -2.636536,0.05459 -1.26416,0.0044 -2.4698005,-0.0024 -2.6792012,-0.01507 z" id="path6" /> </svg>',
|
|
@@ -16315,6 +16738,8 @@ class KritzelBaseHandler {
|
|
|
16315
16738
|
}
|
|
16316
16739
|
}
|
|
16317
16740
|
|
|
16741
|
+
/** Threshold in screen pixels for disconnecting anchored lines during drag */
|
|
16742
|
+
const ANCHOR_DISCONNECT_THRESHOLD = 30;
|
|
16318
16743
|
class KritzelMoveHandler extends KritzelBaseHandler {
|
|
16319
16744
|
dragStartX;
|
|
16320
16745
|
dragStartY;
|
|
@@ -16322,6 +16747,11 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16322
16747
|
startY;
|
|
16323
16748
|
endX;
|
|
16324
16749
|
endY;
|
|
16750
|
+
/** Initial position when drag started (for calculating total accumulated distance) */
|
|
16751
|
+
initialDragX = 0;
|
|
16752
|
+
initialDragY = 0;
|
|
16753
|
+
/** Set of line IDs that have been disconnected from anchors during this drag */
|
|
16754
|
+
disconnectedLineIds = new Set();
|
|
16325
16755
|
hasMoved = false;
|
|
16326
16756
|
trackedPointerId = null;
|
|
16327
16757
|
constructor(core) {
|
|
@@ -16334,6 +16764,9 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16334
16764
|
this.startY = 0;
|
|
16335
16765
|
this.endX = 0;
|
|
16336
16766
|
this.endY = 0;
|
|
16767
|
+
this.initialDragX = 0;
|
|
16768
|
+
this.initialDragY = 0;
|
|
16769
|
+
this.disconnectedLineIds.clear();
|
|
16337
16770
|
this.hasMoved = false;
|
|
16338
16771
|
this.trackedPointerId = null;
|
|
16339
16772
|
}
|
|
@@ -16353,6 +16786,9 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16353
16786
|
this.dragStartY = clientY;
|
|
16354
16787
|
this.startX = this.dragStartX;
|
|
16355
16788
|
this.startY = this.dragStartY;
|
|
16789
|
+
this.initialDragX = clientX;
|
|
16790
|
+
this.initialDragY = clientY;
|
|
16791
|
+
this.disconnectedLineIds.clear();
|
|
16356
16792
|
this.trackedPointerId = event.pointerId;
|
|
16357
16793
|
}
|
|
16358
16794
|
else {
|
|
@@ -16378,6 +16814,9 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16378
16814
|
this.dragStartY = y;
|
|
16379
16815
|
this.startX = x;
|
|
16380
16816
|
this.startY = y;
|
|
16817
|
+
this.initialDragX = x;
|
|
16818
|
+
this.initialDragY = y;
|
|
16819
|
+
this.disconnectedLineIds.clear();
|
|
16381
16820
|
this.trackedPointerId = event.pointerId;
|
|
16382
16821
|
}
|
|
16383
16822
|
else {
|
|
@@ -16401,6 +16840,8 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16401
16840
|
const moveDeltaY = Math.abs(clientY - this.startY);
|
|
16402
16841
|
const moveThreshold = 5;
|
|
16403
16842
|
if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
|
|
16843
|
+
// Check for anchor disconnect threshold on lines
|
|
16844
|
+
this.checkAndDisconnectAnchors(clientX, clientY);
|
|
16404
16845
|
selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
|
|
16405
16846
|
this.dragStartX = clientX;
|
|
16406
16847
|
this.dragStartY = clientY;
|
|
@@ -16426,6 +16867,8 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16426
16867
|
const moveThreshold = 5;
|
|
16427
16868
|
if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
|
|
16428
16869
|
clearTimeout(this._core.store.state.longTouchTimeout);
|
|
16870
|
+
// Check for anchor disconnect threshold on lines
|
|
16871
|
+
this.checkAndDisconnectAnchors(x, y);
|
|
16429
16872
|
selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
|
|
16430
16873
|
this.dragStartX = x;
|
|
16431
16874
|
this.dragStartY = y;
|
|
@@ -16460,6 +16903,48 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
16460
16903
|
}
|
|
16461
16904
|
this.reset();
|
|
16462
16905
|
}
|
|
16906
|
+
/**
|
|
16907
|
+
* Checks if the total accumulated drag distance exceeds the anchor disconnect threshold.
|
|
16908
|
+
* If so, disconnects all anchors from any KritzelLine objects in the selection group.
|
|
16909
|
+
* This allows anchored lines to be freely moved after dragging beyond the threshold.
|
|
16910
|
+
*/
|
|
16911
|
+
checkAndDisconnectAnchors(currentX, currentY) {
|
|
16912
|
+
const totalDeltaX = currentX - this.initialDragX;
|
|
16913
|
+
const totalDeltaY = currentY - this.initialDragY;
|
|
16914
|
+
const totalDistance = Math.sqrt(totalDeltaX * totalDeltaX + totalDeltaY * totalDeltaY);
|
|
16915
|
+
if (totalDistance < ANCHOR_DISCONNECT_THRESHOLD) {
|
|
16916
|
+
return;
|
|
16917
|
+
}
|
|
16918
|
+
const selectionGroup = this._core.store.selectionGroup;
|
|
16919
|
+
if (!selectionGroup) {
|
|
16920
|
+
return;
|
|
16921
|
+
}
|
|
16922
|
+
// Find and disconnect anchors from all anchored lines in the selection
|
|
16923
|
+
for (const obj of selectionGroup.objects) {
|
|
16924
|
+
// Skip if already disconnected in this drag session
|
|
16925
|
+
if (this.disconnectedLineIds.has(obj.id)) {
|
|
16926
|
+
continue;
|
|
16927
|
+
}
|
|
16928
|
+
// Check if this is a line with anchors
|
|
16929
|
+
if (obj instanceof KritzelLine) {
|
|
16930
|
+
const line = obj;
|
|
16931
|
+
const hasAnchors = line.startAnchor || line.endAnchor;
|
|
16932
|
+
if (hasAnchors) {
|
|
16933
|
+
// Disconnect both anchors
|
|
16934
|
+
if (line.startAnchor) {
|
|
16935
|
+
this._core.anchorManager.removeAnchor(line.id, 'start');
|
|
16936
|
+
}
|
|
16937
|
+
if (line.endAnchor) {
|
|
16938
|
+
this._core.anchorManager.removeAnchor(line.id, 'end');
|
|
16939
|
+
}
|
|
16940
|
+
// Mark as disconnected so we don't try again
|
|
16941
|
+
this.disconnectedLineIds.add(line.id);
|
|
16942
|
+
// Update the line to persist the change
|
|
16943
|
+
this._core.store.state.objects.update(line);
|
|
16944
|
+
}
|
|
16945
|
+
}
|
|
16946
|
+
}
|
|
16947
|
+
}
|
|
16463
16948
|
}
|
|
16464
16949
|
|
|
16465
16950
|
var KritzelHandleType;
|
|
@@ -16691,6 +17176,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
|
|
|
16691
17176
|
if (KritzelEventHelper.isLeftClick(event)) {
|
|
16692
17177
|
const selectionGroup = this._core.store.selectionGroup;
|
|
16693
17178
|
if (selectionGroup && this._core.store.state.isRotationHandleSelected) {
|
|
17179
|
+
selectionGroup.beginTransform();
|
|
16694
17180
|
const clientX = event.clientX - this._core.store.offsetX;
|
|
16695
17181
|
const clientY = event.clientY - this._core.store.offsetY;
|
|
16696
17182
|
this._core.store.state.isRotating = true;
|
|
@@ -16714,6 +17200,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
|
|
|
16714
17200
|
if (activePointers.length === 1) {
|
|
16715
17201
|
const selectionGroup = this._core.store.selectionGroup;
|
|
16716
17202
|
if (selectionGroup && this._core.store.state.isRotationHandleSelected) {
|
|
17203
|
+
selectionGroup.beginTransform();
|
|
16717
17204
|
const clientX = Math.round(firstTouch.clientX - this._core.store.offsetX);
|
|
16718
17205
|
const clientY = Math.round(firstTouch.clientY - this._core.store.offsetY);
|
|
16719
17206
|
this._core.store.state.isRotating = true;
|
|
@@ -17024,11 +17511,14 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
|
|
|
17024
17511
|
if (!object) {
|
|
17025
17512
|
return;
|
|
17026
17513
|
}
|
|
17027
|
-
|
|
17514
|
+
// Resolve child objects to their parent groups
|
|
17515
|
+
const parentGroup = KritzelGroup.findParentGroup(this._core, object.id);
|
|
17516
|
+
const objectToSelect = parentGroup || object;
|
|
17517
|
+
objectToSelect.isSelected = false;
|
|
17028
17518
|
const selectionGroup = KritzelSelectionGroup.create(this._core);
|
|
17029
|
-
selectionGroup.addOrRemove(
|
|
17519
|
+
selectionGroup.addOrRemove(objectToSelect);
|
|
17030
17520
|
selectionGroup.isSelected = true;
|
|
17031
|
-
selectionGroup.rotation =
|
|
17521
|
+
selectionGroup.rotation = objectToSelect.rotation;
|
|
17032
17522
|
this._core.addSelectionGroup(selectionGroup);
|
|
17033
17523
|
this._core.rerender();
|
|
17034
17524
|
}
|
|
@@ -17037,10 +17527,24 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
|
|
|
17037
17527
|
if (selectedObjects.length === 0) {
|
|
17038
17528
|
return;
|
|
17039
17529
|
}
|
|
17530
|
+
// Resolve child objects to their parent groups to avoid double-move
|
|
17531
|
+
const resolvedObjects = new Map();
|
|
17532
|
+
selectedObjects.forEach(obj => {
|
|
17533
|
+
// Check if this object is a child of a KritzelGroup
|
|
17534
|
+
const parentGroup = KritzelGroup.findParentGroup(this._core, obj.id);
|
|
17535
|
+
if (parentGroup) {
|
|
17536
|
+
// Add the parent group instead of the child
|
|
17537
|
+
resolvedObjects.set(parentGroup.id, parentGroup);
|
|
17538
|
+
}
|
|
17539
|
+
else {
|
|
17540
|
+
// Not a child of any group, add the object itself
|
|
17541
|
+
resolvedObjects.set(obj.id, obj);
|
|
17542
|
+
}
|
|
17543
|
+
obj.isSelected = false;
|
|
17544
|
+
});
|
|
17040
17545
|
const selectionGroup = KritzelSelectionGroup.create(this._core);
|
|
17041
|
-
|
|
17546
|
+
resolvedObjects.forEach(o => {
|
|
17042
17547
|
selectionGroup.addOrRemove(o);
|
|
17043
|
-
o.isSelected = false;
|
|
17044
17548
|
});
|
|
17045
17549
|
selectionGroup.isSelected = true;
|
|
17046
17550
|
if (selectionGroup.length === 1) {
|
|
@@ -33885,6 +34389,7 @@ exports.KritzelDevicesHelper = KritzelDevicesHelper;
|
|
|
33885
34389
|
exports.KritzelEraserTool = KritzelEraserTool;
|
|
33886
34390
|
exports.KritzelEventHelper = KritzelEventHelper;
|
|
33887
34391
|
exports.KritzelGeometryHelper = KritzelGeometryHelper;
|
|
34392
|
+
exports.KritzelGroup = KritzelGroup;
|
|
33888
34393
|
exports.KritzelIconRegistry = KritzelIconRegistry;
|
|
33889
34394
|
exports.KritzelImage = KritzelImage;
|
|
33890
34395
|
exports.KritzelImageTool = KritzelImageTool;
|
|
@@ -33937,6 +34442,6 @@ exports.varStorage = varStorage;
|
|
|
33937
34442
|
exports.writeVarString = writeVarString$2;
|
|
33938
34443
|
exports.writeVarUint = writeVarUint$2;
|
|
33939
34444
|
exports.writeVarUint8Array = writeVarUint8Array$2;
|
|
33940
|
-
//# sourceMappingURL=default-line-tool.config-
|
|
34445
|
+
//# sourceMappingURL=default-line-tool.config-JuTDR6PF.js.map
|
|
33941
34446
|
|
|
33942
|
-
//# sourceMappingURL=default-line-tool.config-
|
|
34447
|
+
//# sourceMappingURL=default-line-tool.config-JuTDR6PF.js.map
|