kritzel-stencil 0.2.0 → 0.2.2
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/index.cjs.js +1 -1
- package/dist/cjs/kritzel-active-users_42.cjs.entry.js +177 -52
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/stencil.cjs.js +1 -1
- package/dist/cjs/{workspace.migrations-CPncKohl.js → workspace.migrations-BPwtowiJ.js} +208 -24
- package/dist/collection/classes/core/core.class.js +27 -19
- package/dist/collection/classes/core/viewport.class.js +3 -0
- package/dist/collection/classes/handlers/key.handler.js +73 -6
- package/dist/collection/classes/handlers/selection.handler.js +36 -2
- package/dist/collection/classes/objects/group.class.js +69 -12
- package/dist/collection/classes/objects/shape.class.js +24 -0
- package/dist/collection/classes/objects/text.class.js +23 -0
- package/dist/collection/classes/tools/text-tool.class.js +46 -10
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +28 -7
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +64 -18
- package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +23 -1
- package/dist/collection/constants/version.js +1 -1
- package/dist/collection/themes/dark-theme.js +5 -0
- package/dist/collection/themes/light-theme.js +5 -0
- package/dist/components/index.js +1 -1
- package/dist/components/kritzel-awareness-cursors.js +1 -1
- package/dist/components/kritzel-color-palette.js +1 -1
- package/dist/components/kritzel-color.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-editor.js +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-menu-item.js +1 -1
- package/dist/components/kritzel-menu.js +1 -1
- package/dist/components/kritzel-more-menu.js +1 -1
- package/dist/components/kritzel-portal.js +1 -1
- package/dist/components/kritzel-settings.js +1 -1
- package/dist/components/kritzel-split-button.js +1 -1
- package/dist/components/kritzel-stroke-size.js +1 -1
- package/dist/components/kritzel-tool-config.js +1 -1
- package/dist/components/kritzel-workspace-manager.js +1 -1
- package/dist/components/{p-CFzvz-B2.js → p-0YBCp8Wh.js} +1 -1
- package/dist/components/{p-DkT0CXfN.js → p-574MVXxi.js} +1 -1
- package/dist/components/p-BCzbwL4m.js +1 -0
- package/dist/components/p-BLjdzUzs.js +1 -0
- package/dist/components/{p-BFQVg_eQ.js → p-BSEdLfq2.js} +1 -1
- package/dist/components/{p-C3Dwuqka.js → p-BWrxz4mM.js} +1 -1
- package/dist/components/{p-ChqeIKg_.js → p-BYOIzv_f.js} +1 -1
- package/dist/components/{p-CekG3_ce.js → p-Bfa-Amjn.js} +1 -1
- package/dist/components/{p-9ASFIqd0.js → p-BmcAX-1k.js} +1 -1
- package/dist/components/{p-CzIuqMQA.js → p-BtJB7FsW.js} +1 -1
- package/dist/components/{p-C_yfHS4F.js → p-C6Td7I4k.js} +1 -1
- package/dist/components/{p-ChQNi67Z.js → p-D9ifYAtg.js} +1 -1
- package/dist/components/{p-B_rHzy0t.js → p-DE2xDwUM.js} +1 -1
- package/dist/components/{p-CaDBSaxZ.js → p-DFeyobdy.js} +2 -2
- package/dist/components/{p-BHSRRiEg.js → p-DfB7uJ0N.js} +1 -1
- package/dist/components/{p-B2kHVHa_.js → p-u-827ZX7.js} +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/kritzel-active-users_42.entry.js +177 -52
- package/dist/esm/loader.js +1 -1
- package/dist/esm/stencil.js +1 -1
- package/dist/esm/{workspace.migrations-ytjzXm9B.js → workspace.migrations-C_uxbvuH.js} +208 -24
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-4d28c496.entry.js +9 -0
- package/dist/stencil/p-C_uxbvuH.js +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/handlers/selection.handler.d.ts +15 -0
- package/dist/types/classes/objects/group.class.d.ts +15 -0
- package/dist/types/classes/objects/shape.class.d.ts +10 -0
- package/dist/types/classes/objects/text.class.d.ts +9 -0
- package/dist/types/classes/tools/text-tool.class.d.ts +26 -8
- package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +1 -0
- package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -0
- package/dist/types/components/shared/kritzel-portal/kritzel-portal.d.ts +1 -0
- package/dist/types/components.d.ts +7 -2
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/interfaces/theme.interface.d.ts +12 -4
- package/package.json +1 -1
- package/dist/components/p-BYX50YSd.js +0 -1
- package/dist/components/p-CjazGGq3.js +0 -1
- package/dist/stencil/p-19e04f32.entry.js +0 -9
- package/dist/stencil/p-ytjzXm9B.js +0 -1
|
@@ -111,6 +111,23 @@ export class KritzelGroup extends KritzelBaseObject {
|
|
|
111
111
|
}
|
|
112
112
|
return null;
|
|
113
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Recursively collects the IDs of all descendants of the given group (children,
|
|
116
|
+
* grandchildren, etc.). Useful for detecting when a selection contains both an
|
|
117
|
+
* ancestor group and one of its descendants — a configuration that would otherwise
|
|
118
|
+
* cause the descendant to be transformed twice (once via the ancestor, once directly).
|
|
119
|
+
* @param group - The group whose descendants should be collected.
|
|
120
|
+
* @param out - A set that will be populated with all descendant object IDs.
|
|
121
|
+
*/
|
|
122
|
+
static collectDescendantIds(group, out = new Set()) {
|
|
123
|
+
for (const child of group.children) {
|
|
124
|
+
out.add(child.id);
|
|
125
|
+
if (child instanceof KritzelGroup) {
|
|
126
|
+
KritzelGroup.collectDescendantIds(child, out);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
114
131
|
/**
|
|
115
132
|
* Adds a child object to this group.
|
|
116
133
|
* If the object is already a child, no action is taken.
|
|
@@ -154,8 +171,19 @@ export class KritzelGroup extends KritzelBaseObject {
|
|
|
154
171
|
* Finalizes the group after children have been positioned (e.g., after paste).
|
|
155
172
|
* Refreshes the bounding box to encompass all children and captures
|
|
156
173
|
* child snapshots for subsequent transformation operations.
|
|
174
|
+
*
|
|
175
|
+
* Recursively finalizes nested child groups first, so that when a transform
|
|
176
|
+
* (rotate/resize) cascades through nested groups, every group's snapshots are
|
|
177
|
+
* aligned with the current visual state. Without this, a nested group's
|
|
178
|
+
* `snapshotRotation` could be stale, causing the inner group to be offset
|
|
179
|
+
* relative to its parent during rotation.
|
|
157
180
|
*/
|
|
158
181
|
finalize() {
|
|
182
|
+
for (const child of this.children) {
|
|
183
|
+
if (child instanceof KritzelGroup) {
|
|
184
|
+
child.finalize();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
159
187
|
this.refreshBoundingBox();
|
|
160
188
|
this.captureChildSnapshots();
|
|
161
189
|
}
|
|
@@ -312,11 +340,23 @@ export class KritzelGroup extends KritzelBaseObject {
|
|
|
312
340
|
* @param height - The new height of the group's content area.
|
|
313
341
|
*/
|
|
314
342
|
resize(x, y, width, height) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
//
|
|
318
|
-
const
|
|
319
|
-
|
|
343
|
+
// Use snapshot dimensions (stable across the gesture) instead of `this.*`,
|
|
344
|
+
// which mutates each frame and gets distorted by descendants like KritzelText
|
|
345
|
+
// that clamp to a uniform scale, causing the cascade factor to drift.
|
|
346
|
+
const baseWidth = this.snapshotTotalWidth > 0
|
|
347
|
+
? this.snapshotTotalWidth - this.padding * 2
|
|
348
|
+
: this.width;
|
|
349
|
+
const baseHeight = this.snapshotTotalHeight > 0
|
|
350
|
+
? this.snapshotTotalHeight - this.padding * 2
|
|
351
|
+
: this.height;
|
|
352
|
+
const baseScale = this.snapshotScale || this.scale || 1;
|
|
353
|
+
const widthScaleFactor = baseWidth !== 0 ? width / baseWidth : 1;
|
|
354
|
+
const heightScaleFactor = baseHeight !== 0 ? height / baseHeight : 1;
|
|
355
|
+
// Calculate old center from snapshot (stable across the gesture)
|
|
356
|
+
const snapshotTotalWidth = this.snapshotTotalWidth || (this.width + this.padding * 2);
|
|
357
|
+
const snapshotTotalHeight = this.snapshotTotalHeight || (this.height + this.padding * 2);
|
|
358
|
+
const oldCenterX = this.snapshotTranslateX + snapshotTotalWidth / 2 / baseScale;
|
|
359
|
+
const oldCenterY = this.snapshotTranslateY + snapshotTotalHeight / 2 / baseScale;
|
|
320
360
|
// Calculate new center
|
|
321
361
|
const newTotalWidth = width + this.padding * 2;
|
|
322
362
|
const newTotalHeight = height + this.padding * 2;
|
|
@@ -329,9 +369,20 @@ export class KritzelGroup extends KritzelBaseObject {
|
|
|
329
369
|
const sinR = Math.sin(rotation);
|
|
330
370
|
this._core.store.objects.transaction(() => {
|
|
331
371
|
this.children.forEach(child => {
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
const
|
|
372
|
+
// Use snapshot values for the child to avoid compounding distortions caused
|
|
373
|
+
// by descendants like text that cannot honour requested aspect ratios.
|
|
374
|
+
const snapshot = this.unchangedChildSnapshots.get(child.id);
|
|
375
|
+
const childTranslateX = snapshot ? snapshot.translateX : child.translateX;
|
|
376
|
+
const childTranslateY = snapshot ? snapshot.translateY : child.translateY;
|
|
377
|
+
const childTotalWidth = snapshot ? snapshot.totalWidth : child.totalWidth;
|
|
378
|
+
const childTotalHeight = snapshot ? snapshot.totalHeight : child.totalHeight;
|
|
379
|
+
const childWidth = snapshot ? snapshot.width : child.width;
|
|
380
|
+
const childHeight = snapshot ? snapshot.height : child.height;
|
|
381
|
+
const childRotation = snapshot ? snapshot.rotation : child.rotation;
|
|
382
|
+
const childScale = (snapshot ? snapshot.scale : child.scale) || 1;
|
|
383
|
+
// Calculate child center from snapshot
|
|
384
|
+
const childCenterX = childTranslateX + childTotalWidth / 2 / childScale;
|
|
385
|
+
const childCenterY = childTranslateY + childTotalHeight / 2 / childScale;
|
|
335
386
|
// Vector from old group center to child center
|
|
336
387
|
const dx = childCenterX - oldCenterX;
|
|
337
388
|
const dy = childCenterY - oldCenterY;
|
|
@@ -348,13 +399,13 @@ export class KritzelGroup extends KritzelBaseObject {
|
|
|
348
399
|
const newChildCenterX = newCenterX + rotatedX;
|
|
349
400
|
const newChildCenterY = newCenterY + rotatedY;
|
|
350
401
|
// Calculate relative rotation for scaling
|
|
351
|
-
const relativeRotation =
|
|
402
|
+
const relativeRotation = childRotation - rotation;
|
|
352
403
|
const cosRel = Math.cos(relativeRotation);
|
|
353
404
|
const sinRel = Math.sin(relativeRotation);
|
|
354
405
|
const newChildWidthScale = Math.sqrt(Math.pow(widthScaleFactor * cosRel, 2) + Math.pow(heightScaleFactor * sinRel, 2));
|
|
355
406
|
const newChildHeightScale = Math.sqrt(Math.pow(widthScaleFactor * sinRel, 2) + Math.pow(heightScaleFactor * cosRel, 2));
|
|
356
|
-
const updatedWidth =
|
|
357
|
-
const updatedHeight =
|
|
407
|
+
const updatedWidth = childWidth * newChildWidthScale;
|
|
408
|
+
const updatedHeight = childHeight * newChildHeightScale;
|
|
358
409
|
const updatedTotalWidth = updatedWidth + child.padding * 2;
|
|
359
410
|
const updatedTotalHeight = updatedHeight + child.padding * 2;
|
|
360
411
|
const updatedX = newChildCenterX - updatedTotalWidth / 2 / child.scale;
|
|
@@ -364,7 +415,13 @@ export class KritzelGroup extends KritzelBaseObject {
|
|
|
364
415
|
this._core.anchorManager.updateAnchorsForObject(child.id);
|
|
365
416
|
});
|
|
366
417
|
this.refreshBoundingBox();
|
|
367
|
-
|
|
418
|
+
// Don't recapture snapshots while an interactive resize is in progress —
|
|
419
|
+
// recapturing each frame would defeat the purpose of using stable snapshots
|
|
420
|
+
// and re-introduce the compounding distortion described above. Snapshots are
|
|
421
|
+
// refreshed at the start of the next gesture via beginTransform/finalize.
|
|
422
|
+
if (!this._core.store.state.isResizing) {
|
|
423
|
+
this.captureChildSnapshots();
|
|
424
|
+
}
|
|
368
425
|
this._core.store.objects.update(this);
|
|
369
426
|
});
|
|
370
427
|
}
|
|
@@ -341,6 +341,30 @@ export class KritzelShape extends KritzelBaseObject {
|
|
|
341
341
|
this._core.store.objects.update(this);
|
|
342
342
|
this._core.engine.emitObjectsChange();
|
|
343
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Handles the Escape key while the shape's text editor is in edit mode.
|
|
346
|
+
* Implements a two-stage behavior: if the editor currently has a non-empty
|
|
347
|
+
* text selection, the selection is collapsed to a caret without exiting
|
|
348
|
+
* edit mode. If the selection is already collapsed, edit mode is exited
|
|
349
|
+
* (saving the current content), the canvas selection is cleared and the
|
|
350
|
+
* active tool is switched back to the selection tool so subsequent
|
|
351
|
+
* interactions start fresh.
|
|
352
|
+
*/
|
|
353
|
+
handleEscape() {
|
|
354
|
+
if (!this.editor || !this.isEditing) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const { state } = this.editor;
|
|
358
|
+
if (!state.selection.empty) {
|
|
359
|
+
const pos = state.selection.head;
|
|
360
|
+
this.editor.dispatch(state.tr.setSelection(TextSelection.create(state.doc, pos)));
|
|
361
|
+
this.editor.focus();
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
this._core.resetActiveShape();
|
|
365
|
+
this._core.clearSelection();
|
|
366
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
367
|
+
}
|
|
344
368
|
/**
|
|
345
369
|
* Handles pointer down events when the shape is in edit mode.
|
|
346
370
|
* This method stops event propagation for untracked pointers to prevent
|
|
@@ -332,6 +332,29 @@ export class KritzelText extends KritzelBaseObject {
|
|
|
332
332
|
this._core.store.objects.update(this);
|
|
333
333
|
this._core.engine.emitObjectsChange();
|
|
334
334
|
}
|
|
335
|
+
/**
|
|
336
|
+
* Handles the Escape key while the text object is in edit mode.
|
|
337
|
+
* Implements a two-stage behavior: if the editor currently has a non-empty
|
|
338
|
+
* text selection, the selection is collapsed to a caret without exiting
|
|
339
|
+
* edit mode. If the selection is already collapsed, edit mode is exited
|
|
340
|
+
* (saving the current content or deleting the object if it is empty) and
|
|
341
|
+
* the canvas selection is cleared so subsequent tool actions start fresh.
|
|
342
|
+
*/
|
|
343
|
+
handleEscape() {
|
|
344
|
+
if (!this.editor || !this.isEditing) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
const { state } = this.editor;
|
|
348
|
+
if (!state.selection.empty) {
|
|
349
|
+
const pos = state.selection.head;
|
|
350
|
+
this.editor.dispatch(state.tr.setSelection(TextSelection.create(state.doc, pos)));
|
|
351
|
+
this.editor.focus();
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
this._core.resetActiveText();
|
|
355
|
+
this._core.clearSelection();
|
|
356
|
+
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
357
|
+
}
|
|
335
358
|
/**
|
|
336
359
|
* Handles pointer down events during text editing.
|
|
337
360
|
* Stops event propagation to prevent canvas interaction while editing.
|
|
@@ -10,14 +10,38 @@ import { DEFAULT_COLOR_PALETTE } from "../../constants/color-palette.constants";
|
|
|
10
10
|
* Supports configurable font family, size, color, and opacity.
|
|
11
11
|
*/
|
|
12
12
|
export class KritzelTextTool extends KritzelBaseTool {
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
|
|
13
|
+
/** Backing field for {@link fontFamily}. */
|
|
14
|
+
_fontFamily = 'Arial';
|
|
15
|
+
/** Backing field for {@link fontSize}. */
|
|
16
|
+
_fontSize = 16;
|
|
17
|
+
/** Backing field for {@link fontColor}. */
|
|
18
|
+
_fontColor = DEFAULT_COLOR_PALETTE[0];
|
|
19
|
+
/** Backing field for {@link opacity}. */
|
|
20
|
+
_opacity = 1;
|
|
21
|
+
/** The font family for new text objects. */
|
|
22
|
+
get fontFamily() { return this._fontFamily; }
|
|
23
|
+
set fontFamily(value) {
|
|
24
|
+
this._fontFamily = value;
|
|
25
|
+
this.applyToActiveText({ fontFamily: value });
|
|
26
|
+
}
|
|
27
|
+
/** The font size for new text objects in pixels. */
|
|
28
|
+
get fontSize() { return this._fontSize; }
|
|
29
|
+
set fontSize(value) {
|
|
30
|
+
this._fontSize = value;
|
|
31
|
+
this.applyToActiveText({ fontSize: value });
|
|
32
|
+
}
|
|
33
|
+
/** The font color for new text objects (supports theme-aware light/dark colors). */
|
|
34
|
+
get fontColor() { return this._fontColor; }
|
|
35
|
+
set fontColor(value) {
|
|
36
|
+
this._fontColor = value;
|
|
37
|
+
this.applyToActiveText({ fontColor: value });
|
|
38
|
+
}
|
|
39
|
+
/** The opacity of new text objects (0-1). */
|
|
40
|
+
get opacity() { return this._opacity; }
|
|
41
|
+
set opacity(value) {
|
|
42
|
+
this._opacity = value;
|
|
43
|
+
this.applyToActiveText({ opacity: value });
|
|
44
|
+
}
|
|
21
45
|
/** Available color palette for the text tool */
|
|
22
46
|
palette = [...DEFAULT_COLOR_PALETTE];
|
|
23
47
|
/**
|
|
@@ -27,6 +51,18 @@ export class KritzelTextTool extends KritzelBaseTool {
|
|
|
27
51
|
constructor(core) {
|
|
28
52
|
super(core);
|
|
29
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Propagates a property change to the text object that is currently being edited, if any.
|
|
56
|
+
* Mirrors the selection tool pattern of pushing tool-config changes down to live objects,
|
|
57
|
+
* but scoped to the single text in edit mode rather than the current selection.
|
|
58
|
+
*/
|
|
59
|
+
applyToActiveText(updatedProperties) {
|
|
60
|
+
const activeText = this._core?.store?.activeText;
|
|
61
|
+
if (!activeText)
|
|
62
|
+
return;
|
|
63
|
+
this._core.updateObject(activeText, updatedProperties);
|
|
64
|
+
this._core.rerender();
|
|
65
|
+
}
|
|
30
66
|
/**
|
|
31
67
|
* Handles pointer down events for text creation and editing.
|
|
32
68
|
* If clicking on an existing text object, enters edit mode for that object.
|
|
@@ -42,7 +78,7 @@ export class KritzelTextTool extends KritzelBaseTool {
|
|
|
42
78
|
if (event.pointerType === 'mouse') {
|
|
43
79
|
const path = event.composedPath().slice(1);
|
|
44
80
|
const objectElement = path.find(element => element.classList && element.classList.contains('object'));
|
|
45
|
-
const object = this._core.findObjectById(objectElement
|
|
81
|
+
const object = objectElement?.id ? this._core.findObjectById(objectElement.id) : null;
|
|
46
82
|
const activeText = this._core.store.activeText;
|
|
47
83
|
if (activeText === null && object instanceof KritzelText) {
|
|
48
84
|
object.edit(event);
|
|
@@ -79,7 +115,7 @@ export class KritzelTextTool extends KritzelBaseTool {
|
|
|
79
115
|
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
80
116
|
const path = event.composedPath().slice(1);
|
|
81
117
|
const objectElement = path.find(element => element.classList && element.classList.contains('object'));
|
|
82
|
-
const object = this._core.findObjectById(objectElement
|
|
118
|
+
const object = objectElement?.id ? this._core.findObjectById(objectElement.id) : null;
|
|
83
119
|
const activeText = this._core.store.activeText;
|
|
84
120
|
if (activeText === null && object instanceof KritzelText) {
|
|
85
121
|
object.edit(event);
|
|
@@ -112,6 +112,7 @@ export class KritzelEditor {
|
|
|
112
112
|
];
|
|
113
113
|
objectContextMenuItems = [
|
|
114
114
|
{ label: 'Copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },
|
|
115
|
+
{ label: 'Cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },
|
|
115
116
|
{
|
|
116
117
|
label: 'Paste',
|
|
117
118
|
icon: 'paste',
|
|
@@ -372,6 +373,9 @@ export class KritzelEditor {
|
|
|
372
373
|
async copy() {
|
|
373
374
|
return this.engineRef.copy();
|
|
374
375
|
}
|
|
376
|
+
async cut() {
|
|
377
|
+
return this.engineRef.cut();
|
|
378
|
+
}
|
|
375
379
|
async paste(x, y) {
|
|
376
380
|
return this.engineRef.paste(x, y);
|
|
377
381
|
}
|
|
@@ -719,27 +723,27 @@ export class KritzelEditor {
|
|
|
719
723
|
const isLoggedIn = this.isLoggedIn;
|
|
720
724
|
const shouldShowCurrentUser = isLoggedIn;
|
|
721
725
|
const shouldShowLoginButton = !!this.loginConfig && !isLoggedIn;
|
|
722
|
-
return (h(Host, { key: '
|
|
726
|
+
return (h(Host, { key: '6e832b0036dbc0d36aa70b297cf73cceafbaa846' }, h("div", { key: '48e99e354326781792798fdcc2b07a1b5bbc8cca', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '980bf87558891a8b20030be4b6d0c32ee568ca4d', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: '59636e148d71c54e51f17095dfec2754d63f1692', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: '11f17eef609d3d3ece1ead3cf51524e690f4a2eb', ref: el => {
|
|
723
727
|
if (el) {
|
|
724
728
|
this.engineRef = el;
|
|
725
729
|
}
|
|
726
|
-
}, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: '
|
|
730
|
+
}, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: 'b9852a78ed062ca7026b8d0da44263fb0a64d8cc', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => {
|
|
727
731
|
if (el) {
|
|
728
732
|
this.controlsRef = el;
|
|
729
733
|
}
|
|
730
|
-
}, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '
|
|
734
|
+
}, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'f3e33d794033eb5fdbde8c4553c744da61eefc51', class: "top-right-buttons" }, h("kritzel-settings", { key: '466ac8a5d110feb46472c3207f4a73e9ce37e148', ref: el => {
|
|
731
735
|
if (el) {
|
|
732
736
|
this.settingsRef = el;
|
|
733
737
|
}
|
|
734
|
-
}, shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '
|
|
738
|
+
}, shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'c6e0eca3baca940f9160ca02989d5c27410ccc59', ref: el => {
|
|
735
739
|
if (el) {
|
|
736
740
|
this.exportRef = el;
|
|
737
741
|
}
|
|
738
|
-
}, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '
|
|
742
|
+
}, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: 'b66a7736b9ac0942873e5bdc1677228cd53d57d6', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '4ab0b49bd43f428fb1ade5d5d9836d846355d92f', user: this.user }), shouldShowLoginButton && h("kritzel-button", { key: '04d6d43b60ad1bd3272dfb1e09aa3efb9602c42e', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in"), h("kritzel-more-menu", { key: '7ca482736a2253d95dffc369de1db1d14d207c35', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), h("kritzel-share-dialog", { key: 'c5ae3f2e981d980fd35380424036acdc29b0fe53', ref: el => {
|
|
739
743
|
if (el) {
|
|
740
744
|
this.shareDialogRef = el;
|
|
741
745
|
}
|
|
742
|
-
}, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '
|
|
746
|
+
}, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'f72b412715d0ffd9a8038ade192d894623fc98fc', ref: el => {
|
|
743
747
|
if (el) {
|
|
744
748
|
this.loginDialogRef = el;
|
|
745
749
|
}
|
|
@@ -1064,7 +1068,7 @@ export class KritzelEditor {
|
|
|
1064
1068
|
},
|
|
1065
1069
|
"getter": false,
|
|
1066
1070
|
"setter": false,
|
|
1067
|
-
"defaultValue": "[\n { label: 'Copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },\n {\n label: 'Paste',\n icon: 'paste',\n group: 'clipboard',\n disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,\n action: (menu, _) => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'Order',\n icon: 'ordering',\n group: 'other',\n children: [\n { label: 'Bring to Front', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },\n { label: 'Send to Back', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },\n { label: 'Move Up', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },\n { label: 'Move Down', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },\n ],\n },\n {\n label: 'Align',\n icon: 'align',\n group: 'other',\n disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n children: [\n { label: 'Align Left', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },\n { label: 'Align Center Horizontally', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },\n { label: 'Align Right', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },\n { label: 'Align Top', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },\n { label: 'Align Center Vertically', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },\n { label: 'Align Bottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },\n ],\n },\n {\n label: 'Group',\n icon: 'group',\n group: 'other',\n children: [\n {\n label: 'Group',\n icon: 'group',\n disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n action: () => this.engineRef.group(),\n },\n {\n label: 'Ungroup',\n icon: 'ungroup',\n disabled: async () => {\n const selectedObjects = await this.engineRef.getSelectedObjects();\n return !selectedObjects.some(obj => obj.__class__ === 'KritzelGroup');\n },\n action: () => this.engineRef.ungroup(),\n },\n ],\n },\n {\n label: 'Export',\n icon: 'download',\n group: 'export',\n children: [\n { label: 'Export as SVG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },\n { label: 'Export as PNG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },\n ],\n },\n { label: 'Delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },\n ]"
|
|
1071
|
+
"defaultValue": "[\n { label: 'Copy', icon: 'copy', group: 'clipboard', action: () => this.engineRef.copy() },\n { label: 'Cut', icon: 'cut', group: 'clipboard', action: () => this.engineRef.cut() },\n {\n label: 'Paste',\n icon: 'paste',\n group: 'clipboard',\n disabled: async () => (await this.engineRef.getCopiedObjects()).length === 0,\n action: (menu, _) => this.engineRef.paste(menu.x, menu.y),\n },\n {\n label: 'Order',\n icon: 'ordering',\n group: 'other',\n children: [\n { label: 'Bring to Front', icon: 'bring-to-front', action: () => this.engineRef.bringToFront() },\n { label: 'Send to Back', icon: 'send-to-back', action: () => this.engineRef.sendToBack() },\n { label: 'Move Up', icon: 'arrow-up-from-dot', action: () => this.engineRef.bringForward() },\n { label: 'Move Down', icon: 'arrow-down-from-dot', action: () => this.engineRef.sendBackward() },\n ],\n },\n {\n label: 'Align',\n icon: 'align',\n group: 'other',\n disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n children: [\n { label: 'Align Left', icon: 'align-start-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.StartHorizontal) },\n { label: 'Align Center Horizontally', icon: 'align-center-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterHorizontal) },\n { label: 'Align Right', icon: 'align-end-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.EndHorizontal) },\n { label: 'Align Top', icon: 'align-start-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.StartVertical) },\n { label: 'Align Center Vertically', icon: 'align-center-vertical', action: () => this.engineRef.alignObjects(KritzelAlignment.CenterVertical) },\n { label: 'Align Bottom', icon: 'align-end-horizontal', action: () => this.engineRef.alignObjects(KritzelAlignment.EndVertical) },\n ],\n },\n {\n label: 'Group',\n icon: 'group',\n group: 'other',\n children: [\n {\n label: 'Group',\n icon: 'group',\n disabled: async () => (await this.engineRef.getSelectedObjects()).length < 2,\n action: () => this.engineRef.group(),\n },\n {\n label: 'Ungroup',\n icon: 'ungroup',\n disabled: async () => {\n const selectedObjects = await this.engineRef.getSelectedObjects();\n return !selectedObjects.some(obj => obj.__class__ === 'KritzelGroup');\n },\n action: () => this.engineRef.ungroup(),\n },\n ],\n },\n {\n label: 'Export',\n icon: 'download',\n group: 'export',\n children: [\n { label: 'Export as SVG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsSvg() },\n { label: 'Export as PNG', icon: 'download', action: () => this.engineRef.exportSelectedObjectsAsPng() },\n ],\n },\n { label: 'Delete', icon: 'delete', group: 'edit', action: () => this.engineRef.delete() },\n ]"
|
|
1068
1072
|
},
|
|
1069
1073
|
"customSvgIcons": {
|
|
1070
1074
|
"type": "unknown",
|
|
@@ -2382,6 +2386,23 @@ export class KritzelEditor {
|
|
|
2382
2386
|
"tags": []
|
|
2383
2387
|
}
|
|
2384
2388
|
},
|
|
2389
|
+
"cut": {
|
|
2390
|
+
"complexType": {
|
|
2391
|
+
"signature": "() => Promise<void>",
|
|
2392
|
+
"parameters": [],
|
|
2393
|
+
"references": {
|
|
2394
|
+
"Promise": {
|
|
2395
|
+
"location": "global",
|
|
2396
|
+
"id": "global::Promise"
|
|
2397
|
+
}
|
|
2398
|
+
},
|
|
2399
|
+
"return": "Promise<void>"
|
|
2400
|
+
},
|
|
2401
|
+
"docs": {
|
|
2402
|
+
"text": "",
|
|
2403
|
+
"tags": []
|
|
2404
|
+
}
|
|
2405
|
+
},
|
|
2385
2406
|
"paste": {
|
|
2386
2407
|
"complexType": {
|
|
2387
2408
|
"signature": "(x: number, y: number) => Promise<void>",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
2
|
import { KritzelViewport } from "../../../classes/core/viewport.class";
|
|
3
3
|
import { KritzelSelectionTool } from "../../../classes/tools/selection-tool.class";
|
|
4
|
+
import { KritzelTextTool } from "../../../classes/tools/text-tool.class";
|
|
5
|
+
import { KritzelShapeTool } from "../../../classes/tools/shape-tool.class";
|
|
4
6
|
import { KritzelSelectionBox } from "../../../classes/objects/selection-box.class";
|
|
5
7
|
import { KritzelKeyHandler } from "../../../classes/handlers/key.handler";
|
|
6
8
|
import { KritzelBaseTool } from "../../../classes/tools/base-tool.class";
|
|
@@ -396,6 +398,10 @@ export class KritzelEngine {
|
|
|
396
398
|
async copy() {
|
|
397
399
|
this.core.copy();
|
|
398
400
|
}
|
|
401
|
+
/** Cuts the currently selected objects to the internal clipboard (deletes them from the canvas). */
|
|
402
|
+
async cut() {
|
|
403
|
+
this.core.cut();
|
|
404
|
+
}
|
|
399
405
|
/**
|
|
400
406
|
* Pastes previously copied objects at the specified world coordinates.
|
|
401
407
|
* @param x - X position in world coordinates.
|
|
@@ -525,23 +531,39 @@ export class KritzelEngine {
|
|
|
525
531
|
object.setContent(pendingContent);
|
|
526
532
|
}
|
|
527
533
|
}
|
|
528
|
-
// Handle KritzelGroup: flush pending children into the store
|
|
534
|
+
// Handle KritzelGroup: flush pending children (recursively for nested groups) into the store
|
|
529
535
|
if (KritzelClassHelper.isInstanceOf(object, 'KritzelGroup') && object._pendingChildren.length > 0) {
|
|
530
|
-
|
|
531
|
-
//
|
|
536
|
+
// Build a map of old ID → new ID across all nesting levels so we can
|
|
537
|
+
// remap anchor references regardless of how deeply nested the line is.
|
|
532
538
|
const idRemapping = new Map();
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
539
|
+
const allFlushedChildren = [];
|
|
540
|
+
const flushGroup = (group) => {
|
|
541
|
+
if (group._pendingChildren.length === 0) {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
const pending = group._pendingChildren;
|
|
545
|
+
group._pendingChildren = [];
|
|
546
|
+
group.childIds = [];
|
|
547
|
+
pending.forEach(child => {
|
|
548
|
+
const oldId = child.id;
|
|
549
|
+
child.id = child.generateId();
|
|
550
|
+
child._core = this.core;
|
|
551
|
+
child.scale = this.core.store.state.scale;
|
|
552
|
+
child.zIndex = this.core.store.currentZIndex;
|
|
553
|
+
child.workspaceId = this.core.store.state.activeWorkspace.id;
|
|
554
|
+
idRemapping.set(oldId, child.id);
|
|
555
|
+
group.childIds.push(child.id);
|
|
556
|
+
allFlushedChildren.push(child);
|
|
557
|
+
// Recurse into nested groups before inserting so grandchildren get
|
|
558
|
+
// proper IDs and `childIds` references before the parent is added.
|
|
559
|
+
if (KritzelClassHelper.isInstanceOf(child, 'KritzelGroup')) {
|
|
560
|
+
flushGroup(child);
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
};
|
|
564
|
+
flushGroup(object);
|
|
565
|
+
// Remap anchor references in lines across all flushed descendants
|
|
566
|
+
allFlushedChildren.forEach(child => {
|
|
545
567
|
if (KritzelClassHelper.isInstanceOf(child, 'KritzelLine')) {
|
|
546
568
|
if (child.startAnchor && idRemapping.has(child.startAnchor.objectId)) {
|
|
547
569
|
child.startAnchor = { objectId: idRemapping.get(child.startAnchor.objectId) };
|
|
@@ -551,10 +573,11 @@ export class KritzelEngine {
|
|
|
551
573
|
}
|
|
552
574
|
}
|
|
553
575
|
});
|
|
554
|
-
|
|
576
|
+
// Insert all flushed descendants into the store
|
|
577
|
+
allFlushedChildren.forEach(child => {
|
|
555
578
|
this.core.addObject(child);
|
|
556
579
|
});
|
|
557
|
-
|
|
580
|
+
// finalize() recurses into nested groups so all bounding boxes/snapshots align
|
|
558
581
|
object.finalize();
|
|
559
582
|
// Rebuild anchor index so anchored lines are tracked
|
|
560
583
|
this.core.anchorManager.rebuildIndex();
|
|
@@ -1494,6 +1517,12 @@ export class KritzelEngine {
|
|
|
1494
1517
|
this.core.store.state.isResizeHandleSelected = false;
|
|
1495
1518
|
this.core.store.state.isRotationHandleSelected = false;
|
|
1496
1519
|
}
|
|
1520
|
+
if (!(activeTool instanceof KritzelTextTool)) {
|
|
1521
|
+
this.core.resetActiveText();
|
|
1522
|
+
}
|
|
1523
|
+
if (!(activeTool instanceof KritzelShapeTool)) {
|
|
1524
|
+
this.core.resetActiveShape();
|
|
1525
|
+
}
|
|
1497
1526
|
this.core.store.state.skipContextMenu = false;
|
|
1498
1527
|
this.core.store.state.copiedObjects = undefined;
|
|
1499
1528
|
if (activeTool) {
|
|
@@ -1570,7 +1599,7 @@ export class KritzelEngine {
|
|
|
1570
1599
|
overflow: 'visible',
|
|
1571
1600
|
userSelect: 'none',
|
|
1572
1601
|
imageRendering: this.core.store.state.isScaling || this.core.store.state.isPanning ? 'pixelated' : 'auto',
|
|
1573
|
-
}, draggable: false, onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && object.loadState !== 'ready' && (h("div", { ref: () => object.ensureLoaded(), style: {
|
|
1602
|
+
}, draggable: false, decoding: "async", loading: "eager", onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && object.loadState !== 'ready' && (h("div", { ref: () => object.ensureLoaded(), style: {
|
|
1574
1603
|
position: 'absolute',
|
|
1575
1604
|
left: '0',
|
|
1576
1605
|
top: '0',
|
|
@@ -2897,6 +2926,23 @@ export class KritzelEngine {
|
|
|
2897
2926
|
"tags": []
|
|
2898
2927
|
}
|
|
2899
2928
|
},
|
|
2929
|
+
"cut": {
|
|
2930
|
+
"complexType": {
|
|
2931
|
+
"signature": "() => Promise<void>",
|
|
2932
|
+
"parameters": [],
|
|
2933
|
+
"references": {
|
|
2934
|
+
"Promise": {
|
|
2935
|
+
"location": "global",
|
|
2936
|
+
"id": "global::Promise"
|
|
2937
|
+
}
|
|
2938
|
+
},
|
|
2939
|
+
"return": "Promise<void>"
|
|
2940
|
+
},
|
|
2941
|
+
"docs": {
|
|
2942
|
+
"text": "Cuts the currently selected objects to the internal clipboard (deletes them from the canvas).",
|
|
2943
|
+
"tags": []
|
|
2944
|
+
}
|
|
2945
|
+
},
|
|
2900
2946
|
"paste": {
|
|
2901
2947
|
"complexType": {
|
|
2902
2948
|
"signature": "(x: number, y: number) => Promise<void>",
|
|
@@ -40,6 +40,22 @@ export class KritzelPortal {
|
|
|
40
40
|
this.closePortal();
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
handleOutsidePointerDown(event) {
|
|
44
|
+
if (!this.portal)
|
|
45
|
+
return;
|
|
46
|
+
const isLastPortal = this.lastAddedPortal === this.portal;
|
|
47
|
+
if (!isLastPortal)
|
|
48
|
+
return;
|
|
49
|
+
const path = event.composedPath();
|
|
50
|
+
const isInsidePortal = path.some(el => el === this.host);
|
|
51
|
+
const isOnAnchor = this.anchor && path.some(el => el === this.anchor);
|
|
52
|
+
if (!isInsidePortal && !isOnAnchor) {
|
|
53
|
+
event.stopPropagation();
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
this.close.emit();
|
|
56
|
+
this.closePortal();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
43
59
|
handleKeyDown(event) {
|
|
44
60
|
const isLastPortal = this.lastAddedPortal === this.portal;
|
|
45
61
|
if (!isLastPortal)
|
|
@@ -261,7 +277,7 @@ export class KritzelPortal {
|
|
|
261
277
|
this.portal.style.visibility = 'visible';
|
|
262
278
|
}
|
|
263
279
|
render() {
|
|
264
|
-
return (h(Host, { key: '
|
|
280
|
+
return (h(Host, { key: 'dcd8e6f3787c713012aeb6436bf63f2f4930c39e', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '830f51521a77f0a28471026494323e14ab4f9f9a' })));
|
|
265
281
|
}
|
|
266
282
|
static get is() { return "kritzel-portal"; }
|
|
267
283
|
static get encapsulation() { return "shadow"; }
|
|
@@ -387,6 +403,12 @@ export class KritzelPortal {
|
|
|
387
403
|
"target": "window",
|
|
388
404
|
"capture": false,
|
|
389
405
|
"passive": false
|
|
406
|
+
}, {
|
|
407
|
+
"name": "pointerdown",
|
|
408
|
+
"method": "handleOutsidePointerDown",
|
|
409
|
+
"target": "document",
|
|
410
|
+
"capture": true,
|
|
411
|
+
"passive": false
|
|
390
412
|
}, {
|
|
391
413
|
"name": "keydown",
|
|
392
414
|
"method": "handleKeyDown",
|
|
@@ -117,6 +117,11 @@ export const darkTheme = {
|
|
|
117
117
|
engine: {
|
|
118
118
|
backgroundColor: '#1a1a1a',
|
|
119
119
|
},
|
|
120
|
+
snap: {
|
|
121
|
+
indicatorFill: 'rgba(10, 132, 255, 0.35)',
|
|
122
|
+
indicatorStroke: '#0A84FF',
|
|
123
|
+
lineStroke: 'rgba(255, 255, 255, 0.35)',
|
|
124
|
+
},
|
|
120
125
|
fontSize: {
|
|
121
126
|
hoverBackgroundColor: '#3a3a3a',
|
|
122
127
|
selectedBackgroundColor: '#3a3a3a',
|
|
@@ -118,6 +118,11 @@ export const lightTheme = {
|
|
|
118
118
|
engine: {
|
|
119
119
|
backgroundColor: '#ffffff',
|
|
120
120
|
},
|
|
121
|
+
snap: {
|
|
122
|
+
indicatorFill: 'rgba(59, 130, 246, 0.3)',
|
|
123
|
+
indicatorStroke: '#007bff',
|
|
124
|
+
lineStroke: 'rgba(0, 0, 0, 0.2)',
|
|
125
|
+
},
|
|
121
126
|
fontSize: {
|
|
122
127
|
hoverBackgroundColor: '#ebebeb',
|
|
123
128
|
selectedBackgroundColor: '#ebebeb',
|