@inditextech/weave-sdk 5.0.0-SNAPSHOT.366.1 → 5.0.0-SNAPSHOT.397.1
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/sdk.js +2049 -172
- package/dist/sdk.node.js +2049 -172
- package/dist/sdk.node.stats.html +1 -1
- package/dist/sdk.stats.html +1 -1
- package/dist/types.d.ts +310 -30
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2049 -172
- package/dist/types.js.map +1 -1
- package/dist/types.stats.html +1 -1
- package/package.json +2 -2
package/dist/types.js
CHANGED
|
@@ -4356,6 +4356,7 @@ var TransformerController = class {
|
|
|
4356
4356
|
listening: true,
|
|
4357
4357
|
shouldOverdrawWholeArea: true
|
|
4358
4358
|
});
|
|
4359
|
+
this.tr.boundBoxFunc(this.getBoundBoxFunc());
|
|
4359
4360
|
layer.add(this.tr);
|
|
4360
4361
|
this.trHover = new Konva.Transformer({
|
|
4361
4362
|
id: "hoverTransformer",
|
|
@@ -4371,6 +4372,20 @@ var TransformerController = class {
|
|
|
4371
4372
|
this.registerTransformerEvents();
|
|
4372
4373
|
this.registerInstanceEvents();
|
|
4373
4374
|
}
|
|
4375
|
+
getBoundBoxFunc() {
|
|
4376
|
+
return (oldBox, newBox) => {
|
|
4377
|
+
const sx = newBox.width / oldBox.width;
|
|
4378
|
+
const sy = newBox.height / oldBox.height;
|
|
4379
|
+
const violatesConstraint = this.tr.nodes().some((node) => {
|
|
4380
|
+
const rect = node.getClientRect({ skipStroke: true });
|
|
4381
|
+
const { width: minWidth, height: minHeight } = node.getNodeMinSize();
|
|
4382
|
+
if (["middle-right", "middle-left"].includes(this.tr.getActiveAnchor() ?? "")) return rect.width * sx < minWidth;
|
|
4383
|
+
if (["top-center", "bottom-center"].includes(this.tr.getActiveAnchor() ?? "")) return rect.height * sy < minHeight;
|
|
4384
|
+
return rect.width * sx < minWidth || rect.height * sy < minHeight;
|
|
4385
|
+
});
|
|
4386
|
+
return violatesConstraint ? oldBox : newBox;
|
|
4387
|
+
};
|
|
4388
|
+
}
|
|
4374
4389
|
getTransformer() {
|
|
4375
4390
|
return this.tr;
|
|
4376
4391
|
}
|
|
@@ -4835,9 +4850,10 @@ function handleClickOrTap(ctx, e) {
|
|
|
4835
4850
|
const isMainLayer = parent === mainLayer;
|
|
4836
4851
|
const isContainerEmptyArea = e.target.getAttrs().isContainerPrincipal !== void 0 && !e.target.getAttrs().isContainerPrincipal;
|
|
4837
4852
|
if (isStage || isMainLayer || isContainerEmptyArea) ctx.setSelectedNodes([]);
|
|
4853
|
+
ctx.triggerSelectedNodesEvent();
|
|
4838
4854
|
return;
|
|
4839
4855
|
}
|
|
4840
|
-
if (nodeTargeted.getAttrs().nodeId) {
|
|
4856
|
+
if (!nodeTargeted.getAttrs().name?.includes("node") && nodeTargeted.getAttrs().nodeId) {
|
|
4841
4857
|
const realNode = stage.findOne(`#${nodeTargeted.getAttrs().nodeId}`);
|
|
4842
4858
|
if (realNode) nodeTargeted = realNode;
|
|
4843
4859
|
}
|
|
@@ -4950,6 +4966,7 @@ function handlePointerDown(ctx, e) {
|
|
|
4950
4966
|
for (const node of nodesSelected) node.fire("onSelectionCleared", { bubbles: true });
|
|
4951
4967
|
}
|
|
4952
4968
|
ctx.selectNone();
|
|
4969
|
+
ctx.triggerSelectedNodesEvent();
|
|
4953
4970
|
ctx.getWeaveInstance().emitEvent("onSelectionState", true);
|
|
4954
4971
|
ctx.getEdgePanning().start();
|
|
4955
4972
|
}
|
|
@@ -5432,6 +5449,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
|
|
|
5432
5449
|
isDragging() {
|
|
5433
5450
|
return this.transformerCtrl.isDragging();
|
|
5434
5451
|
}
|
|
5452
|
+
getBoundBoxFunc() {
|
|
5453
|
+
return this.transformerCtrl.getBoundBoxFunc();
|
|
5454
|
+
}
|
|
5435
5455
|
getSelectorConfig() {
|
|
5436
5456
|
return this.config.selection;
|
|
5437
5457
|
}
|
|
@@ -6006,6 +6026,12 @@ const augmentKonvaNodeClass = (config) => {
|
|
|
6006
6026
|
};
|
|
6007
6027
|
Konva.Node.prototype.lockMutex = function() {};
|
|
6008
6028
|
Konva.Node.prototype.releaseMutex = function() {};
|
|
6029
|
+
Konva.Node.prototype.getNodeMinSize = function() {
|
|
6030
|
+
return {
|
|
6031
|
+
width: 0,
|
|
6032
|
+
height: 0
|
|
6033
|
+
};
|
|
6034
|
+
};
|
|
6009
6035
|
};
|
|
6010
6036
|
var WeaveNode = class {
|
|
6011
6037
|
async register(instance) {
|
|
@@ -6169,8 +6195,8 @@ var WeaveNode = class {
|
|
|
6169
6195
|
if (selectionPlugin?.getSelectedNodes().map((node) => node.getAttrs().id).includes(ele.getAttrs().id)) return true;
|
|
6170
6196
|
return false;
|
|
6171
6197
|
}
|
|
6172
|
-
scaleReset(node) {
|
|
6173
|
-
const scale = node.scale();
|
|
6198
|
+
scaleReset(node, scaleCustom) {
|
|
6199
|
+
const scale = scaleCustom ?? node.scale();
|
|
6174
6200
|
node.width(Math.max(5, node.width() * scale.x));
|
|
6175
6201
|
node.height(Math.max(5, node.height() * scale.y));
|
|
6176
6202
|
node.scale({
|
|
@@ -6260,8 +6286,6 @@ var WeaveNode = class {
|
|
|
6260
6286
|
if (e.target.getAttrs()._revertStrokeScaleEnabled === true) e.target.setAttr("strokeScaleEnabled", true);
|
|
6261
6287
|
e.target.setAttr("_revertStrokeScaleEnabled", void 0);
|
|
6262
6288
|
this.instance.emitEvent("onTransform", null);
|
|
6263
|
-
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
6264
|
-
if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
6265
6289
|
if (performScaleReset) this.scaleReset(node$1);
|
|
6266
6290
|
if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
|
|
6267
6291
|
this.getNodesSelectionFeedbackPlugin()?.showSelectionHalo(node$1);
|
|
@@ -6270,8 +6294,13 @@ var WeaveNode = class {
|
|
|
6270
6294
|
const nodeHandler = this.instance.getNodeHandler(node$1.getAttrs().nodeType);
|
|
6271
6295
|
if (nodeHandler) {
|
|
6272
6296
|
const shouldUpdateOnTransform = node$1.getAttrs().shouldUpdateOnTransform ?? true;
|
|
6273
|
-
if (shouldUpdateOnTransform)
|
|
6297
|
+
if (shouldUpdateOnTransform) {
|
|
6298
|
+
const serializedNode = nodeHandler.serialize(node$1);
|
|
6299
|
+
this.instance.updateNode(serializedNode);
|
|
6300
|
+
}
|
|
6274
6301
|
}
|
|
6302
|
+
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
6303
|
+
if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
6275
6304
|
this.getNodesSelectionPlugin()?.getHoverTransformer().forceUpdate();
|
|
6276
6305
|
});
|
|
6277
6306
|
const stage = this.instance.getStage();
|
|
@@ -8427,7 +8456,11 @@ var WeaveGroupsManager = class {
|
|
|
8427
8456
|
this.instance.removeNodes(sortedNodesByZIndex);
|
|
8428
8457
|
groupInstance.destroy();
|
|
8429
8458
|
const groupNode = stage.findOne(`#${groupId}`);
|
|
8430
|
-
if (groupHandler && groupNode)
|
|
8459
|
+
if (groupHandler && groupNode) {
|
|
8460
|
+
groupNode.x(0);
|
|
8461
|
+
groupNode.y(0);
|
|
8462
|
+
this.instance.updateNodeNT(groupHandler.serialize(groupNode));
|
|
8463
|
+
}
|
|
8431
8464
|
setTimeout(() => {
|
|
8432
8465
|
this.getNodesMultiSelectionFeedbackPlugin()?.cleanupSelectedHalos();
|
|
8433
8466
|
const groupNode$1 = stage.findOne(`#${groupId}`);
|
|
@@ -8489,6 +8522,8 @@ var WeaveGroupsManager = class {
|
|
|
8489
8522
|
y: absScale.y / stage.scaleY()
|
|
8490
8523
|
});
|
|
8491
8524
|
child.rotation(absRotation);
|
|
8525
|
+
const nodeHandler = this.instance.getNodeHandler(child.getAttrs().nodeType);
|
|
8526
|
+
if (nodeHandler) nodeHandler.scaleReset(child);
|
|
8492
8527
|
child.zIndex(newLayerChildrenAmount - 1 + child.zIndex());
|
|
8493
8528
|
child.setAttr("draggable", true);
|
|
8494
8529
|
newChildId = child.getAttrs().id;
|
|
@@ -9299,6 +9334,7 @@ var WeaveStateManager = class {
|
|
|
9299
9334
|
}
|
|
9300
9335
|
const yjsProps = yjsNode.get("props");
|
|
9301
9336
|
this.updateYjsMapFromObject(yjsProps, node.props);
|
|
9337
|
+
if (Array.isArray(node.props.children) && node.props.children.length > 0) for (const child of node.props.children) this.updateNode(child);
|
|
9302
9338
|
this.instance.emitEvent("onNodeUpdated", node);
|
|
9303
9339
|
}
|
|
9304
9340
|
updateNodes(nodes) {
|
|
@@ -9493,7 +9529,7 @@ var WeaveRegisterManager = class {
|
|
|
9493
9529
|
|
|
9494
9530
|
//#endregion
|
|
9495
9531
|
//#region package.json
|
|
9496
|
-
var version = "5.0.0-SNAPSHOT.
|
|
9532
|
+
var version = "5.0.0-SNAPSHOT.397.1";
|
|
9497
9533
|
|
|
9498
9534
|
//#endregion
|
|
9499
9535
|
//#region src/managers/setup.ts
|
|
@@ -11882,10 +11918,36 @@ var WeaveGroupNode = class extends WeaveNode {
|
|
|
11882
11918
|
return intersectArrays(anchorsArrays);
|
|
11883
11919
|
};
|
|
11884
11920
|
this.setupDefaultNodeEvents(group);
|
|
11921
|
+
group.on("transform", () => {
|
|
11922
|
+
const sx = group.scaleX();
|
|
11923
|
+
const sy = group.scaleY();
|
|
11924
|
+
group.getChildren().forEach((child) => {
|
|
11925
|
+
child.scaleX(child.scaleX() * sx);
|
|
11926
|
+
child.scaleY(child.scaleY() * sy);
|
|
11927
|
+
child.x(child.x() * sx);
|
|
11928
|
+
child.y(child.y() * sy);
|
|
11929
|
+
const nodeHandler = this.instance.getNodeHandler(child.getAttrs().nodeType);
|
|
11930
|
+
if (nodeHandler) {
|
|
11931
|
+
nodeHandler.scaleReset(child);
|
|
11932
|
+
nodeHandler.onUpdate(child, child.getAttrs());
|
|
11933
|
+
}
|
|
11934
|
+
});
|
|
11935
|
+
group.scale({
|
|
11936
|
+
x: 1,
|
|
11937
|
+
y: 1
|
|
11938
|
+
});
|
|
11939
|
+
});
|
|
11885
11940
|
return group;
|
|
11886
11941
|
}
|
|
11887
11942
|
onUpdate(nodeInstance, nextProps) {
|
|
11888
|
-
nodeInstance.setAttrs({
|
|
11943
|
+
nodeInstance.setAttrs({
|
|
11944
|
+
...nextProps,
|
|
11945
|
+
x: nextProps.x ?? 0,
|
|
11946
|
+
y: nextProps.y ?? 0,
|
|
11947
|
+
scaleX: nextProps.scaleX ?? 1,
|
|
11948
|
+
scaleY: nextProps.scaleY ?? 1,
|
|
11949
|
+
rotation: nextProps.rotation ?? 0
|
|
11950
|
+
});
|
|
11889
11951
|
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
11890
11952
|
if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
11891
11953
|
}
|
|
@@ -11922,7 +11984,25 @@ var WeaveGroupNode = class extends WeaveNode {
|
|
|
11922
11984
|
}
|
|
11923
11985
|
};
|
|
11924
11986
|
}
|
|
11925
|
-
scaleReset() {
|
|
11987
|
+
scaleReset(node) {
|
|
11988
|
+
const sx = node.scaleX();
|
|
11989
|
+
const sy = node.scaleY();
|
|
11990
|
+
node.getChildren().forEach((child) => {
|
|
11991
|
+
child.scaleX(child.scaleX() * sx);
|
|
11992
|
+
child.scaleY(child.scaleY() * sy);
|
|
11993
|
+
child.x(child.x() * sx);
|
|
11994
|
+
child.y(child.y() * sy);
|
|
11995
|
+
const nodeHandler = this.instance.getNodeHandler(child.getAttrs().nodeType);
|
|
11996
|
+
if (nodeHandler) {
|
|
11997
|
+
nodeHandler.scaleReset(child);
|
|
11998
|
+
nodeHandler.onUpdate(child, child.getAttrs());
|
|
11999
|
+
}
|
|
12000
|
+
});
|
|
12001
|
+
node.scale({
|
|
12002
|
+
x: 1,
|
|
12003
|
+
y: 1
|
|
12004
|
+
});
|
|
12005
|
+
}
|
|
11926
12006
|
};
|
|
11927
12007
|
|
|
11928
12008
|
//#endregion
|
|
@@ -11975,11 +12055,546 @@ function getJSONFromYjsBinary(actualState) {
|
|
|
11975
12055
|
return actualStateJson;
|
|
11976
12056
|
}
|
|
11977
12057
|
|
|
12058
|
+
//#endregion
|
|
12059
|
+
//#region src/nodes/shared/shape-label.constants.ts
|
|
12060
|
+
const WEAVE_STAGE_SHAPE_LABEL_EDITION_MODE = "shape-label-edition";
|
|
12061
|
+
const WEAVE_SHAPE_LABEL_DEFAULTS = {
|
|
12062
|
+
labelText: "",
|
|
12063
|
+
labelFontFamily: "Arial, sans-serif",
|
|
12064
|
+
labelFontSize: 14,
|
|
12065
|
+
labelFontStyle: "normal",
|
|
12066
|
+
labelFontVariant: "normal",
|
|
12067
|
+
labelTextDecoration: "",
|
|
12068
|
+
labelFill: "#000000",
|
|
12069
|
+
labelAlign: "center",
|
|
12070
|
+
labelVerticalAlign: "middle",
|
|
12071
|
+
labelLetterSpacing: 0,
|
|
12072
|
+
labelLineHeight: 1,
|
|
12073
|
+
labelPaddingX: 8,
|
|
12074
|
+
labelPaddingY: 8
|
|
12075
|
+
};
|
|
12076
|
+
const labelId = (id) => `${id}-label`;
|
|
12077
|
+
|
|
12078
|
+
//#endregion
|
|
12079
|
+
//#region src/nodes/shared/shape-label-editor.ts
|
|
12080
|
+
var WeaveShapeLabelEditor = class {
|
|
12081
|
+
editing = false;
|
|
12082
|
+
editingGroup = null;
|
|
12083
|
+
editingTextBounds = null;
|
|
12084
|
+
textArea = null;
|
|
12085
|
+
onLiveResize = null;
|
|
12086
|
+
constructor(instance) {
|
|
12087
|
+
this.instance = instance;
|
|
12088
|
+
}
|
|
12089
|
+
isEditing() {
|
|
12090
|
+
return this.editing;
|
|
12091
|
+
}
|
|
12092
|
+
renderLabel(group, props, textBounds) {
|
|
12093
|
+
const labelText = props.labelText ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelText;
|
|
12094
|
+
const labelNode = new Konva.Text({
|
|
12095
|
+
id: labelId(props.id),
|
|
12096
|
+
x: textBounds.x,
|
|
12097
|
+
y: textBounds.y,
|
|
12098
|
+
width: textBounds.width,
|
|
12099
|
+
height: textBounds.height,
|
|
12100
|
+
text: labelText,
|
|
12101
|
+
fontFamily: props.labelFontFamily ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontFamily,
|
|
12102
|
+
fontSize: props.labelFontSize ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontSize,
|
|
12103
|
+
fontStyle: props.labelFontStyle ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontStyle,
|
|
12104
|
+
fontVariant: props.labelFontVariant ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontVariant,
|
|
12105
|
+
textDecoration: props.labelTextDecoration ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelTextDecoration,
|
|
12106
|
+
fill: props.labelFill ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFill,
|
|
12107
|
+
align: props.labelAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelAlign,
|
|
12108
|
+
verticalAlign: props.labelVerticalAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelVerticalAlign,
|
|
12109
|
+
letterSpacing: props.labelLetterSpacing ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelLetterSpacing,
|
|
12110
|
+
lineHeight: props.labelLineHeight ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelLineHeight,
|
|
12111
|
+
wrap: "word",
|
|
12112
|
+
listening: false,
|
|
12113
|
+
visible: labelText !== ""
|
|
12114
|
+
});
|
|
12115
|
+
group.add(labelNode);
|
|
12116
|
+
return labelNode;
|
|
12117
|
+
}
|
|
12118
|
+
updateLabel(group, nextProps, textBounds, growCallback) {
|
|
12119
|
+
const labelNode = group.findOne(`#${labelId(nextProps.id)}`);
|
|
12120
|
+
if (!labelNode) return;
|
|
12121
|
+
const labelText = nextProps.labelText ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelText;
|
|
12122
|
+
labelNode.setAttrs({
|
|
12123
|
+
x: textBounds.x,
|
|
12124
|
+
y: textBounds.y,
|
|
12125
|
+
width: textBounds.width,
|
|
12126
|
+
height: textBounds.height,
|
|
12127
|
+
text: labelText,
|
|
12128
|
+
fontFamily: nextProps.labelFontFamily ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontFamily,
|
|
12129
|
+
fontSize: nextProps.labelFontSize ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontSize,
|
|
12130
|
+
fontStyle: nextProps.labelFontStyle ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontStyle,
|
|
12131
|
+
fontVariant: nextProps.labelFontVariant ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontVariant,
|
|
12132
|
+
textDecoration: nextProps.labelTextDecoration ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelTextDecoration,
|
|
12133
|
+
fill: nextProps.labelFill ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFill,
|
|
12134
|
+
align: nextProps.labelAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelAlign,
|
|
12135
|
+
verticalAlign: nextProps.labelVerticalAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelVerticalAlign,
|
|
12136
|
+
letterSpacing: nextProps.labelLetterSpacing ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelLetterSpacing,
|
|
12137
|
+
lineHeight: nextProps.labelLineHeight ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelLineHeight,
|
|
12138
|
+
wrap: "word",
|
|
12139
|
+
visible: !this.editing && labelText !== ""
|
|
12140
|
+
});
|
|
12141
|
+
if (labelText !== "") {
|
|
12142
|
+
labelNode.setAttr("height", void 0);
|
|
12143
|
+
const measuredHeight = labelNode.height();
|
|
12144
|
+
labelNode.height(Math.max(textBounds.height, measuredHeight));
|
|
12145
|
+
if (growCallback && measuredHeight > textBounds.height) {
|
|
12146
|
+
const paddingY = nextProps.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12147
|
+
growCallback(measuredHeight + paddingY * 2);
|
|
12148
|
+
}
|
|
12149
|
+
}
|
|
12150
|
+
}
|
|
12151
|
+
computeVerticalOffset(verticalAlign, boundsHeightPx, contentHeightPx) {
|
|
12152
|
+
if (verticalAlign === "top") return 0;
|
|
12153
|
+
if (verticalAlign === "bottom") return Math.max(0, boundsHeightPx - contentHeightPx);
|
|
12154
|
+
return Math.max(0, (boundsHeightPx - contentHeightPx) / 2);
|
|
12155
|
+
}
|
|
12156
|
+
triggerEditMode(group, textBounds, onCommit, onLiveResize) {
|
|
12157
|
+
if (this.editing) return;
|
|
12158
|
+
const lockAcquired = this.instance.setMutexLock({
|
|
12159
|
+
nodeIds: [group.id()],
|
|
12160
|
+
operation: "label-edit"
|
|
12161
|
+
});
|
|
12162
|
+
if (!lockAcquired) return;
|
|
12163
|
+
this.editing = true;
|
|
12164
|
+
this.editingGroup = group;
|
|
12165
|
+
this.editingTextBounds = textBounds;
|
|
12166
|
+
this.onLiveResize = onLiveResize ?? null;
|
|
12167
|
+
const labelNode = group.findOne(`#${labelId(group.id())}`);
|
|
12168
|
+
if (labelNode) labelNode.visible(false);
|
|
12169
|
+
const selectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
12170
|
+
if (selectionPlugin) {
|
|
12171
|
+
const tr = selectionPlugin.getTransformer();
|
|
12172
|
+
this.instance.disablePlugin("nodesSelection");
|
|
12173
|
+
tr.hide();
|
|
12174
|
+
}
|
|
12175
|
+
const stage = this.instance.getStage();
|
|
12176
|
+
const upscaleScale = stage.getAttr("upscaleScale") ?? 1;
|
|
12177
|
+
const absoluteTransform = group.getAbsoluteTransform();
|
|
12178
|
+
const topLeft = absoluteTransform.point({
|
|
12179
|
+
x: textBounds.x,
|
|
12180
|
+
y: textBounds.y
|
|
12181
|
+
});
|
|
12182
|
+
this.createTextAreaDOM(group, textBounds, topLeft, upscaleScale, onCommit, onLiveResize);
|
|
12183
|
+
this.instance.getStage().mode(WEAVE_STAGE_SHAPE_LABEL_EDITION_MODE);
|
|
12184
|
+
}
|
|
12185
|
+
exitEditMode() {
|
|
12186
|
+
if (!this.editing) return;
|
|
12187
|
+
this.instance.releaseMutexLock();
|
|
12188
|
+
this.instance.getStage().mode(WEAVE_STAGE_DEFAULT_MODE);
|
|
12189
|
+
this.editing = false;
|
|
12190
|
+
if (this.editingGroup) {
|
|
12191
|
+
const liveGroup = this.instance.getStage().findOne(`#${this.editingGroup.id()}`);
|
|
12192
|
+
const labelNode = liveGroup?.findOne(`#${labelId(this.editingGroup.id())}`);
|
|
12193
|
+
if (labelNode) {
|
|
12194
|
+
labelNode.visible(true);
|
|
12195
|
+
labelNode.getLayer()?.batchDraw();
|
|
12196
|
+
}
|
|
12197
|
+
this.editingGroup = null;
|
|
12198
|
+
}
|
|
12199
|
+
if (this.textArea) this.textArea.remove();
|
|
12200
|
+
this.textArea = null;
|
|
12201
|
+
this.onLiveResize = null;
|
|
12202
|
+
this.editingTextBounds = null;
|
|
12203
|
+
this.instance.getStage().off(".weaveLabelEdit");
|
|
12204
|
+
const selectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
12205
|
+
if (selectionPlugin) this.instance.enablePlugin("nodesSelection");
|
|
12206
|
+
}
|
|
12207
|
+
updateTextAreaPosition(group, textBounds) {
|
|
12208
|
+
if (!this.editing || !this.textArea) return;
|
|
12209
|
+
const stage = this.instance.getStage();
|
|
12210
|
+
const upscaleScale = stage.getAttr("upscaleScale") ?? 1;
|
|
12211
|
+
const absoluteTransform = group.getAbsoluteTransform();
|
|
12212
|
+
const topLeft = absoluteTransform.point({
|
|
12213
|
+
x: textBounds.x,
|
|
12214
|
+
y: textBounds.y
|
|
12215
|
+
});
|
|
12216
|
+
this.textArea.style.left = `${topLeft.x * upscaleScale}px`;
|
|
12217
|
+
const absScale = group.getAbsoluteScale();
|
|
12218
|
+
const props = group.getAttrs();
|
|
12219
|
+
const fontSize = (props.labelFontSize ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontSize) * absScale.x;
|
|
12220
|
+
this.textArea.style.fontSize = `${fontSize * upscaleScale}px`;
|
|
12221
|
+
const textWidth = textBounds.width * absScale.x;
|
|
12222
|
+
this.textArea.style.width = `${textWidth * upscaleScale}px`;
|
|
12223
|
+
const originalBoundsHeightPx = textBounds.height * absScale.y * upscaleScale;
|
|
12224
|
+
const paddingY = props.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12225
|
+
const verticalAlign = props.labelVerticalAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelVerticalAlign;
|
|
12226
|
+
this.textArea.style.height = "auto";
|
|
12227
|
+
const contentHeightPx = this.textArea.scrollHeight;
|
|
12228
|
+
if (contentHeightPx <= originalBoundsHeightPx) {
|
|
12229
|
+
this.textArea.style.height = `${contentHeightPx}px`;
|
|
12230
|
+
const offsetY = this.computeVerticalOffset(verticalAlign, originalBoundsHeightPx, contentHeightPx);
|
|
12231
|
+
this.textArea.style.top = `${topLeft.y * upscaleScale + offsetY}px`;
|
|
12232
|
+
} else {
|
|
12233
|
+
this.textArea.style.height = `${contentHeightPx}px`;
|
|
12234
|
+
this.textArea.style.top = `${topLeft.y * upscaleScale}px`;
|
|
12235
|
+
}
|
|
12236
|
+
if (this.onLiveResize) {
|
|
12237
|
+
const contentHeightInCanvas = contentHeightPx / (absScale.y * upscaleScale);
|
|
12238
|
+
this.onLiveResize(contentHeightInCanvas + paddingY * 2);
|
|
12239
|
+
}
|
|
12240
|
+
}
|
|
12241
|
+
/**
|
|
12242
|
+
* Updates the textarea `left`, `width`, and `top` to match new text bounds.
|
|
12243
|
+
* Call this from an `onLiveResize` callback when the shape grows symmetrically
|
|
12244
|
+
* (e.g. regular polygon) so the textarea tracks the new position on all axes.
|
|
12245
|
+
* Does NOT call `onLiveResize` — there is no re-entrancy risk, but also no need.
|
|
12246
|
+
*/
|
|
12247
|
+
repositionTextArea(group, textBounds) {
|
|
12248
|
+
if (!this.editing || !this.textArea) return;
|
|
12249
|
+
this.editingTextBounds = textBounds;
|
|
12250
|
+
const stage = this.instance.getStage();
|
|
12251
|
+
const upscaleScale = stage.getAttr("upscaleScale") ?? 1;
|
|
12252
|
+
const absoluteTransform = group.getAbsoluteTransform();
|
|
12253
|
+
const topLeft = absoluteTransform.point({
|
|
12254
|
+
x: textBounds.x,
|
|
12255
|
+
y: textBounds.y
|
|
12256
|
+
});
|
|
12257
|
+
const absScale = group.getAbsoluteScale();
|
|
12258
|
+
const textWidth = textBounds.width * absScale.x;
|
|
12259
|
+
this.textArea.style.left = `${topLeft.x * upscaleScale}px`;
|
|
12260
|
+
this.textArea.style.width = `${textWidth * upscaleScale}px`;
|
|
12261
|
+
const newBoundsHeightPx = textBounds.height * absScale.y * upscaleScale;
|
|
12262
|
+
const savedHeight = this.textArea.style.height;
|
|
12263
|
+
this.textArea.style.height = "auto";
|
|
12264
|
+
const actualContentHeightPx = this.textArea.scrollHeight;
|
|
12265
|
+
this.textArea.style.height = savedHeight;
|
|
12266
|
+
const groupProps = group.getAttrs();
|
|
12267
|
+
const verticalAlign = groupProps.labelVerticalAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelVerticalAlign;
|
|
12268
|
+
const offsetY = this.computeVerticalOffset(verticalAlign, newBoundsHeightPx, actualContentHeightPx);
|
|
12269
|
+
this.textArea.style.top = `${topLeft.y * upscaleScale + offsetY}px`;
|
|
12270
|
+
}
|
|
12271
|
+
/**
|
|
12272
|
+
* Convergence loop: onLiveResize may change the textarea width (e.g. a
|
|
12273
|
+
* growing polygon becomes wider), which changes line-wrapping, which may
|
|
12274
|
+
* require a different shape height. Iterates until scrollHeight is stable
|
|
12275
|
+
* or a safety limit is reached (5 passes cover any practical input).
|
|
12276
|
+
*
|
|
12277
|
+
* Oscillation prevention: if the sequence alternates (narrow→grow→wide→
|
|
12278
|
+
* restore→narrow→…) the loop exits with the polygon under-sized.
|
|
12279
|
+
* We track `lastUsedPx` — the height last passed to onLiveResize — and
|
|
12280
|
+
* fire a final corrective grow whenever `prevHeightPx > lastUsedPx`
|
|
12281
|
+
* (content at the current width still overflows what was last asked for).
|
|
12282
|
+
*/
|
|
12283
|
+
runLiveResizeLoop(onLiveResize, contentHeightPx, effectiveScale, upscaleScale, paddingY) {
|
|
12284
|
+
const MAX_PASSES = 5;
|
|
12285
|
+
let maxNeededPx = contentHeightPx;
|
|
12286
|
+
let prevHeightPx = contentHeightPx;
|
|
12287
|
+
let lastUsedPx = 0;
|
|
12288
|
+
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
12289
|
+
lastUsedPx = prevHeightPx;
|
|
12290
|
+
const neededInCanvas = prevHeightPx / (effectiveScale * upscaleScale);
|
|
12291
|
+
onLiveResize(neededInCanvas + paddingY * 2);
|
|
12292
|
+
if (!this.textArea) break;
|
|
12293
|
+
this.textArea.style.height = "auto";
|
|
12294
|
+
const measuredPx = this.textArea.scrollHeight;
|
|
12295
|
+
this.textArea.style.height = `${measuredPx}px`;
|
|
12296
|
+
if (measuredPx > maxNeededPx) maxNeededPx = measuredPx;
|
|
12297
|
+
if (measuredPx === prevHeightPx) break;
|
|
12298
|
+
prevHeightPx = measuredPx;
|
|
12299
|
+
}
|
|
12300
|
+
if (this.textArea && prevHeightPx > lastUsedPx) {
|
|
12301
|
+
const finalInCanvas = maxNeededPx / (effectiveScale * upscaleScale);
|
|
12302
|
+
onLiveResize(finalInCanvas + paddingY * 2);
|
|
12303
|
+
this.textArea.style.height = "auto";
|
|
12304
|
+
const finalPx = this.textArea.scrollHeight;
|
|
12305
|
+
this.textArea.style.height = `${finalPx}px`;
|
|
12306
|
+
}
|
|
12307
|
+
}
|
|
12308
|
+
createTextAreaDOM(group, textBounds, position, upscaleScale, onCommit, onLiveResize) {
|
|
12309
|
+
const stage = this.instance.getStage();
|
|
12310
|
+
const props = group.getAttrs();
|
|
12311
|
+
const absScale = group.getAbsoluteScale();
|
|
12312
|
+
const effectiveScale = absScale.x;
|
|
12313
|
+
this.textArea = document.createElement("textarea");
|
|
12314
|
+
this.textArea.id = `${group.id()}_label_textarea`;
|
|
12315
|
+
this.textArea.rows = 1;
|
|
12316
|
+
stage.container().appendChild(this.textArea);
|
|
12317
|
+
stage.on("dragmove.weaveLabelEdit xChange.weaveLabelEdit yChange.weaveLabelEdit", () => {
|
|
12318
|
+
if (this.editingGroup && this.editingTextBounds) this.repositionTextArea(this.editingGroup, this.editingTextBounds);
|
|
12319
|
+
});
|
|
12320
|
+
const textWidth = textBounds.width * effectiveScale;
|
|
12321
|
+
const fontSize = (props.labelFontSize ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontSize) * effectiveScale;
|
|
12322
|
+
const originalBoundsHeightPx = textBounds.height * effectiveScale * upscaleScale;
|
|
12323
|
+
const paddingY = props.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12324
|
+
this.textArea.style.position = "absolute";
|
|
12325
|
+
this.textArea.style.visibility = "hidden";
|
|
12326
|
+
this.textArea.style.left = `${position.x * upscaleScale}px`;
|
|
12327
|
+
this.textArea.style.width = `${textWidth * upscaleScale}px`;
|
|
12328
|
+
this.textArea.style.border = "solid 0px #1e40af";
|
|
12329
|
+
this.textArea.style.background = "transparent";
|
|
12330
|
+
this.textArea.style.backgroundColor = "transparent";
|
|
12331
|
+
this.textArea.style.boxSizing = "border-box";
|
|
12332
|
+
this.textArea.style.overflow = "hidden";
|
|
12333
|
+
const rotation = group.getAbsoluteRotation();
|
|
12334
|
+
if (rotation) {
|
|
12335
|
+
this.textArea.style.transformOrigin = "left top";
|
|
12336
|
+
this.textArea.style.transform = `rotate(${rotation}deg)`;
|
|
12337
|
+
}
|
|
12338
|
+
this.textArea.value = props.labelText ?? "";
|
|
12339
|
+
this.textArea.style.fontSize = `${fontSize * upscaleScale}px`;
|
|
12340
|
+
this.textArea.style.fontFamily = props.labelFontFamily ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontFamily;
|
|
12341
|
+
this.textArea.style.letterSpacing = `${props.labelLetterSpacing ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelLetterSpacing}px`;
|
|
12342
|
+
this.textArea.style.lineHeight = `${props.labelLineHeight ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelLineHeight}em`;
|
|
12343
|
+
const fontStyle = props.labelFontStyle ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontStyle;
|
|
12344
|
+
this.textArea.style.fontStyle = fontStyle.includes("italic") ? "italic" : "normal";
|
|
12345
|
+
this.textArea.style.textDecoration = props.labelTextDecoration ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelTextDecoration;
|
|
12346
|
+
let fontWeight = "normal";
|
|
12347
|
+
const matchNumber = fontStyle.match(/\d+/);
|
|
12348
|
+
if (fontStyle.includes("bold")) fontWeight = "bold";
|
|
12349
|
+
if (matchNumber) fontWeight = matchNumber[0];
|
|
12350
|
+
this.textArea.style.fontWeight = fontWeight;
|
|
12351
|
+
this.textArea.style.fontVariant = props.labelFontVariant ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontVariant;
|
|
12352
|
+
this.textArea.style.color = props.labelFill ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFill;
|
|
12353
|
+
this.textArea.style.textAlign = props.labelAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelAlign;
|
|
12354
|
+
this.textArea.style.outline = "none";
|
|
12355
|
+
this.textArea.style.resize = "none";
|
|
12356
|
+
this.textArea.style.margin = "0";
|
|
12357
|
+
this.textArea.style.padding = "0";
|
|
12358
|
+
this.textArea.style.caretColor = "black";
|
|
12359
|
+
this.textArea.style.overscrollBehavior = "contains";
|
|
12360
|
+
const resizeTextarea = () => {
|
|
12361
|
+
if (!this.textArea) return;
|
|
12362
|
+
this.textArea.style.height = "auto";
|
|
12363
|
+
const contentHeightPx = this.textArea.scrollHeight;
|
|
12364
|
+
const fonts = this.instance.getFonts();
|
|
12365
|
+
const font = fonts.find((f) => f.name === (props.labelFontFamily ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontFamily));
|
|
12366
|
+
const currentBounds = this.editingTextBounds ?? textBounds;
|
|
12367
|
+
const liveTL = group.getAbsoluteTransform().point({
|
|
12368
|
+
x: currentBounds.x,
|
|
12369
|
+
y: currentBounds.y + (font?.offsetY ?? 0)
|
|
12370
|
+
});
|
|
12371
|
+
this.textArea.style.left = `${liveTL.x * upscaleScale}px`;
|
|
12372
|
+
if (contentHeightPx <= originalBoundsHeightPx) {
|
|
12373
|
+
this.textArea.style.height = `${contentHeightPx}px`;
|
|
12374
|
+
const verticalAlign = props.labelVerticalAlign ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelVerticalAlign;
|
|
12375
|
+
const offsetY = this.computeVerticalOffset(verticalAlign, originalBoundsHeightPx, contentHeightPx);
|
|
12376
|
+
this.textArea.style.top = `${liveTL.y * upscaleScale + offsetY}px`;
|
|
12377
|
+
} else {
|
|
12378
|
+
this.textArea.style.height = `${contentHeightPx}px`;
|
|
12379
|
+
this.textArea.style.top = `${liveTL.y * upscaleScale}px`;
|
|
12380
|
+
}
|
|
12381
|
+
if (onLiveResize) this.runLiveResizeLoop(onLiveResize, contentHeightPx, effectiveScale, upscaleScale, paddingY);
|
|
12382
|
+
if (this.textArea.style.visibility === "hidden") this.textArea.style.visibility = "";
|
|
12383
|
+
};
|
|
12384
|
+
const commit = (text) => {
|
|
12385
|
+
window.removeEventListener("pointerup", handleOutsideClick);
|
|
12386
|
+
this.exitEditMode();
|
|
12387
|
+
const liveGroup = this.instance.getStage().findOne(`#${group.id()}`);
|
|
12388
|
+
const labelNode = liveGroup?.findOne(`#${labelId(group.id())}`);
|
|
12389
|
+
if (labelNode) labelNode.visible(text !== "");
|
|
12390
|
+
onCommit(text);
|
|
12391
|
+
};
|
|
12392
|
+
this.textArea.addEventListener("keydown", (e) => {
|
|
12393
|
+
e.stopPropagation();
|
|
12394
|
+
if (e.code === "Escape") {
|
|
12395
|
+
e.preventDefault();
|
|
12396
|
+
commit(this.textArea?.value ?? "");
|
|
12397
|
+
return;
|
|
12398
|
+
}
|
|
12399
|
+
resizeTextarea();
|
|
12400
|
+
}, { signal: this.instance.getEventsController().signal });
|
|
12401
|
+
this.textArea.addEventListener("keyup", () => resizeTextarea(), { signal: this.instance.getEventsController().signal });
|
|
12402
|
+
this.textArea.addEventListener("input", () => resizeTextarea(), { signal: this.instance.getEventsController().signal });
|
|
12403
|
+
this.textArea.addEventListener("scroll", () => {
|
|
12404
|
+
if (this.textArea) {
|
|
12405
|
+
this.textArea.scrollTop = 0;
|
|
12406
|
+
this.textArea.scrollLeft = 0;
|
|
12407
|
+
}
|
|
12408
|
+
}, { signal: this.instance.getEventsController().signal });
|
|
12409
|
+
const handleOutsideClick = (e) => {
|
|
12410
|
+
e.stopPropagation();
|
|
12411
|
+
if (!this.textArea) return;
|
|
12412
|
+
const mouseX = e.clientX;
|
|
12413
|
+
const mouseY = e.clientY;
|
|
12414
|
+
let elementUnderMouse = document.elementFromPoint(mouseX, mouseY);
|
|
12415
|
+
if (isInShadowDOM(stage.container())) {
|
|
12416
|
+
const shadowHost = getTopmostShadowHost(stage.container());
|
|
12417
|
+
if (shadowHost) elementUnderMouse = shadowHost.elementFromPoint(mouseX, mouseY);
|
|
12418
|
+
}
|
|
12419
|
+
const clickedOutside = elementUnderMouse?.id !== `${group.id()}_label_textarea`;
|
|
12420
|
+
if (clickedOutside) commit(this.textArea.value);
|
|
12421
|
+
};
|
|
12422
|
+
setTimeout(() => {
|
|
12423
|
+
window.addEventListener("pointerup", handleOutsideClick, { signal: this.instance.getEventsController().signal });
|
|
12424
|
+
}, 0);
|
|
12425
|
+
this.textArea.tabIndex = 1;
|
|
12426
|
+
requestAnimationFrame(() => {
|
|
12427
|
+
resizeTextarea();
|
|
12428
|
+
this.textArea?.focus({ preventScroll: true });
|
|
12429
|
+
if (this.textArea?.value) this.textArea.select();
|
|
12430
|
+
});
|
|
12431
|
+
}
|
|
12432
|
+
};
|
|
12433
|
+
|
|
12434
|
+
//#endregion
|
|
12435
|
+
//#region src/nodes/shared/shape-label.utils.ts
|
|
12436
|
+
/**
|
|
12437
|
+
* Returns a partial props object containing only the label-related fields that
|
|
12438
|
+
* are explicitly set on `props`. Spread this into the `props` section of
|
|
12439
|
+
* `addNodeState` / `updateNodeState` to avoid duplicating the 12-field pattern
|
|
12440
|
+
* across every shape node that supports inline text labels.
|
|
12441
|
+
*/
|
|
12442
|
+
function spreadLabelProps(props) {
|
|
12443
|
+
return {
|
|
12444
|
+
...props.labelText !== void 0 && { labelText: props.labelText },
|
|
12445
|
+
...props.labelFontFamily !== void 0 && { labelFontFamily: props.labelFontFamily },
|
|
12446
|
+
...props.labelFontSize !== void 0 && { labelFontSize: props.labelFontSize },
|
|
12447
|
+
...props.labelFontStyle !== void 0 && { labelFontStyle: props.labelFontStyle },
|
|
12448
|
+
...props.labelFontVariant !== void 0 && { labelFontVariant: props.labelFontVariant },
|
|
12449
|
+
...props.labelFill !== void 0 && { labelFill: props.labelFill },
|
|
12450
|
+
...props.labelAlign !== void 0 && { labelAlign: props.labelAlign },
|
|
12451
|
+
...props.labelVerticalAlign !== void 0 && { labelVerticalAlign: props.labelVerticalAlign },
|
|
12452
|
+
...props.labelLetterSpacing !== void 0 && { labelLetterSpacing: props.labelLetterSpacing },
|
|
12453
|
+
...props.labelLineHeight !== void 0 && { labelLineHeight: props.labelLineHeight },
|
|
12454
|
+
...props.labelPaddingX !== void 0 && { labelPaddingX: props.labelPaddingX },
|
|
12455
|
+
...props.labelPaddingY !== void 0 && { labelPaddingY: props.labelPaddingY }
|
|
12456
|
+
};
|
|
12457
|
+
}
|
|
12458
|
+
/**
|
|
12459
|
+
* Returns the shared Zod schema fields for inline text label properties.
|
|
12460
|
+
* Spread the result of this function into a shape node's `props` schema
|
|
12461
|
+
* extension to avoid duplicating the 10-field label schema across rectangle,
|
|
12462
|
+
* ellipse, and any future shape that supports text labels.
|
|
12463
|
+
*/
|
|
12464
|
+
function getShapeLabelSchemaFields() {
|
|
12465
|
+
return {
|
|
12466
|
+
labelText: z.string().optional().describe("Text label displayed inside the shape"),
|
|
12467
|
+
labelFontFamily: z.string().optional().describe("Font family for the label text"),
|
|
12468
|
+
labelFontSize: z.number().optional().describe("Font size for the label text in pixels"),
|
|
12469
|
+
labelFontStyle: z.string().optional().describe("Font style for the label text (e.g. \"normal\", \"bold\", \"italic\", \"bold italic\")"),
|
|
12470
|
+
labelFontVariant: z.string().optional().describe("Font variant for the label text (e.g. \"normal\", \"small-caps\")"),
|
|
12471
|
+
labelFill: z.string().optional().describe("Color of the label text in hex format (e.g. #RRGGBBAA)"),
|
|
12472
|
+
labelAlign: z.string().optional().describe("Horizontal alignment of the label text (\"left\", \"center\", \"right\")"),
|
|
12473
|
+
labelVerticalAlign: z.string().optional().describe("Vertical alignment of the label text (\"top\", \"middle\", \"bottom\")"),
|
|
12474
|
+
labelLetterSpacing: z.number().optional().describe("Letter spacing for the label text in pixels"),
|
|
12475
|
+
labelLineHeight: z.number().optional().describe("Line height multiplier for the label text"),
|
|
12476
|
+
labelPaddingX: z.number().optional().describe("Horizontal inset (padding) in pixels applied on each side of the label"),
|
|
12477
|
+
labelPaddingY: z.number().optional().describe("Vertical inset (padding) in pixels applied on top and bottom of the label")
|
|
12478
|
+
};
|
|
12479
|
+
}
|
|
12480
|
+
/**
|
|
12481
|
+
* Extracts the label node and typography settings from a Konva group.
|
|
12482
|
+
* Returns `null` when the group has no label text or no label Konva.Text child.
|
|
12483
|
+
* Used internally by `computeRectangleLabelMinSize`, `computeEllipseLabelMinSize`,
|
|
12484
|
+
* and `computePolygonLabelMinSize` to avoid duplicating the setup logic.
|
|
12485
|
+
*/
|
|
12486
|
+
function extractLabelNodeContext(group, skipTransformInClientRect = true) {
|
|
12487
|
+
const attrs = group.getAttrs();
|
|
12488
|
+
const labelText = attrs.labelText ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelText;
|
|
12489
|
+
if (!labelText) return null;
|
|
12490
|
+
const labelNode = group.findOne(`#${labelId(group.id())}`);
|
|
12491
|
+
if (!labelNode) return null;
|
|
12492
|
+
const paddingX = attrs.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
12493
|
+
const paddingY = attrs.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12494
|
+
const fontSize = attrs.labelFontSize ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelFontSize;
|
|
12495
|
+
const cloneLabel = labelNode.clone({ visible: false });
|
|
12496
|
+
cloneLabel.height(void 0);
|
|
12497
|
+
const naturalSize = cloneLabel.getClientRect({
|
|
12498
|
+
skipTransform: skipTransformInClientRect,
|
|
12499
|
+
skipShadow: true
|
|
12500
|
+
});
|
|
12501
|
+
return {
|
|
12502
|
+
paddingX,
|
|
12503
|
+
paddingY,
|
|
12504
|
+
fontSize,
|
|
12505
|
+
labelNode,
|
|
12506
|
+
naturalSize
|
|
12507
|
+
};
|
|
12508
|
+
}
|
|
12509
|
+
/**
|
|
12510
|
+
* Returns the minimum bounding size `{ width, height }` (in Konva canvas
|
|
12511
|
+
* units) that the rectangle must have so its label text is fully visible —
|
|
12512
|
+
* no vertical truncation and no horizontal clipping of the widest word.
|
|
12513
|
+
*
|
|
12514
|
+
* Returns `{ width: 0, height: 0 }` when the label is empty.
|
|
12515
|
+
*
|
|
12516
|
+
* @param group - The rectangle `Konva.Group` returned by `onRender`.
|
|
12517
|
+
*/
|
|
12518
|
+
function computeRectangleLabelMinSize(stage, group) {
|
|
12519
|
+
const ctx = extractLabelNodeContext(group);
|
|
12520
|
+
if (!ctx) return {
|
|
12521
|
+
width: 0,
|
|
12522
|
+
height: 0
|
|
12523
|
+
};
|
|
12524
|
+
const { paddingX, paddingY, fontSize, naturalSize } = ctx;
|
|
12525
|
+
return {
|
|
12526
|
+
width: (paddingX * 2 + fontSize) * stage.scaleX(),
|
|
12527
|
+
height: (naturalSize.height + paddingY * 2) * stage.scaleX()
|
|
12528
|
+
};
|
|
12529
|
+
}
|
|
12530
|
+
/**
|
|
12531
|
+
* Returns the minimum bounding box size `{ minWidth, minHeight }` (in Konva
|
|
12532
|
+
* canvas units, i.e. `radiusX * 2` × `radiusY * 2`) that the ellipse must have
|
|
12533
|
+
* so its inscribed label text is fully visible.
|
|
12534
|
+
*
|
|
12535
|
+
* The ellipse label sits inside the largest axis-aligned rectangle inscribed in
|
|
12536
|
+
* the ellipse: `inscribedW = radiusX * √2`, `inscribedH = radiusY * √2`. The
|
|
12537
|
+
* minimum radiusY is back-computed from the text's natural height:
|
|
12538
|
+
* `minRadiusY = ceil(naturalTextH / √2)`
|
|
12539
|
+
*
|
|
12540
|
+
* Returns `{ minWidth: 0, minHeight: 0 }` when the label is empty.
|
|
12541
|
+
*
|
|
12542
|
+
* @param group - The ellipse `Konva.Group` returned by `onRender`.
|
|
12543
|
+
*/
|
|
12544
|
+
function computeEllipseLabelMinSize(stage, group) {
|
|
12545
|
+
const ctx = extractLabelNodeContext(group);
|
|
12546
|
+
if (!ctx) return {
|
|
12547
|
+
width: 0,
|
|
12548
|
+
height: 0
|
|
12549
|
+
};
|
|
12550
|
+
const { paddingX, paddingY, fontSize, naturalSize } = ctx;
|
|
12551
|
+
const minRadiusY = Math.ceil((naturalSize.height + paddingY * 2) / Math.SQRT2);
|
|
12552
|
+
const minRadiusX = Math.ceil((fontSize + paddingX * 2) / Math.SQRT2);
|
|
12553
|
+
return {
|
|
12554
|
+
width: minRadiusX * 2 * stage.scaleX(),
|
|
12555
|
+
height: minRadiusY * 2 * stage.scaleY()
|
|
12556
|
+
};
|
|
12557
|
+
}
|
|
12558
|
+
/**
|
|
12559
|
+
* Returns the minimum bounding-box size `{ width, height }` (in Konva canvas
|
|
12560
|
+
* units) that the polygon node must have so its label text is fully visible.
|
|
12561
|
+
*
|
|
12562
|
+
* The polygon label sits inside the stored `innerRect` attribute. The minimum
|
|
12563
|
+
* size is back-computed from the label text's natural wrapped height and the
|
|
12564
|
+
* current ratio of `innerRect` to the overall bounding box.
|
|
12565
|
+
*
|
|
12566
|
+
* Returns `{ width: 0, height: 0 }` when the label is empty.
|
|
12567
|
+
*
|
|
12568
|
+
* @param group - The polygon `Konva.Group` returned by `onRender`.
|
|
12569
|
+
*/
|
|
12570
|
+
function computePolygonLabelMinSize(stage, group) {
|
|
12571
|
+
const ctx = extractLabelNodeContext(group);
|
|
12572
|
+
if (!ctx) return {
|
|
12573
|
+
width: 0,
|
|
12574
|
+
height: 0
|
|
12575
|
+
};
|
|
12576
|
+
const { paddingX, paddingY, fontSize, naturalSize } = ctx;
|
|
12577
|
+
const attrs = group.getAttrs();
|
|
12578
|
+
const innerRect = attrs.innerRect;
|
|
12579
|
+
if (!innerRect) return {
|
|
12580
|
+
width: 0,
|
|
12581
|
+
height: 0
|
|
12582
|
+
};
|
|
12583
|
+
return {
|
|
12584
|
+
width: (paddingX * 2 + fontSize) * stage.scaleX(),
|
|
12585
|
+
height: (naturalSize.height + paddingY * 2) * stage.scaleX()
|
|
12586
|
+
};
|
|
12587
|
+
}
|
|
12588
|
+
|
|
11978
12589
|
//#endregion
|
|
11979
12590
|
//#region src/nodes/rectangle/rectangle.ts
|
|
11980
12591
|
var WeaveRectangleNode = class extends WeaveNode {
|
|
11981
12592
|
nodeType = WEAVE_RECTANGLE_NODE_TYPE;
|
|
11982
12593
|
initialize = void 0;
|
|
12594
|
+
_transforming = false;
|
|
12595
|
+
get shapeLabelEditor() {
|
|
12596
|
+
return this._shapeLabelEditor ??= new WeaveShapeLabelEditor(this.instance);
|
|
12597
|
+
}
|
|
11983
12598
|
constructor(params) {
|
|
11984
12599
|
super();
|
|
11985
12600
|
const { config } = params ?? {};
|
|
@@ -11988,13 +12603,15 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
11988
12603
|
onRender(props) {
|
|
11989
12604
|
const rectangle = new Konva.Group({
|
|
11990
12605
|
...props,
|
|
12606
|
+
id: `${props.id}`,
|
|
11991
12607
|
name: "node"
|
|
11992
12608
|
});
|
|
11993
12609
|
const internalRectBg = new Konva.Rect({
|
|
11994
12610
|
...props,
|
|
11995
12611
|
name: void 0,
|
|
11996
|
-
|
|
12612
|
+
nodeType: void 0,
|
|
11997
12613
|
nodeId: props.id,
|
|
12614
|
+
id: `${props.id}-bg`,
|
|
11998
12615
|
x: 0,
|
|
11999
12616
|
y: 0,
|
|
12000
12617
|
width: props.width,
|
|
@@ -12009,6 +12626,7 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12009
12626
|
const internalRectBorder = new Konva.Rect({
|
|
12010
12627
|
...props,
|
|
12011
12628
|
name: void 0,
|
|
12629
|
+
nodeType: void 0,
|
|
12012
12630
|
id: `${props.id}-border`,
|
|
12013
12631
|
x: props.strokeWidth / 2,
|
|
12014
12632
|
y: props.strokeWidth / 2,
|
|
@@ -12018,9 +12636,19 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12018
12636
|
strokeWidth: props.strokeWidth || 0,
|
|
12019
12637
|
strokeScaleEnabled: true,
|
|
12020
12638
|
rotation: 0,
|
|
12021
|
-
listening: false
|
|
12639
|
+
listening: false,
|
|
12640
|
+
draggable: false
|
|
12022
12641
|
});
|
|
12023
12642
|
rectangle.add(internalRectBorder);
|
|
12643
|
+
const paddingX = props.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
12644
|
+
const paddingY = props.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12645
|
+
const labelTextBounds = {
|
|
12646
|
+
x: paddingX,
|
|
12647
|
+
y: paddingY,
|
|
12648
|
+
width: Math.max(1, props.width - paddingX * 2),
|
|
12649
|
+
height: Math.max(1, props.height - paddingY * 2)
|
|
12650
|
+
};
|
|
12651
|
+
this.shapeLabelEditor.renderLabel(rectangle, props, labelTextBounds);
|
|
12024
12652
|
internalRectBorder.moveToTop();
|
|
12025
12653
|
internalRectBg.moveToBottom();
|
|
12026
12654
|
this.setupDefaultNodeAugmentation(rectangle);
|
|
@@ -12029,6 +12657,51 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12029
12657
|
return defaultTransformerProperties;
|
|
12030
12658
|
};
|
|
12031
12659
|
this.setupDefaultNodeEvents(rectangle);
|
|
12660
|
+
rectangle.on("transformstart", () => {
|
|
12661
|
+
this._transforming = true;
|
|
12662
|
+
});
|
|
12663
|
+
rectangle.on("transform", () => {
|
|
12664
|
+
this.scaleReset(rectangle);
|
|
12665
|
+
this.onUpdate(rectangle, rectangle.getAttrs());
|
|
12666
|
+
});
|
|
12667
|
+
rectangle.on("transformend", () => {
|
|
12668
|
+
this._transforming = false;
|
|
12669
|
+
});
|
|
12670
|
+
rectangle.dblClick = () => {
|
|
12671
|
+
if (this.shapeLabelEditor.isEditing()) return;
|
|
12672
|
+
if (!(this.isSelecting() && this.isNodeSelected(rectangle))) return;
|
|
12673
|
+
const onCommit = (labelText) => {
|
|
12674
|
+
const updatedGroup = this.instance.getStage().findOne(`#${props.id}`);
|
|
12675
|
+
if (!updatedGroup) return;
|
|
12676
|
+
const serialized = this.serialize(updatedGroup);
|
|
12677
|
+
serialized.props.labelText = labelText;
|
|
12678
|
+
this.instance.updateNode(serialized);
|
|
12679
|
+
};
|
|
12680
|
+
const currentAttrs = rectangle.getAttrs();
|
|
12681
|
+
const curPaddingX = currentAttrs.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
12682
|
+
const curPaddingY = currentAttrs.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12683
|
+
const currentLabelTextBounds = {
|
|
12684
|
+
x: curPaddingX,
|
|
12685
|
+
y: curPaddingY,
|
|
12686
|
+
width: Math.max(1, (currentAttrs.width ?? 0) - curPaddingX * 2),
|
|
12687
|
+
height: Math.max(1, (currentAttrs.height ?? 0) - curPaddingY * 2)
|
|
12688
|
+
};
|
|
12689
|
+
const originalHeight = currentAttrs.height ?? 0;
|
|
12690
|
+
this.shapeLabelEditor.triggerEditMode(rectangle, currentLabelTextBounds, onCommit, (neededShapeHeight) => {
|
|
12691
|
+
const finalHeight = Math.max(neededShapeHeight, originalHeight);
|
|
12692
|
+
const liveAttrs = rectangle.getAttrs();
|
|
12693
|
+
const strokeW = liveAttrs.strokeWidth || 0;
|
|
12694
|
+
const bg = rectangle.findOne(`#${liveAttrs.id}-bg`);
|
|
12695
|
+
const border = rectangle.findOne(`#${liveAttrs.id}-border`);
|
|
12696
|
+
rectangle.setAttrs({ height: finalHeight });
|
|
12697
|
+
bg?.setAttrs({ height: finalHeight });
|
|
12698
|
+
border?.setAttrs({ height: Math.max(0, finalHeight - strokeW) });
|
|
12699
|
+
rectangle.getLayer()?.batchDraw();
|
|
12700
|
+
});
|
|
12701
|
+
};
|
|
12702
|
+
rectangle.getNodeMinSize = () => {
|
|
12703
|
+
return computeRectangleLabelMinSize(this.instance.getStage(), rectangle);
|
|
12704
|
+
};
|
|
12032
12705
|
return rectangle;
|
|
12033
12706
|
}
|
|
12034
12707
|
onUpdate(nodeInstance, nextProps) {
|
|
@@ -12058,6 +12731,7 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12058
12731
|
internalRectBorder.setAttrs({
|
|
12059
12732
|
...nextProps,
|
|
12060
12733
|
name: void 0,
|
|
12734
|
+
fill: "transparent",
|
|
12061
12735
|
id: `${nextProps.id}-border`,
|
|
12062
12736
|
x: nextProps.strokeWidth / 2,
|
|
12063
12737
|
y: nextProps.strokeWidth / 2,
|
|
@@ -12071,6 +12745,26 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12071
12745
|
});
|
|
12072
12746
|
internalRectBorder.moveToTop();
|
|
12073
12747
|
}
|
|
12748
|
+
const paddingX = nextProps.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
12749
|
+
const paddingY = nextProps.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12750
|
+
const labelTextBounds = {
|
|
12751
|
+
x: paddingX,
|
|
12752
|
+
y: paddingY,
|
|
12753
|
+
width: Math.max(1, nextProps.width - paddingX * 2),
|
|
12754
|
+
height: Math.max(1, nextProps.height - paddingY * 2)
|
|
12755
|
+
};
|
|
12756
|
+
this.shapeLabelEditor.updateLabel(rectangle, nextProps, labelTextBounds, (neededShapeHeight) => {
|
|
12757
|
+
nodeInstance.setAttrs({ height: neededShapeHeight });
|
|
12758
|
+
internalRectBg?.setAttrs({ height: neededShapeHeight });
|
|
12759
|
+
internalRectBorder?.setAttrs({ height: neededShapeHeight - nextProps.strokeWidth });
|
|
12760
|
+
if (!this._transforming) this.instance.updateNode(this.serialize(nodeInstance));
|
|
12761
|
+
});
|
|
12762
|
+
const labelNode = rectangle.findOne(`#${labelId(nextProps.id ?? "")}`);
|
|
12763
|
+
if (labelNode) {
|
|
12764
|
+
labelNode.moveToTop();
|
|
12765
|
+
internalRectBg?.moveToBottom();
|
|
12766
|
+
internalRectBorder?.moveToTop();
|
|
12767
|
+
}
|
|
12074
12768
|
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
12075
12769
|
if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
12076
12770
|
}
|
|
@@ -12091,7 +12785,8 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12091
12785
|
strokeScaleEnabled: true,
|
|
12092
12786
|
rotation: 0,
|
|
12093
12787
|
zIndex: 1,
|
|
12094
|
-
children: []
|
|
12788
|
+
children: [],
|
|
12789
|
+
...WEAVE_SHAPE_LABEL_DEFAULTS
|
|
12095
12790
|
}
|
|
12096
12791
|
};
|
|
12097
12792
|
}
|
|
@@ -12104,7 +12799,8 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12104
12799
|
rotation: props.rotation,
|
|
12105
12800
|
fill: props.fill,
|
|
12106
12801
|
...props.stroke && { stroke: props.stroke },
|
|
12107
|
-
...props.strokeWidth && { strokeWidth: props.strokeWidth }
|
|
12802
|
+
...props.strokeWidth && { strokeWidth: props.strokeWidth },
|
|
12803
|
+
...spreadLabelProps(props)
|
|
12108
12804
|
} });
|
|
12109
12805
|
}
|
|
12110
12806
|
static updateNodeState(prevNodeState, nextProps) {
|
|
@@ -12116,7 +12812,8 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12116
12812
|
rotation: nextProps.rotation,
|
|
12117
12813
|
fill: nextProps.fill,
|
|
12118
12814
|
...nextProps.stroke && { stroke: nextProps.stroke },
|
|
12119
|
-
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth }
|
|
12815
|
+
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth },
|
|
12816
|
+
...spreadLabelProps(nextProps)
|
|
12120
12817
|
} });
|
|
12121
12818
|
}
|
|
12122
12819
|
static getSchema() {
|
|
@@ -12130,7 +12827,8 @@ var WeaveRectangleNode = class extends WeaveNode {
|
|
|
12130
12827
|
fill: z.string().describe("Fill color of the rectangle in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
12131
12828
|
stroke: z.string().describe("Stroke color of the rectangle in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
12132
12829
|
strokeWidth: z.number().describe("Stroke width of the rectangle in pixels"),
|
|
12133
|
-
strokeScaleEnabled: z.boolean().describe("Whether the rectangle stroke width should scale when the node is scaled. Defaults to true.")
|
|
12830
|
+
strokeScaleEnabled: z.boolean().describe("Whether the rectangle stroke width should scale when the node is scaled. Defaults to true."),
|
|
12831
|
+
...getShapeLabelSchemaFields()
|
|
12134
12832
|
})
|
|
12135
12833
|
});
|
|
12136
12834
|
return nodeSchema;
|
|
@@ -12146,11 +12844,25 @@ const WEAVE_ELLIPSE_NODE_TYPE = "ellipse";
|
|
|
12146
12844
|
var WeaveEllipseNode = class extends WeaveNode {
|
|
12147
12845
|
nodeType = WEAVE_ELLIPSE_NODE_TYPE;
|
|
12148
12846
|
initialize = void 0;
|
|
12847
|
+
_transforming = false;
|
|
12848
|
+
get shapeLabelEditor() {
|
|
12849
|
+
return this._shapeLabelEditor ??= new WeaveShapeLabelEditor(this.instance);
|
|
12850
|
+
}
|
|
12149
12851
|
constructor(params) {
|
|
12150
12852
|
super();
|
|
12151
12853
|
const { config } = params ?? {};
|
|
12152
12854
|
this.config = { transform: { ...config?.transform } };
|
|
12153
12855
|
}
|
|
12856
|
+
getLabelTextBounds(radiusX, radiusY, paddingX, paddingY) {
|
|
12857
|
+
const inscribedW = radiusX * Math.SQRT2;
|
|
12858
|
+
const inscribedH = radiusY * Math.SQRT2;
|
|
12859
|
+
return {
|
|
12860
|
+
x: radiusX - inscribedW / 2 + paddingX,
|
|
12861
|
+
y: radiusY - inscribedH / 2 + paddingY,
|
|
12862
|
+
width: Math.max(1, inscribedW - paddingX * 2),
|
|
12863
|
+
height: Math.max(1, inscribedH - paddingY * 2)
|
|
12864
|
+
};
|
|
12865
|
+
}
|
|
12154
12866
|
onRender(props) {
|
|
12155
12867
|
const ellipse = new Konva.Group({
|
|
12156
12868
|
...props,
|
|
@@ -12188,6 +12900,10 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12188
12900
|
listening: false
|
|
12189
12901
|
});
|
|
12190
12902
|
ellipse.add(internalEllipseBorder);
|
|
12903
|
+
const paddingX = props.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
12904
|
+
const paddingY = props.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12905
|
+
const labelTextBounds = this.getLabelTextBounds(Math.max(1, baseRadiusX), Math.max(1, baseRadiusY), paddingX, paddingY);
|
|
12906
|
+
this.shapeLabelEditor.renderLabel(ellipse, props, labelTextBounds);
|
|
12191
12907
|
internalEllipseBorder.moveToTop();
|
|
12192
12908
|
internalEllipseBg.moveToBottom();
|
|
12193
12909
|
this.setupDefaultNodeAugmentation(ellipse);
|
|
@@ -12226,6 +12942,56 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12226
12942
|
];
|
|
12227
12943
|
};
|
|
12228
12944
|
this.setupDefaultNodeEvents(ellipse);
|
|
12945
|
+
ellipse.on("transformstart", () => {
|
|
12946
|
+
this._transforming = true;
|
|
12947
|
+
});
|
|
12948
|
+
ellipse.on("transform", () => {
|
|
12949
|
+
this.scaleReset(ellipse);
|
|
12950
|
+
this.onUpdate(ellipse, ellipse.getAttrs());
|
|
12951
|
+
});
|
|
12952
|
+
ellipse.on("transformend", () => {
|
|
12953
|
+
this._transforming = false;
|
|
12954
|
+
});
|
|
12955
|
+
ellipse.dblClick = () => {
|
|
12956
|
+
if (this.shapeLabelEditor.isEditing()) return;
|
|
12957
|
+
if (!(this.isSelecting() && this.isNodeSelected(ellipse))) return;
|
|
12958
|
+
const onCommit = (labelText) => {
|
|
12959
|
+
const updatedGroup = this.instance.getStage().findOne(`#${props.id}`);
|
|
12960
|
+
if (!updatedGroup) return;
|
|
12961
|
+
const serialized = this.serialize(updatedGroup);
|
|
12962
|
+
serialized.props.labelText = labelText;
|
|
12963
|
+
this.instance.updateNode(serialized);
|
|
12964
|
+
};
|
|
12965
|
+
const currentAttrs = ellipse.getAttrs();
|
|
12966
|
+
const curPaddingX = currentAttrs.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
12967
|
+
const curPaddingY = currentAttrs.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
12968
|
+
const currentRadiusX = Math.max(1, currentAttrs.radiusX);
|
|
12969
|
+
const currentRadiusY = Math.max(1, currentAttrs.radiusY);
|
|
12970
|
+
const currentLabelTextBounds = this.getLabelTextBounds(currentRadiusX, currentRadiusY, curPaddingX, curPaddingY);
|
|
12971
|
+
const originalRadiusY = currentRadiusY;
|
|
12972
|
+
const originalNeededHeight = currentLabelTextBounds.height + curPaddingY * 2;
|
|
12973
|
+
this.shapeLabelEditor.triggerEditMode(ellipse, currentLabelTextBounds, onCommit, (neededShapeHeight) => {
|
|
12974
|
+
const newRadiusY = neededShapeHeight <= originalNeededHeight ? originalRadiusY : Math.ceil(neededShapeHeight / Math.SQRT2);
|
|
12975
|
+
const liveAttrs = ellipse.getAttrs();
|
|
12976
|
+
const strokeW = liveAttrs.strokeWidth || 0;
|
|
12977
|
+
const bg = ellipse.findOne(`#${liveAttrs.id}-bg`);
|
|
12978
|
+
const border = ellipse.findOne(`#${liveAttrs.id}-border`);
|
|
12979
|
+
ellipse.setAttrs({ radiusY: newRadiusY });
|
|
12980
|
+
bg?.setAttrs({
|
|
12981
|
+
radiusY: Math.max(1, newRadiusY),
|
|
12982
|
+
y: Math.max(1, newRadiusY)
|
|
12983
|
+
});
|
|
12984
|
+
border?.setAttrs({
|
|
12985
|
+
radiusY: Math.max(1, newRadiusY) - strokeW / 2,
|
|
12986
|
+
y: Math.max(1, newRadiusY)
|
|
12987
|
+
});
|
|
12988
|
+
const newLabelTextBounds = this.getLabelTextBounds(currentRadiusX, newRadiusY, curPaddingX, curPaddingY);
|
|
12989
|
+
this.shapeLabelEditor.repositionTextArea(ellipse, newLabelTextBounds);
|
|
12990
|
+
});
|
|
12991
|
+
};
|
|
12992
|
+
ellipse.getNodeMinSize = () => {
|
|
12993
|
+
return computeEllipseLabelMinSize(this.instance.getStage(), ellipse);
|
|
12994
|
+
};
|
|
12229
12995
|
return ellipse;
|
|
12230
12996
|
}
|
|
12231
12997
|
onUpdate(nodeInstance, nextProps) {
|
|
@@ -12263,12 +13029,34 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12263
13029
|
radiusY: Math.max(1, baseRadiusY) - (nextProps.strokeWidth || 0) / 2,
|
|
12264
13030
|
stroke: nextProps.stroke || "transparent",
|
|
12265
13031
|
strokeWidth: nextProps.strokeWidth || 0,
|
|
13032
|
+
fill: "transparent",
|
|
12266
13033
|
strokeScaleEnabled: true,
|
|
12267
13034
|
listening: false,
|
|
12268
13035
|
rotation: 0
|
|
12269
13036
|
});
|
|
12270
13037
|
internalEllipseBorder.moveToTop();
|
|
12271
13038
|
}
|
|
13039
|
+
const paddingX = nextProps.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
13040
|
+
const paddingY = nextProps.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
13041
|
+
const labelTextBounds = this.getLabelTextBounds(Math.max(1, baseRadiusX), Math.max(1, baseRadiusY), paddingX, paddingY);
|
|
13042
|
+
this.shapeLabelEditor.updateLabel(ellipse, nextProps, labelTextBounds, (neededHeight) => {
|
|
13043
|
+
const newRadiusY = Math.ceil(neededHeight / Math.SQRT2);
|
|
13044
|
+
nodeInstance.setAttrs({ radiusY: newRadiusY });
|
|
13045
|
+
internalEllipseBg?.setAttrs({
|
|
13046
|
+
radiusY: Math.max(1, newRadiusY),
|
|
13047
|
+
y: Math.max(1, newRadiusY)
|
|
13048
|
+
});
|
|
13049
|
+
internalEllipseBorder?.setAttrs({
|
|
13050
|
+
radiusY: Math.max(1, newRadiusY) - (nextProps.strokeWidth || 0) / 2,
|
|
13051
|
+
y: Math.max(1, newRadiusY)
|
|
13052
|
+
});
|
|
13053
|
+
if (!this._transforming) this.instance.updateNode(this.serialize(nodeInstance));
|
|
13054
|
+
});
|
|
13055
|
+
const labelNode = ellipse.findOne(`#${labelId(nextProps.id)}`);
|
|
13056
|
+
if (labelNode) {
|
|
13057
|
+
labelNode.moveToTop();
|
|
13058
|
+
internalEllipseBorder?.moveToTop();
|
|
13059
|
+
}
|
|
12272
13060
|
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
12273
13061
|
if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
12274
13062
|
}
|
|
@@ -12311,7 +13099,8 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12311
13099
|
strokeScaleEnabled: true,
|
|
12312
13100
|
rotation: 0,
|
|
12313
13101
|
zIndex: 1,
|
|
12314
|
-
children: []
|
|
13102
|
+
children: [],
|
|
13103
|
+
...WEAVE_SHAPE_LABEL_DEFAULTS
|
|
12315
13104
|
}
|
|
12316
13105
|
};
|
|
12317
13106
|
}
|
|
@@ -12324,7 +13113,8 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12324
13113
|
rotation: props.rotation,
|
|
12325
13114
|
fill: props.fill,
|
|
12326
13115
|
...props.stroke && { stroke: props.stroke },
|
|
12327
|
-
...props.strokeWidth && { strokeWidth: props.strokeWidth }
|
|
13116
|
+
...props.strokeWidth && { strokeWidth: props.strokeWidth },
|
|
13117
|
+
...spreadLabelProps(props)
|
|
12328
13118
|
} });
|
|
12329
13119
|
}
|
|
12330
13120
|
static updateNodeState(prevNodeState, nextProps) {
|
|
@@ -12336,7 +13126,8 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12336
13126
|
rotation: nextProps.rotation,
|
|
12337
13127
|
fill: nextProps.fill,
|
|
12338
13128
|
...nextProps.stroke && { stroke: nextProps.stroke },
|
|
12339
|
-
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth }
|
|
13129
|
+
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth },
|
|
13130
|
+
...spreadLabelProps(nextProps)
|
|
12340
13131
|
} });
|
|
12341
13132
|
}
|
|
12342
13133
|
static getSchema() {
|
|
@@ -12350,7 +13141,8 @@ var WeaveEllipseNode = class extends WeaveNode {
|
|
|
12350
13141
|
fill: z.string().describe("Fill color of the ellipse in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
12351
13142
|
stroke: z.string().describe("Stroke color of the ellipse in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
12352
13143
|
strokeWidth: z.number().describe("Stroke width of the ellipse in pixels"),
|
|
12353
|
-
strokeScaleEnabled: z.boolean().describe("Whether the ellipse stroke width should scale when the node is scaled. Defaults to true.")
|
|
13144
|
+
strokeScaleEnabled: z.boolean().describe("Whether the ellipse stroke width should scale when the node is scaled. Defaults to true."),
|
|
13145
|
+
...getShapeLabelSchemaFields()
|
|
12354
13146
|
})
|
|
12355
13147
|
});
|
|
12356
13148
|
return nodeSchema;
|
|
@@ -12728,7 +13520,8 @@ const WEAVE_STAGE_TEXT_EDITION_MODE = "text-edition";
|
|
|
12728
13520
|
const WEAVE_TEXT_NODE_DEFAULT_CONFIG = {
|
|
12729
13521
|
transform: { ...WEAVE_NODES_SELECTION_DEFAULT_CONFIG.selection },
|
|
12730
13522
|
outline: { enabled: false },
|
|
12731
|
-
cursor: { color: "#000000" }
|
|
13523
|
+
cursor: { color: "#000000" },
|
|
13524
|
+
edition: { borderSize: 2 }
|
|
12732
13525
|
};
|
|
12733
13526
|
const TEXT_LAYOUT = {
|
|
12734
13527
|
["SMART"]: "smart",
|
|
@@ -13024,7 +13817,8 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13024
13817
|
if (!this.textArea || !this.textAreaContainer) return;
|
|
13025
13818
|
if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.SMART && !textNode.getAttrs().smartFixedWidth) {
|
|
13026
13819
|
const { width: textAreaWidth } = this.textRenderedSize(this.textArea.value, textNode);
|
|
13027
|
-
const
|
|
13820
|
+
const borderSize = this.config.edition.borderSize;
|
|
13821
|
+
const width = (textAreaWidth + borderSize * 2) * textNode.getAbsoluteScale().x / this.instance.getStage().scaleX();
|
|
13028
13822
|
this.textAreaContainer.style.width = width + "px";
|
|
13029
13823
|
}
|
|
13030
13824
|
if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.SMART) {
|
|
@@ -13123,13 +13917,15 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13123
13917
|
this.textAreaContainer.style.top = position.y * upscaleScale + "px";
|
|
13124
13918
|
this.textAreaContainer.style.left = position.x * upscaleScale + "px";
|
|
13125
13919
|
if (textNode.getAttrs().layout === TEXT_LAYOUT.SMART && !textNode.getAttrs().smartFixedWidth) {
|
|
13920
|
+
const borderSize$1 = this.config.edition.borderSize;
|
|
13126
13921
|
const rect = textNode.getClientRect({ relativeTo: stage });
|
|
13127
|
-
this.textAreaContainer.style.width = (rect.width + 2) * textNode.getAbsoluteScale().x + "px";
|
|
13922
|
+
this.textAreaContainer.style.width = (rect.width + borderSize$1 * 2) * textNode.getAbsoluteScale().x + "px";
|
|
13128
13923
|
this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
|
|
13129
13924
|
}
|
|
13130
13925
|
if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL) {
|
|
13926
|
+
const borderSize$1 = this.config.edition.borderSize;
|
|
13131
13927
|
const rect = textNode.getClientRect({ relativeTo: stage });
|
|
13132
|
-
this.textAreaContainer.style.width = (rect.width + 2) * textNode.getAbsoluteScale().x + "px";
|
|
13928
|
+
this.textAreaContainer.style.width = (rect.width + borderSize$1 * 2) * textNode.getAbsoluteScale().x + "px";
|
|
13133
13929
|
this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
|
|
13134
13930
|
}
|
|
13135
13931
|
if (textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.SMART && textNode.getAttrs().smartFixedWidth) {
|
|
@@ -13142,7 +13938,9 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13142
13938
|
this.textAreaContainer.style.width = (textNode.width() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
|
|
13143
13939
|
this.textAreaContainer.style.height = (textNode.height() - textNode.padding() * 2) * textNode.getAbsoluteScale().x + "px";
|
|
13144
13940
|
}
|
|
13145
|
-
this.
|
|
13941
|
+
const size = this.textRenderedSize(textNode.text(), textNode);
|
|
13942
|
+
const borderSize = this.config.edition.borderSize;
|
|
13943
|
+
this.textAreaContainer.style.border = `solid ${borderSize}px #1e40af`;
|
|
13146
13944
|
this.textArea.style.position = "absolute";
|
|
13147
13945
|
this.textArea.style.top = "0px";
|
|
13148
13946
|
this.textArea.style.left = "0px";
|
|
@@ -13151,11 +13949,12 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13151
13949
|
this.textArea.style.scrollBehavior = "auto";
|
|
13152
13950
|
this.textArea.style.caretColor = "black";
|
|
13153
13951
|
this.textArea.style.width = "100%";
|
|
13952
|
+
this.textArea.style.height = `${size.height}px`;
|
|
13154
13953
|
this.textArea.style.minHeight = "auto";
|
|
13155
13954
|
this.textArea.style.margin = "0px";
|
|
13156
13955
|
this.textArea.style.padding = "0px";
|
|
13157
13956
|
this.textArea.style.paddingTop = "0px";
|
|
13158
|
-
this.textArea.style.boxSizing = "
|
|
13957
|
+
this.textArea.style.boxSizing = "content-box";
|
|
13159
13958
|
this.textArea.style.overflow = "hidden";
|
|
13160
13959
|
this.textArea.style.background = "transparent";
|
|
13161
13960
|
this.textArea.style.border = "none";
|
|
@@ -13169,8 +13968,8 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13169
13968
|
this.textArea.style.backgroundColor = "transparent";
|
|
13170
13969
|
this.textAreaContainer.style.transformOrigin = "left top";
|
|
13171
13970
|
this.mimicTextNode(textNode);
|
|
13172
|
-
this.textArea.style.left =
|
|
13173
|
-
this.textArea.style.top =
|
|
13971
|
+
this.textArea.style.left = `${-borderSize}px`;
|
|
13972
|
+
this.textArea.style.top = `${-borderSize + (size.height - this.textArea.offsetHeight)}px`;
|
|
13174
13973
|
this.textArea.onfocus = () => {
|
|
13175
13974
|
this.textAreaDomResize(textNode);
|
|
13176
13975
|
};
|
|
@@ -13216,7 +14015,10 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13216
14015
|
const width = textAreaWidth / this.instance.getStage().scaleX();
|
|
13217
14016
|
textNode.width(width);
|
|
13218
14017
|
}
|
|
13219
|
-
if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.SMART)
|
|
14018
|
+
if (!textNode.getAttrs().layout || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_HEIGHT || textNode.getAttrs().layout === TEXT_LAYOUT.AUTO_ALL || textNode.getAttrs().layout === TEXT_LAYOUT.SMART) {
|
|
14019
|
+
const size$1 = this.textRenderedSize(this.textArea.value, textNode);
|
|
14020
|
+
textNode.height(size$1.height * (1 / textNode.getAbsoluteScale().x));
|
|
14021
|
+
}
|
|
13220
14022
|
};
|
|
13221
14023
|
const handleKeyDown = (e) => {
|
|
13222
14024
|
if (this.textArea && textNode && e.code === "Escape") {
|
|
@@ -15107,6 +15909,7 @@ var WeaveImageNode = class extends WeaveNode {
|
|
|
15107
15909
|
x: 1,
|
|
15108
15910
|
y: 1
|
|
15109
15911
|
});
|
|
15912
|
+
this.updateImageCrop(node);
|
|
15110
15913
|
}
|
|
15111
15914
|
getIsAsync() {
|
|
15112
15915
|
return true;
|
|
@@ -15618,127 +16421,975 @@ var WeaveRegularPolygonNode = class extends WeaveNode {
|
|
|
15618
16421
|
rotation: 0,
|
|
15619
16422
|
listening: false
|
|
15620
16423
|
});
|
|
15621
|
-
const internalRPBorderBox = internalRPBorder.getClientRect({ relativeTo: regularPolygon });
|
|
15622
|
-
internalRPBorder.x(internalRPBorder.x() - internalRPBorderBox.x);
|
|
15623
|
-
internalRPBorder.y(internalRPBorder.y() - internalRPBorderBox.y);
|
|
15624
|
-
regularPolygon.add(internalRPBorder);
|
|
15625
|
-
internalRPBorder.moveToTop();
|
|
15626
|
-
internalRPBg.moveToBottom();
|
|
15627
|
-
this.setupDefaultNodeAugmentation(regularPolygon);
|
|
16424
|
+
const internalRPBorderBox = internalRPBorder.getClientRect({ relativeTo: regularPolygon });
|
|
16425
|
+
internalRPBorder.x(internalRPBorder.x() - internalRPBorderBox.x);
|
|
16426
|
+
internalRPBorder.y(internalRPBorder.y() - internalRPBorderBox.y);
|
|
16427
|
+
regularPolygon.add(internalRPBorder);
|
|
16428
|
+
internalRPBorder.moveToTop();
|
|
16429
|
+
internalRPBg.moveToBottom();
|
|
16430
|
+
this.setupDefaultNodeAugmentation(regularPolygon);
|
|
16431
|
+
const defaultTransformerProperties = this.defaultGetTransformerProperties(this.config.transform);
|
|
16432
|
+
regularPolygon.getTransformerProperties = function() {
|
|
16433
|
+
return {
|
|
16434
|
+
...defaultTransformerProperties,
|
|
16435
|
+
enabledAnchors: [
|
|
16436
|
+
"top-left",
|
|
16437
|
+
"top-right",
|
|
16438
|
+
"bottom-left",
|
|
16439
|
+
"bottom-right"
|
|
16440
|
+
],
|
|
16441
|
+
keepRatio: true
|
|
16442
|
+
};
|
|
16443
|
+
};
|
|
16444
|
+
regularPolygon.allowedAnchors = function() {
|
|
16445
|
+
return [
|
|
16446
|
+
"top-left",
|
|
16447
|
+
"top-right",
|
|
16448
|
+
"bottom-left",
|
|
16449
|
+
"bottom-right"
|
|
16450
|
+
];
|
|
16451
|
+
};
|
|
16452
|
+
this.setupDefaultNodeEvents(regularPolygon);
|
|
16453
|
+
return regularPolygon;
|
|
16454
|
+
}
|
|
16455
|
+
onUpdate(nodeInstance, nextProps) {
|
|
16456
|
+
nodeInstance.setAttrs({ ...nextProps });
|
|
16457
|
+
const sides = nodeInstance.getAttr("sides");
|
|
16458
|
+
const radius = nodeInstance.getAttr("radius");
|
|
16459
|
+
const regularPolygon = nodeInstance;
|
|
16460
|
+
const internalRPBg = regularPolygon.findOne(`#${nextProps.id}-bg`);
|
|
16461
|
+
const internalRPBorder = regularPolygon.findOne(`#${nextProps.id}-border`);
|
|
16462
|
+
if (internalRPBg) {
|
|
16463
|
+
internalRPBg.setAttrs({
|
|
16464
|
+
...nextProps,
|
|
16465
|
+
name: void 0,
|
|
16466
|
+
id: `${nextProps.id}-bg`,
|
|
16467
|
+
nodeId: nextProps.id,
|
|
16468
|
+
x: radius,
|
|
16469
|
+
y: radius,
|
|
16470
|
+
sides,
|
|
16471
|
+
radius,
|
|
16472
|
+
fill: nextProps.fill || "transparent",
|
|
16473
|
+
strokeWidth: 0,
|
|
16474
|
+
strokeScaleEnabled: true,
|
|
16475
|
+
rotation: 0
|
|
16476
|
+
});
|
|
16477
|
+
const internalRPBgBox = internalRPBg.getClientRect({ relativeTo: regularPolygon });
|
|
16478
|
+
internalRPBg.x(internalRPBg.x() - internalRPBgBox.x);
|
|
16479
|
+
internalRPBg.y(internalRPBg.y() - internalRPBgBox.y);
|
|
16480
|
+
internalRPBg.moveToBottom();
|
|
16481
|
+
}
|
|
16482
|
+
if (internalRPBorder) {
|
|
16483
|
+
internalRPBorder.setAttrs({
|
|
16484
|
+
...nextProps,
|
|
16485
|
+
name: void 0,
|
|
16486
|
+
id: `${nextProps.id}-border`,
|
|
16487
|
+
x: radius,
|
|
16488
|
+
y: radius,
|
|
16489
|
+
sides,
|
|
16490
|
+
radius: radius - (nextProps.strokeWidth || 0) / 2,
|
|
16491
|
+
stroke: nextProps.stroke || "transparent",
|
|
16492
|
+
strokeWidth: nextProps.strokeWidth || 0,
|
|
16493
|
+
strokeScaleEnabled: true,
|
|
16494
|
+
fill: "transparent",
|
|
16495
|
+
listening: false,
|
|
16496
|
+
rotation: 0
|
|
16497
|
+
});
|
|
16498
|
+
const internalRPBorderBox = internalRPBorder.getClientRect({ relativeTo: regularPolygon });
|
|
16499
|
+
internalRPBorder.x(internalRPBorder.x() - internalRPBorderBox.x);
|
|
16500
|
+
internalRPBorder.y(internalRPBorder.y() - internalRPBorderBox.y);
|
|
16501
|
+
internalRPBorder.moveToTop();
|
|
16502
|
+
}
|
|
16503
|
+
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
16504
|
+
if (nodesSelectionPlugin) {
|
|
16505
|
+
const actualSelectedNodes = nodesSelectionPlugin.getSelectedNodes();
|
|
16506
|
+
nodesSelectionPlugin.setSelectedNodes(actualSelectedNodes);
|
|
16507
|
+
nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
16508
|
+
}
|
|
16509
|
+
}
|
|
16510
|
+
scaleReset(node) {
|
|
16511
|
+
const absTransform = node.getAbsoluteTransform().copy();
|
|
16512
|
+
const radius = node.getAttr("radius");
|
|
16513
|
+
node.setAttrs({ radius: radius * node.scaleX() });
|
|
16514
|
+
node.scaleX(1);
|
|
16515
|
+
node.scaleY(1);
|
|
16516
|
+
const newTransform = node.getAbsoluteTransform();
|
|
16517
|
+
const dx = absTransform.m[4] - newTransform.m[4];
|
|
16518
|
+
const dy = absTransform.m[5] - newTransform.m[5];
|
|
16519
|
+
node.x(node.x() + dx);
|
|
16520
|
+
node.y(node.y() + dy);
|
|
16521
|
+
}
|
|
16522
|
+
realOffset(element) {
|
|
16523
|
+
return {
|
|
16524
|
+
x: element.props.radius,
|
|
16525
|
+
y: element.props.radius
|
|
16526
|
+
};
|
|
16527
|
+
}
|
|
16528
|
+
static defaultState(nodeId) {
|
|
16529
|
+
return {
|
|
16530
|
+
...super.defaultState(nodeId),
|
|
16531
|
+
type: WEAVE_REGULAR_POLYGON_NODE_TYPE,
|
|
16532
|
+
props: {
|
|
16533
|
+
...super.defaultState(nodeId).props,
|
|
16534
|
+
nodeType: WEAVE_REGULAR_POLYGON_NODE_TYPE,
|
|
16535
|
+
x: 0,
|
|
16536
|
+
y: 0,
|
|
16537
|
+
sides: 5,
|
|
16538
|
+
radius: 100,
|
|
16539
|
+
stroke: "#000000",
|
|
16540
|
+
fill: "#FFFFFF",
|
|
16541
|
+
strokeWidth: 1,
|
|
16542
|
+
strokeScaleEnabled: true,
|
|
16543
|
+
rotation: 0,
|
|
16544
|
+
zIndex: 1,
|
|
16545
|
+
children: []
|
|
16546
|
+
}
|
|
16547
|
+
};
|
|
16548
|
+
}
|
|
16549
|
+
static addNodeState(defaultNodeState, props) {
|
|
16550
|
+
return mergeExceptArrays(defaultNodeState, { props: {
|
|
16551
|
+
x: props.x,
|
|
16552
|
+
y: props.y,
|
|
16553
|
+
sides: props.sides,
|
|
16554
|
+
radius: props.radius,
|
|
16555
|
+
rotation: props.rotation,
|
|
16556
|
+
fill: props.fill,
|
|
16557
|
+
...props.stroke && { stroke: props.stroke },
|
|
16558
|
+
...props.strokeWidth && { strokeWidth: props.strokeWidth }
|
|
16559
|
+
} });
|
|
16560
|
+
}
|
|
16561
|
+
static updateNodeState(prevNodeState, nextProps) {
|
|
16562
|
+
return mergeExceptArrays(prevNodeState, { props: {
|
|
16563
|
+
x: nextProps.x,
|
|
16564
|
+
y: nextProps.y,
|
|
16565
|
+
sides: nextProps.sides,
|
|
16566
|
+
radius: nextProps.radius,
|
|
16567
|
+
rotation: nextProps.rotation,
|
|
16568
|
+
fill: nextProps.fill,
|
|
16569
|
+
...nextProps.stroke && { stroke: nextProps.stroke },
|
|
16570
|
+
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth }
|
|
16571
|
+
} });
|
|
16572
|
+
}
|
|
16573
|
+
static getSchema() {
|
|
16574
|
+
const baseSchema = super.getSchema();
|
|
16575
|
+
const nodeSchema = baseSchema.extend({
|
|
16576
|
+
type: z.literal(WEAVE_REGULAR_POLYGON_NODE_TYPE).describe(`Type of the node, for a regular polygon node it will always be "${WEAVE_REGULAR_POLYGON_NODE_TYPE}"`),
|
|
16577
|
+
props: baseSchema.shape.props.extend({
|
|
16578
|
+
nodeType: z.literal(WEAVE_REGULAR_POLYGON_NODE_TYPE).describe(`Type of the node, for a regular polygon node it will always be "${WEAVE_REGULAR_POLYGON_NODE_TYPE}"`),
|
|
16579
|
+
sides: z.number().describe("Number of sides of the regular polygon, must be 3 or more"),
|
|
16580
|
+
radius: z.number().describe("Radius of the regular polygon in pixels, distance from the center to any vertex"),
|
|
16581
|
+
fill: z.string().describe("Fill color of the regular polygon in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
16582
|
+
stroke: z.string().describe("Stroke color of the regular polygon in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
16583
|
+
strokeWidth: z.number().describe("Stroke width of the regular polygon in pixels"),
|
|
16584
|
+
strokeScaleEnabled: z.boolean().describe("Whether the regular polygon stroke width should scale when the node is scaled. Defaults to true.")
|
|
16585
|
+
})
|
|
16586
|
+
});
|
|
16587
|
+
return nodeSchema;
|
|
16588
|
+
}
|
|
16589
|
+
};
|
|
16590
|
+
|
|
16591
|
+
//#endregion
|
|
16592
|
+
//#region src/nodes/polygon/constants.ts
|
|
16593
|
+
const WEAVE_POLYGON_NODE_TYPE = "polygon";
|
|
16594
|
+
|
|
16595
|
+
//#endregion
|
|
16596
|
+
//#region src/nodes/polygon/presets.ts
|
|
16597
|
+
const WEAVE_POLYGON_PRESETS = {
|
|
16598
|
+
triangle: {
|
|
16599
|
+
label: "Triangle",
|
|
16600
|
+
sides: 3,
|
|
16601
|
+
defaultWidth: 100,
|
|
16602
|
+
defaultHeight: 100,
|
|
16603
|
+
normalizedPoints: [
|
|
16604
|
+
{
|
|
16605
|
+
x: .5,
|
|
16606
|
+
y: 0
|
|
16607
|
+
},
|
|
16608
|
+
{
|
|
16609
|
+
x: .933013,
|
|
16610
|
+
y: .75
|
|
16611
|
+
},
|
|
16612
|
+
{
|
|
16613
|
+
x: .066987,
|
|
16614
|
+
y: .75
|
|
16615
|
+
}
|
|
16616
|
+
],
|
|
16617
|
+
normalizedInnerRect: {
|
|
16618
|
+
tl: {
|
|
16619
|
+
x: .283494,
|
|
16620
|
+
y: .375
|
|
16621
|
+
},
|
|
16622
|
+
tr: {
|
|
16623
|
+
x: .716506,
|
|
16624
|
+
y: .375
|
|
16625
|
+
},
|
|
16626
|
+
bl: {
|
|
16627
|
+
x: .283494,
|
|
16628
|
+
y: .75
|
|
16629
|
+
},
|
|
16630
|
+
br: {
|
|
16631
|
+
x: .716506,
|
|
16632
|
+
y: .75
|
|
16633
|
+
}
|
|
16634
|
+
}
|
|
16635
|
+
},
|
|
16636
|
+
diamond: {
|
|
16637
|
+
label: "Diamond",
|
|
16638
|
+
sides: 4,
|
|
16639
|
+
defaultWidth: 100,
|
|
16640
|
+
defaultHeight: 100,
|
|
16641
|
+
normalizedPoints: [
|
|
16642
|
+
{
|
|
16643
|
+
x: .5,
|
|
16644
|
+
y: 0
|
|
16645
|
+
},
|
|
16646
|
+
{
|
|
16647
|
+
x: 1,
|
|
16648
|
+
y: .5
|
|
16649
|
+
},
|
|
16650
|
+
{
|
|
16651
|
+
x: .5,
|
|
16652
|
+
y: 1
|
|
16653
|
+
},
|
|
16654
|
+
{
|
|
16655
|
+
x: 0,
|
|
16656
|
+
y: .5
|
|
16657
|
+
}
|
|
16658
|
+
],
|
|
16659
|
+
normalizedInnerRect: {
|
|
16660
|
+
tl: {
|
|
16661
|
+
x: .25,
|
|
16662
|
+
y: .25
|
|
16663
|
+
},
|
|
16664
|
+
tr: {
|
|
16665
|
+
x: .75,
|
|
16666
|
+
y: .25
|
|
16667
|
+
},
|
|
16668
|
+
bl: {
|
|
16669
|
+
x: .25,
|
|
16670
|
+
y: .75
|
|
16671
|
+
},
|
|
16672
|
+
br: {
|
|
16673
|
+
x: .75,
|
|
16674
|
+
y: .75
|
|
16675
|
+
}
|
|
16676
|
+
}
|
|
16677
|
+
},
|
|
16678
|
+
pentagon: {
|
|
16679
|
+
label: "Pentagon",
|
|
16680
|
+
sides: 5,
|
|
16681
|
+
defaultWidth: 100,
|
|
16682
|
+
defaultHeight: 100,
|
|
16683
|
+
normalizedPoints: [
|
|
16684
|
+
{
|
|
16685
|
+
x: .5,
|
|
16686
|
+
y: 0
|
|
16687
|
+
},
|
|
16688
|
+
{
|
|
16689
|
+
x: .975528,
|
|
16690
|
+
y: .345492
|
|
16691
|
+
},
|
|
16692
|
+
{
|
|
16693
|
+
x: .793893,
|
|
16694
|
+
y: .904508
|
|
16695
|
+
},
|
|
16696
|
+
{
|
|
16697
|
+
x: .206107,
|
|
16698
|
+
y: .904508
|
|
16699
|
+
},
|
|
16700
|
+
{
|
|
16701
|
+
x: .024472,
|
|
16702
|
+
y: .345492
|
|
16703
|
+
}
|
|
16704
|
+
],
|
|
16705
|
+
normalizedInnerRect: {
|
|
16706
|
+
tl: {
|
|
16707
|
+
x: .132634,
|
|
16708
|
+
y: .316578
|
|
16709
|
+
},
|
|
16710
|
+
tr: {
|
|
16711
|
+
x: .867366,
|
|
16712
|
+
y: .316578
|
|
16713
|
+
},
|
|
16714
|
+
bl: {
|
|
16715
|
+
x: .132634,
|
|
16716
|
+
y: .678381
|
|
16717
|
+
},
|
|
16718
|
+
br: {
|
|
16719
|
+
x: .867366,
|
|
16720
|
+
y: .678381
|
|
16721
|
+
}
|
|
16722
|
+
}
|
|
16723
|
+
},
|
|
16724
|
+
hexagon: {
|
|
16725
|
+
label: "Hexagon",
|
|
16726
|
+
sides: 6,
|
|
16727
|
+
defaultWidth: 100,
|
|
16728
|
+
defaultHeight: 100,
|
|
16729
|
+
normalizedPoints: [
|
|
16730
|
+
{
|
|
16731
|
+
x: .5,
|
|
16732
|
+
y: 0
|
|
16733
|
+
},
|
|
16734
|
+
{
|
|
16735
|
+
x: .933013,
|
|
16736
|
+
y: .25
|
|
16737
|
+
},
|
|
16738
|
+
{
|
|
16739
|
+
x: .933013,
|
|
16740
|
+
y: .75
|
|
16741
|
+
},
|
|
16742
|
+
{
|
|
16743
|
+
x: .5,
|
|
16744
|
+
y: 1
|
|
16745
|
+
},
|
|
16746
|
+
{
|
|
16747
|
+
x: .066987,
|
|
16748
|
+
y: .75
|
|
16749
|
+
},
|
|
16750
|
+
{
|
|
16751
|
+
x: .066987,
|
|
16752
|
+
y: .25
|
|
16753
|
+
}
|
|
16754
|
+
],
|
|
16755
|
+
normalizedInnerRect: {
|
|
16756
|
+
tl: {
|
|
16757
|
+
x: .066987,
|
|
16758
|
+
y: .25
|
|
16759
|
+
},
|
|
16760
|
+
tr: {
|
|
16761
|
+
x: .933013,
|
|
16762
|
+
y: .25
|
|
16763
|
+
},
|
|
16764
|
+
bl: {
|
|
16765
|
+
x: .066987,
|
|
16766
|
+
y: .75
|
|
16767
|
+
},
|
|
16768
|
+
br: {
|
|
16769
|
+
x: .933013,
|
|
16770
|
+
y: .75
|
|
16771
|
+
}
|
|
16772
|
+
}
|
|
16773
|
+
},
|
|
16774
|
+
octagon: {
|
|
16775
|
+
label: "Octagon",
|
|
16776
|
+
sides: 8,
|
|
16777
|
+
defaultWidth: 100,
|
|
16778
|
+
defaultHeight: 100,
|
|
16779
|
+
normalizedPoints: [
|
|
16780
|
+
{
|
|
16781
|
+
x: .5,
|
|
16782
|
+
y: 0
|
|
16783
|
+
},
|
|
16784
|
+
{
|
|
16785
|
+
x: .853553,
|
|
16786
|
+
y: .146447
|
|
16787
|
+
},
|
|
16788
|
+
{
|
|
16789
|
+
x: 1,
|
|
16790
|
+
y: .5
|
|
16791
|
+
},
|
|
16792
|
+
{
|
|
16793
|
+
x: .853553,
|
|
16794
|
+
y: .853553
|
|
16795
|
+
},
|
|
16796
|
+
{
|
|
16797
|
+
x: .5,
|
|
16798
|
+
y: 1
|
|
16799
|
+
},
|
|
16800
|
+
{
|
|
16801
|
+
x: .146447,
|
|
16802
|
+
y: .853553
|
|
16803
|
+
},
|
|
16804
|
+
{
|
|
16805
|
+
x: 0,
|
|
16806
|
+
y: .5
|
|
16807
|
+
},
|
|
16808
|
+
{
|
|
16809
|
+
x: .146447,
|
|
16810
|
+
y: .146447
|
|
16811
|
+
}
|
|
16812
|
+
],
|
|
16813
|
+
normalizedInnerRect: {
|
|
16814
|
+
tl: {
|
|
16815
|
+
x: .25,
|
|
16816
|
+
y: .25
|
|
16817
|
+
},
|
|
16818
|
+
tr: {
|
|
16819
|
+
x: .75,
|
|
16820
|
+
y: .25
|
|
16821
|
+
},
|
|
16822
|
+
bl: {
|
|
16823
|
+
x: .25,
|
|
16824
|
+
y: .75
|
|
16825
|
+
},
|
|
16826
|
+
br: {
|
|
16827
|
+
x: .75,
|
|
16828
|
+
y: .75
|
|
16829
|
+
}
|
|
16830
|
+
}
|
|
16831
|
+
},
|
|
16832
|
+
decagon: {
|
|
16833
|
+
label: "Decagon",
|
|
16834
|
+
sides: 10,
|
|
16835
|
+
defaultWidth: 100,
|
|
16836
|
+
defaultHeight: 100,
|
|
16837
|
+
normalizedPoints: [
|
|
16838
|
+
{
|
|
16839
|
+
x: .5,
|
|
16840
|
+
y: 0
|
|
16841
|
+
},
|
|
16842
|
+
{
|
|
16843
|
+
x: .793893,
|
|
16844
|
+
y: .095492
|
|
16845
|
+
},
|
|
16846
|
+
{
|
|
16847
|
+
x: .975528,
|
|
16848
|
+
y: .345492
|
|
16849
|
+
},
|
|
16850
|
+
{
|
|
16851
|
+
x: .975528,
|
|
16852
|
+
y: .654508
|
|
16853
|
+
},
|
|
16854
|
+
{
|
|
16855
|
+
x: .793893,
|
|
16856
|
+
y: .904508
|
|
16857
|
+
},
|
|
16858
|
+
{
|
|
16859
|
+
x: .5,
|
|
16860
|
+
y: 1
|
|
16861
|
+
},
|
|
16862
|
+
{
|
|
16863
|
+
x: .206107,
|
|
16864
|
+
y: .904508
|
|
16865
|
+
},
|
|
16866
|
+
{
|
|
16867
|
+
x: .024472,
|
|
16868
|
+
y: .654508
|
|
16869
|
+
},
|
|
16870
|
+
{
|
|
16871
|
+
x: .024472,
|
|
16872
|
+
y: .345492
|
|
16873
|
+
},
|
|
16874
|
+
{
|
|
16875
|
+
x: .206107,
|
|
16876
|
+
y: .095492
|
|
16877
|
+
}
|
|
16878
|
+
],
|
|
16879
|
+
normalizedInnerRect: {
|
|
16880
|
+
tl: {
|
|
16881
|
+
x: .093851,
|
|
16882
|
+
y: .35
|
|
16883
|
+
},
|
|
16884
|
+
tr: {
|
|
16885
|
+
x: .906149,
|
|
16886
|
+
y: .35
|
|
16887
|
+
},
|
|
16888
|
+
bl: {
|
|
16889
|
+
x: .093851,
|
|
16890
|
+
y: .75
|
|
16891
|
+
},
|
|
16892
|
+
br: {
|
|
16893
|
+
x: .906149,
|
|
16894
|
+
y: .75
|
|
16895
|
+
}
|
|
16896
|
+
}
|
|
16897
|
+
}
|
|
16898
|
+
};
|
|
16899
|
+
/**
|
|
16900
|
+
* Scales a preset's normalized points and inner rect to actual pixel dimensions.
|
|
16901
|
+
*
|
|
16902
|
+
* Points are normalized so that minX = 0 and minY = 0 in the resulting pixel
|
|
16903
|
+
* space. This ensures the polygon group's position corresponds exactly to the
|
|
16904
|
+
* visual top-left of the polygon, which is required for the snapping system to
|
|
16905
|
+
* work correctly (it assumes nodeBox.x === node.x()).
|
|
16906
|
+
*/
|
|
16907
|
+
function instantiatePreset(def, width, height) {
|
|
16908
|
+
const rawPoints = def.normalizedPoints.map((p) => ({
|
|
16909
|
+
x: p.x * width,
|
|
16910
|
+
y: p.y * height
|
|
16911
|
+
}));
|
|
16912
|
+
const minX = Math.min(...rawPoints.map((p) => p.x));
|
|
16913
|
+
const minY = Math.min(...rawPoints.map((p) => p.y));
|
|
16914
|
+
const points = rawPoints.map((p) => ({
|
|
16915
|
+
x: p.x - minX,
|
|
16916
|
+
y: p.y - minY
|
|
16917
|
+
}));
|
|
16918
|
+
const ir = def.normalizedInnerRect;
|
|
16919
|
+
const innerRect = {
|
|
16920
|
+
tl: {
|
|
16921
|
+
x: ir.tl.x * width - minX,
|
|
16922
|
+
y: ir.tl.y * height - minY
|
|
16923
|
+
},
|
|
16924
|
+
tr: {
|
|
16925
|
+
x: ir.tr.x * width - minX,
|
|
16926
|
+
y: ir.tr.y * height - minY
|
|
16927
|
+
},
|
|
16928
|
+
bl: {
|
|
16929
|
+
x: ir.bl.x * width - minX,
|
|
16930
|
+
y: ir.bl.y * height - minY
|
|
16931
|
+
},
|
|
16932
|
+
br: {
|
|
16933
|
+
x: ir.br.x * width - minX,
|
|
16934
|
+
y: ir.br.y * height - minY
|
|
16935
|
+
}
|
|
16936
|
+
};
|
|
16937
|
+
const visualWidth = Math.max(...points.map((p) => p.x));
|
|
16938
|
+
const visualHeight = Math.max(...points.map((p) => p.y));
|
|
16939
|
+
return {
|
|
16940
|
+
points,
|
|
16941
|
+
innerRect,
|
|
16942
|
+
width: visualWidth,
|
|
16943
|
+
height: visualHeight
|
|
16944
|
+
};
|
|
16945
|
+
}
|
|
16946
|
+
|
|
16947
|
+
//#endregion
|
|
16948
|
+
//#region src/nodes/polygon/polygon.ts
|
|
16949
|
+
function computePolygonBounds(points) {
|
|
16950
|
+
if (!points.length) return {
|
|
16951
|
+
width: 0,
|
|
16952
|
+
height: 0
|
|
16953
|
+
};
|
|
16954
|
+
const maxX = Math.max(...points.map((p) => p.x));
|
|
16955
|
+
const maxY = Math.max(...points.map((p) => p.y));
|
|
16956
|
+
return {
|
|
16957
|
+
width: Math.max(1, maxX),
|
|
16958
|
+
height: Math.max(1, maxY)
|
|
16959
|
+
};
|
|
16960
|
+
}
|
|
16961
|
+
function polygonSelfRect() {
|
|
16962
|
+
const pts = this.getAttr("points");
|
|
16963
|
+
if (!pts?.length) return {
|
|
16964
|
+
x: 0,
|
|
16965
|
+
y: 0,
|
|
16966
|
+
width: 0,
|
|
16967
|
+
height: 0
|
|
16968
|
+
};
|
|
16969
|
+
const minX = Math.min(...pts.map((p) => p.x));
|
|
16970
|
+
const minY = Math.min(...pts.map((p) => p.y));
|
|
16971
|
+
const maxX = Math.max(...pts.map((p) => p.x));
|
|
16972
|
+
const maxY = Math.max(...pts.map((p) => p.y));
|
|
16973
|
+
return {
|
|
16974
|
+
x: minX,
|
|
16975
|
+
y: minY,
|
|
16976
|
+
width: maxX - minX,
|
|
16977
|
+
height: maxY - minY
|
|
16978
|
+
};
|
|
16979
|
+
}
|
|
16980
|
+
function getPolygonLabelTextBounds(innerRect, paddingX, paddingY) {
|
|
16981
|
+
return {
|
|
16982
|
+
x: innerRect.tl.x + paddingX,
|
|
16983
|
+
y: innerRect.tl.y + paddingY,
|
|
16984
|
+
width: Math.max(1, innerRect.tr.x - innerRect.tl.x - paddingX * 2),
|
|
16985
|
+
height: Math.max(1, innerRect.bl.y - innerRect.tl.y - paddingY * 2)
|
|
16986
|
+
};
|
|
16987
|
+
}
|
|
16988
|
+
function sceneFunc(context, shape) {
|
|
16989
|
+
const pts = shape.getAttr("points");
|
|
16990
|
+
if (!pts || pts.length < 3) return;
|
|
16991
|
+
context.beginPath();
|
|
16992
|
+
context.moveTo(pts[0].x, pts[0].y);
|
|
16993
|
+
for (let i = 1; i < pts.length; i++) context.lineTo(pts[i].x, pts[i].y);
|
|
16994
|
+
context.closePath();
|
|
16995
|
+
context.fillStrokeShape(shape);
|
|
16996
|
+
}
|
|
16997
|
+
/**
|
|
16998
|
+
* Draws an "inside" stroke for the border shape.
|
|
16999
|
+
* Clips to the polygon interior then draws 2× the stroke width so the outer
|
|
17000
|
+
* half is clipped away — resulting in a stroke of correct visual width that
|
|
17001
|
+
* stays entirely inside the polygon boundary.
|
|
17002
|
+
* strokeWidth is intentionally 0 on the shape (so getClientRect doesn't
|
|
17003
|
+
* expand the bounding box); the real width is stored in `innerStrokeWidth`.
|
|
17004
|
+
*/
|
|
17005
|
+
function borderSceneFunc(context, shape) {
|
|
17006
|
+
const pts = shape.getAttr("points");
|
|
17007
|
+
if (!pts || pts.length < 3) return;
|
|
17008
|
+
const sw = shape.getAttr("innerStrokeWidth");
|
|
17009
|
+
if (!sw) return;
|
|
17010
|
+
const stroke = shape.stroke();
|
|
17011
|
+
if (!stroke || stroke === "transparent") return;
|
|
17012
|
+
const ctx = context._context;
|
|
17013
|
+
const drawPath = () => {
|
|
17014
|
+
ctx.beginPath();
|
|
17015
|
+
ctx.moveTo(pts[0].x, pts[0].y);
|
|
17016
|
+
for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i].x, pts[i].y);
|
|
17017
|
+
ctx.closePath();
|
|
17018
|
+
};
|
|
17019
|
+
ctx.save();
|
|
17020
|
+
drawPath();
|
|
17021
|
+
ctx.clip();
|
|
17022
|
+
drawPath();
|
|
17023
|
+
ctx.lineWidth = sw * 2;
|
|
17024
|
+
ctx.strokeStyle = stroke;
|
|
17025
|
+
ctx.stroke();
|
|
17026
|
+
ctx.restore();
|
|
17027
|
+
}
|
|
17028
|
+
var WeavePolygonNode = class extends WeaveNode {
|
|
17029
|
+
nodeType = WEAVE_POLYGON_NODE_TYPE;
|
|
17030
|
+
initialize = void 0;
|
|
17031
|
+
_transforming = false;
|
|
17032
|
+
get shapeLabelEditor() {
|
|
17033
|
+
this._shapeLabelEditor ??= new WeaveShapeLabelEditor(this.instance);
|
|
17034
|
+
return this._shapeLabelEditor;
|
|
17035
|
+
}
|
|
17036
|
+
constructor(params) {
|
|
17037
|
+
super();
|
|
17038
|
+
const { config } = params ?? {};
|
|
17039
|
+
this.config = { transform: { ...config?.transform } };
|
|
17040
|
+
}
|
|
17041
|
+
getLabelTextBounds(group) {
|
|
17042
|
+
const attrs = group.getAttrs();
|
|
17043
|
+
const innerRect = attrs.innerRect;
|
|
17044
|
+
const paddingX = attrs.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
17045
|
+
const paddingY = attrs.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
17046
|
+
if (!innerRect) return {
|
|
17047
|
+
x: 0,
|
|
17048
|
+
y: 0,
|
|
17049
|
+
width: 1,
|
|
17050
|
+
height: 1
|
|
17051
|
+
};
|
|
17052
|
+
return getPolygonLabelTextBounds(innerRect, paddingX, paddingY);
|
|
17053
|
+
}
|
|
17054
|
+
scalePolygonByDimensions(polygon, nextProps, nodeInstance) {
|
|
17055
|
+
let points = polygon.getAttr("points");
|
|
17056
|
+
const propsMaxX = points.length ? Math.max(...points.map((p) => p.x)) : 0;
|
|
17057
|
+
const propsMaxY = points.length ? Math.max(...points.map((p) => p.y)) : 0;
|
|
17058
|
+
const wantWidth = nextProps.width;
|
|
17059
|
+
const wantHeight = nextProps.height;
|
|
17060
|
+
if (wantWidth === void 0 || wantHeight === void 0) return points;
|
|
17061
|
+
const sX = propsMaxX > 0 ? wantWidth / propsMaxX : 1;
|
|
17062
|
+
const sY = propsMaxY > 0 ? wantHeight / propsMaxY : 1;
|
|
17063
|
+
if (Math.abs(sX - 1) <= .001 && Math.abs(sY - 1) <= .001) return points;
|
|
17064
|
+
const scaledPoints = points.map((p) => ({
|
|
17065
|
+
x: p.x * sX,
|
|
17066
|
+
y: p.y * sY
|
|
17067
|
+
}));
|
|
17068
|
+
const prevInnerRect = polygon.getAttr("innerRect");
|
|
17069
|
+
if (prevInnerRect) {
|
|
17070
|
+
const scaledInnerRect = {
|
|
17071
|
+
tl: {
|
|
17072
|
+
x: prevInnerRect.tl.x * sX,
|
|
17073
|
+
y: prevInnerRect.tl.y * sY
|
|
17074
|
+
},
|
|
17075
|
+
tr: {
|
|
17076
|
+
x: prevInnerRect.tr.x * sX,
|
|
17077
|
+
y: prevInnerRect.tr.y * sY
|
|
17078
|
+
},
|
|
17079
|
+
bl: {
|
|
17080
|
+
x: prevInnerRect.bl.x * sX,
|
|
17081
|
+
y: prevInnerRect.bl.y * sY
|
|
17082
|
+
},
|
|
17083
|
+
br: {
|
|
17084
|
+
x: prevInnerRect.br.x * sX,
|
|
17085
|
+
y: prevInnerRect.br.y * sY
|
|
17086
|
+
}
|
|
17087
|
+
};
|
|
17088
|
+
polygon.setAttr("innerRect", scaledInnerRect);
|
|
17089
|
+
}
|
|
17090
|
+
polygon.setAttr("points", scaledPoints);
|
|
17091
|
+
points = scaledPoints;
|
|
17092
|
+
if (!this._transforming) this.instance.updateNode(this.serialize(nodeInstance));
|
|
17093
|
+
return points;
|
|
17094
|
+
}
|
|
17095
|
+
onLabelGrow(polygon, bgShape, borderShape, nodeInstance, neededHeight) {
|
|
17096
|
+
const livePoints = polygon.getAttr("points");
|
|
17097
|
+
const liveInnerRect = polygon.getAttr("innerRect");
|
|
17098
|
+
if (!liveInnerRect) return;
|
|
17099
|
+
const currentBoundsHeight = liveInnerRect.bl.y - liveInnerRect.tl.y;
|
|
17100
|
+
if (neededHeight <= currentBoundsHeight) return;
|
|
17101
|
+
const oldHeight = Math.max(...livePoints.map((p) => p.y));
|
|
17102
|
+
const scale = currentBoundsHeight > 0 ? neededHeight / currentBoundsHeight : 1;
|
|
17103
|
+
const newHeight = oldHeight * scale;
|
|
17104
|
+
const newPoints = livePoints.map((p) => ({
|
|
17105
|
+
...p,
|
|
17106
|
+
y: p.y * scale
|
|
17107
|
+
}));
|
|
17108
|
+
const newInnerRect = {
|
|
17109
|
+
tl: {
|
|
17110
|
+
...liveInnerRect.tl,
|
|
17111
|
+
y: liveInnerRect.tl.y * scale
|
|
17112
|
+
},
|
|
17113
|
+
tr: {
|
|
17114
|
+
...liveInnerRect.tr,
|
|
17115
|
+
y: liveInnerRect.tr.y * scale
|
|
17116
|
+
},
|
|
17117
|
+
bl: {
|
|
17118
|
+
...liveInnerRect.bl,
|
|
17119
|
+
y: liveInnerRect.bl.y * scale
|
|
17120
|
+
},
|
|
17121
|
+
br: {
|
|
17122
|
+
...liveInnerRect.br,
|
|
17123
|
+
y: liveInnerRect.br.y * scale
|
|
17124
|
+
}
|
|
17125
|
+
};
|
|
17126
|
+
polygon.setAttr("points", newPoints);
|
|
17127
|
+
polygon.setAttr("innerRect", newInnerRect);
|
|
17128
|
+
polygon.setAttr("height", newHeight);
|
|
17129
|
+
bgShape?.setAttr("points", newPoints);
|
|
17130
|
+
borderShape?.setAttr("points", newPoints);
|
|
17131
|
+
if (!this._transforming) this.instance.updateNode(this.serialize(nodeInstance));
|
|
17132
|
+
}
|
|
17133
|
+
triggerPolygonLabelEdit(polygon, props) {
|
|
17134
|
+
const onCommit = (labelText) => {
|
|
17135
|
+
const updatedGroup = this.instance.getStage().findOne(`#${props.id}`);
|
|
17136
|
+
if (!updatedGroup) return;
|
|
17137
|
+
const serialized = this.serialize(updatedGroup);
|
|
17138
|
+
serialized.props.labelText = labelText;
|
|
17139
|
+
this.instance.updateNode(serialized);
|
|
17140
|
+
};
|
|
17141
|
+
const currentLabelTextBounds = this.getLabelTextBounds(polygon);
|
|
17142
|
+
this.shapeLabelEditor.triggerEditMode(polygon, currentLabelTextBounds, onCommit, (neededShapeHeight) => {
|
|
17143
|
+
const liveAttrs = polygon.getAttrs();
|
|
17144
|
+
const livePoints = liveAttrs.points;
|
|
17145
|
+
const liveInnerRect = liveAttrs.innerRect;
|
|
17146
|
+
const liveInnerRectHeight = liveInnerRect.bl.y - liveInnerRect.tl.y;
|
|
17147
|
+
if (neededShapeHeight <= liveInnerRectHeight) return;
|
|
17148
|
+
const oldHeight = Math.max(...livePoints.map((p) => p.y));
|
|
17149
|
+
const scale = liveInnerRectHeight > 0 ? neededShapeHeight / liveInnerRectHeight : 1;
|
|
17150
|
+
const newHeight = oldHeight * scale;
|
|
17151
|
+
const newPoints = livePoints.map((p) => ({
|
|
17152
|
+
...p,
|
|
17153
|
+
y: p.y * scale
|
|
17154
|
+
}));
|
|
17155
|
+
const newInnerRect = {
|
|
17156
|
+
tl: {
|
|
17157
|
+
...liveInnerRect.tl,
|
|
17158
|
+
y: liveInnerRect.tl.y * scale
|
|
17159
|
+
},
|
|
17160
|
+
tr: {
|
|
17161
|
+
...liveInnerRect.tr,
|
|
17162
|
+
y: liveInnerRect.tr.y * scale
|
|
17163
|
+
},
|
|
17164
|
+
bl: {
|
|
17165
|
+
...liveInnerRect.bl,
|
|
17166
|
+
y: liveInnerRect.bl.y * scale
|
|
17167
|
+
},
|
|
17168
|
+
br: {
|
|
17169
|
+
...liveInnerRect.br,
|
|
17170
|
+
y: liveInnerRect.br.y * scale
|
|
17171
|
+
}
|
|
17172
|
+
};
|
|
17173
|
+
polygon.setAttrs({
|
|
17174
|
+
points: newPoints,
|
|
17175
|
+
innerRect: newInnerRect,
|
|
17176
|
+
height: newHeight
|
|
17177
|
+
});
|
|
17178
|
+
this.onUpdate(polygon, polygon.getAttrs());
|
|
17179
|
+
const newLabelTextBounds = this.getLabelTextBounds(polygon);
|
|
17180
|
+
this.shapeLabelEditor.repositionTextArea(polygon, newLabelTextBounds);
|
|
17181
|
+
});
|
|
17182
|
+
}
|
|
17183
|
+
scaleReset(group) {
|
|
17184
|
+
const scaleX = group.scaleX();
|
|
17185
|
+
const scaleY = group.scaleY();
|
|
17186
|
+
if (scaleX === 1 && scaleY === 1) return;
|
|
17187
|
+
const points = group.getAttr("points");
|
|
17188
|
+
const innerRect = group.getAttr("innerRect");
|
|
17189
|
+
const newPoints = points.map((p) => ({
|
|
17190
|
+
x: p.x * scaleX,
|
|
17191
|
+
y: p.y * scaleY
|
|
17192
|
+
}));
|
|
17193
|
+
const newInnerRect = innerRect ? {
|
|
17194
|
+
tl: {
|
|
17195
|
+
x: innerRect.tl.x * scaleX,
|
|
17196
|
+
y: innerRect.tl.y * scaleY
|
|
17197
|
+
},
|
|
17198
|
+
tr: {
|
|
17199
|
+
x: innerRect.tr.x * scaleX,
|
|
17200
|
+
y: innerRect.tr.y * scaleY
|
|
17201
|
+
},
|
|
17202
|
+
bl: {
|
|
17203
|
+
x: innerRect.bl.x * scaleX,
|
|
17204
|
+
y: innerRect.bl.y * scaleY
|
|
17205
|
+
},
|
|
17206
|
+
br: {
|
|
17207
|
+
x: innerRect.br.x * scaleX,
|
|
17208
|
+
y: innerRect.br.y * scaleY
|
|
17209
|
+
}
|
|
17210
|
+
} : void 0;
|
|
17211
|
+
const absTransform = group.getAbsoluteTransform().copy();
|
|
17212
|
+
group.setAttr("points", newPoints);
|
|
17213
|
+
if (newInnerRect) group.setAttr("innerRect", newInnerRect);
|
|
17214
|
+
group.scaleX(1);
|
|
17215
|
+
group.scaleY(1);
|
|
17216
|
+
group.setAttr("width", Math.max(...newPoints.map((p) => p.x)));
|
|
17217
|
+
group.setAttr("height", Math.max(...newPoints.map((p) => p.y)));
|
|
17218
|
+
const newTransform = group.getAbsoluteTransform();
|
|
17219
|
+
const dx = absTransform.m[4] - newTransform.m[4];
|
|
17220
|
+
const dy = absTransform.m[5] - newTransform.m[5];
|
|
17221
|
+
group.x(group.x() + dx);
|
|
17222
|
+
group.y(group.y() + dy);
|
|
17223
|
+
}
|
|
17224
|
+
onRender(props) {
|
|
17225
|
+
const polygon = new Konva.Group({
|
|
17226
|
+
...props,
|
|
17227
|
+
name: "node"
|
|
17228
|
+
});
|
|
17229
|
+
const points = polygon.getAttr("points");
|
|
17230
|
+
const strokeWidth = props.strokeWidth || 0;
|
|
17231
|
+
const bgShape = new Konva.Shape({
|
|
17232
|
+
id: `${props.id}-bg`,
|
|
17233
|
+
nodeId: props.id,
|
|
17234
|
+
points,
|
|
17235
|
+
...computePolygonBounds(points),
|
|
17236
|
+
fill: props.fill || "transparent",
|
|
17237
|
+
strokeWidth: 0,
|
|
17238
|
+
strokeScaleEnabled: false,
|
|
17239
|
+
sceneFunc
|
|
17240
|
+
});
|
|
17241
|
+
bgShape.getSelfRect = polygonSelfRect.bind(bgShape);
|
|
17242
|
+
polygon.add(bgShape);
|
|
17243
|
+
const borderShape = new Konva.Shape({
|
|
17244
|
+
id: `${props.id}-border`,
|
|
17245
|
+
points,
|
|
17246
|
+
fill: "transparent",
|
|
17247
|
+
stroke: props.stroke || "transparent",
|
|
17248
|
+
strokeWidth: 0,
|
|
17249
|
+
innerStrokeWidth: strokeWidth,
|
|
17250
|
+
strokeScaleEnabled: false,
|
|
17251
|
+
listening: false,
|
|
17252
|
+
sceneFunc: borderSceneFunc
|
|
17253
|
+
});
|
|
17254
|
+
borderShape.getSelfRect = polygonSelfRect.bind(borderShape);
|
|
17255
|
+
polygon.add(borderShape);
|
|
17256
|
+
const innerRect = polygon.getAttr("innerRect");
|
|
17257
|
+
const paddingX = props.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
17258
|
+
const paddingY = props.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
17259
|
+
const labelTextBounds = innerRect ? getPolygonLabelTextBounds(innerRect, paddingX, paddingY) : {
|
|
17260
|
+
x: 0,
|
|
17261
|
+
y: 0,
|
|
17262
|
+
width: 1,
|
|
17263
|
+
height: 1
|
|
17264
|
+
};
|
|
17265
|
+
this.shapeLabelEditor.renderLabel(polygon, props, labelTextBounds);
|
|
17266
|
+
borderShape.moveToTop();
|
|
17267
|
+
bgShape.moveToBottom();
|
|
17268
|
+
this.setupDefaultNodeAugmentation(polygon);
|
|
15628
17269
|
const defaultTransformerProperties = this.defaultGetTransformerProperties(this.config.transform);
|
|
15629
|
-
|
|
17270
|
+
polygon.getTransformerProperties = function() {
|
|
15630
17271
|
return {
|
|
15631
17272
|
...defaultTransformerProperties,
|
|
15632
17273
|
enabledAnchors: [
|
|
15633
17274
|
"top-left",
|
|
17275
|
+
"top-center",
|
|
15634
17276
|
"top-right",
|
|
17277
|
+
"middle-right",
|
|
17278
|
+
"middle-left",
|
|
15635
17279
|
"bottom-left",
|
|
17280
|
+
"bottom-center",
|
|
15636
17281
|
"bottom-right"
|
|
15637
17282
|
],
|
|
15638
|
-
keepRatio:
|
|
17283
|
+
keepRatio: false
|
|
15639
17284
|
};
|
|
15640
17285
|
};
|
|
15641
|
-
|
|
17286
|
+
polygon.allowedAnchors = function() {
|
|
15642
17287
|
return [
|
|
15643
17288
|
"top-left",
|
|
17289
|
+
"top-center",
|
|
15644
17290
|
"top-right",
|
|
17291
|
+
"middle-right",
|
|
17292
|
+
"middle-left",
|
|
15645
17293
|
"bottom-left",
|
|
17294
|
+
"bottom-center",
|
|
15646
17295
|
"bottom-right"
|
|
15647
17296
|
];
|
|
15648
17297
|
};
|
|
15649
|
-
this.setupDefaultNodeEvents(
|
|
15650
|
-
|
|
17298
|
+
this.setupDefaultNodeEvents(polygon);
|
|
17299
|
+
polygon.on("transformstart", () => {
|
|
17300
|
+
this._transforming = true;
|
|
17301
|
+
});
|
|
17302
|
+
polygon.on("transform", () => {
|
|
17303
|
+
this.scaleReset(polygon);
|
|
17304
|
+
this.onUpdate(polygon, polygon.getAttrs());
|
|
17305
|
+
});
|
|
17306
|
+
polygon.on("transformend", () => {
|
|
17307
|
+
this._transforming = false;
|
|
17308
|
+
});
|
|
17309
|
+
polygon.dblClick = () => {
|
|
17310
|
+
if (this.shapeLabelEditor.isEditing()) return;
|
|
17311
|
+
if (!(this.isSelecting() && this.isNodeSelected(polygon))) return;
|
|
17312
|
+
this.triggerPolygonLabelEdit(polygon, props);
|
|
17313
|
+
};
|
|
17314
|
+
polygon.getNodeMinSize = () => {
|
|
17315
|
+
return computePolygonLabelMinSize(this.instance.getStage(), polygon);
|
|
17316
|
+
};
|
|
17317
|
+
return polygon;
|
|
15651
17318
|
}
|
|
15652
17319
|
onUpdate(nodeInstance, nextProps) {
|
|
15653
17320
|
nodeInstance.setAttrs({ ...nextProps });
|
|
15654
|
-
const
|
|
15655
|
-
const
|
|
15656
|
-
const
|
|
15657
|
-
const
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15661
|
-
...
|
|
15662
|
-
name: void 0,
|
|
15663
|
-
id: `${nextProps.id}-bg`,
|
|
15664
|
-
nodeId: nextProps.id,
|
|
15665
|
-
x: radius,
|
|
15666
|
-
y: radius,
|
|
15667
|
-
sides,
|
|
15668
|
-
radius,
|
|
17321
|
+
const polygon = nodeInstance;
|
|
17322
|
+
const strokeWidth = nextProps.strokeWidth || 0;
|
|
17323
|
+
const points = this.scalePolygonByDimensions(polygon, nextProps, nodeInstance);
|
|
17324
|
+
const bgShape = polygon.findOne(`#${nextProps.id}-bg`);
|
|
17325
|
+
if (bgShape) {
|
|
17326
|
+
bgShape.setAttrs({
|
|
17327
|
+
points,
|
|
17328
|
+
...computePolygonBounds(points),
|
|
15669
17329
|
fill: nextProps.fill || "transparent",
|
|
15670
17330
|
strokeWidth: 0,
|
|
15671
|
-
strokeScaleEnabled:
|
|
15672
|
-
rotation: 0
|
|
17331
|
+
strokeScaleEnabled: false
|
|
15673
17332
|
});
|
|
15674
|
-
|
|
15675
|
-
internalRPBg.x(internalRPBg.x() - internalRPBgBox.x);
|
|
15676
|
-
internalRPBg.y(internalRPBg.y() - internalRPBgBox.y);
|
|
15677
|
-
internalRPBg.moveToBottom();
|
|
17333
|
+
bgShape.moveToBottom();
|
|
15678
17334
|
}
|
|
15679
|
-
|
|
15680
|
-
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15690
|
-
|
|
15691
|
-
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
17335
|
+
const borderShape = polygon.findOne(`#${nextProps.id}-border`);
|
|
17336
|
+
if (borderShape) borderShape.setAttrs({
|
|
17337
|
+
points,
|
|
17338
|
+
fill: "transparent",
|
|
17339
|
+
stroke: nextProps.stroke || "transparent",
|
|
17340
|
+
strokeWidth: 0,
|
|
17341
|
+
innerStrokeWidth: strokeWidth,
|
|
17342
|
+
strokeScaleEnabled: false,
|
|
17343
|
+
listening: false
|
|
17344
|
+
});
|
|
17345
|
+
const paddingX = nextProps.labelPaddingX ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingX;
|
|
17346
|
+
const paddingY = nextProps.labelPaddingY ?? WEAVE_SHAPE_LABEL_DEFAULTS.labelPaddingY;
|
|
17347
|
+
const innerRect = polygon.getAttr("innerRect");
|
|
17348
|
+
const labelTextBounds = innerRect ? getPolygonLabelTextBounds(innerRect, paddingX, paddingY) : {
|
|
17349
|
+
x: 0,
|
|
17350
|
+
y: 0,
|
|
17351
|
+
width: 1,
|
|
17352
|
+
height: 1
|
|
17353
|
+
};
|
|
17354
|
+
this.shapeLabelEditor.updateLabel(polygon, nextProps, labelTextBounds, (neededHeight) => this.onLabelGrow(polygon, bgShape, borderShape, nodeInstance, neededHeight));
|
|
17355
|
+
const labelNode = polygon.findOne(`#${labelId(nextProps.id)}`);
|
|
17356
|
+
if (labelNode) {
|
|
17357
|
+
labelNode.moveToTop();
|
|
17358
|
+
borderShape?.moveToTop();
|
|
15698
17359
|
}
|
|
15699
17360
|
const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
15700
|
-
if (nodesSelectionPlugin)
|
|
15701
|
-
const actualSelectedNodes = nodesSelectionPlugin.getSelectedNodes();
|
|
15702
|
-
nodesSelectionPlugin.setSelectedNodes(actualSelectedNodes);
|
|
15703
|
-
nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
15704
|
-
}
|
|
15705
|
-
}
|
|
15706
|
-
scaleReset(node) {
|
|
15707
|
-
const absTransform = node.getAbsoluteTransform().copy();
|
|
15708
|
-
const radius = node.getAttr("radius");
|
|
15709
|
-
node.setAttrs({ radius: radius * node.scaleX() });
|
|
15710
|
-
node.scaleX(1);
|
|
15711
|
-
node.scaleY(1);
|
|
15712
|
-
const newTransform = node.getAbsoluteTransform();
|
|
15713
|
-
const dx = absTransform.m[4] - newTransform.m[4];
|
|
15714
|
-
const dy = absTransform.m[5] - newTransform.m[5];
|
|
15715
|
-
node.x(node.x() + dx);
|
|
15716
|
-
node.y(node.y() + dy);
|
|
17361
|
+
if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
|
|
15717
17362
|
}
|
|
15718
|
-
realOffset(
|
|
17363
|
+
realOffset(_element) {
|
|
15719
17364
|
return {
|
|
15720
|
-
x:
|
|
15721
|
-
y:
|
|
17365
|
+
x: 0,
|
|
17366
|
+
y: 0
|
|
15722
17367
|
};
|
|
15723
17368
|
}
|
|
15724
17369
|
static defaultState(nodeId) {
|
|
17370
|
+
const preset = WEAVE_POLYGON_PRESETS.pentagon;
|
|
17371
|
+
const { points, innerRect, width, height } = instantiatePreset(preset, preset.defaultWidth, preset.defaultHeight);
|
|
15725
17372
|
return {
|
|
15726
17373
|
...super.defaultState(nodeId),
|
|
15727
|
-
type:
|
|
17374
|
+
type: WEAVE_POLYGON_NODE_TYPE,
|
|
15728
17375
|
props: {
|
|
15729
17376
|
...super.defaultState(nodeId).props,
|
|
15730
|
-
nodeType:
|
|
17377
|
+
nodeType: WEAVE_POLYGON_NODE_TYPE,
|
|
15731
17378
|
x: 0,
|
|
15732
17379
|
y: 0,
|
|
15733
|
-
|
|
15734
|
-
|
|
17380
|
+
width,
|
|
17381
|
+
height,
|
|
17382
|
+
sides: preset.sides,
|
|
17383
|
+
points,
|
|
17384
|
+
innerRect,
|
|
15735
17385
|
stroke: "#000000",
|
|
15736
17386
|
fill: "#FFFFFF",
|
|
15737
17387
|
strokeWidth: 1,
|
|
15738
|
-
strokeScaleEnabled:
|
|
17388
|
+
strokeScaleEnabled: false,
|
|
15739
17389
|
rotation: 0,
|
|
15740
17390
|
zIndex: 1,
|
|
15741
|
-
children: []
|
|
17391
|
+
children: [],
|
|
17392
|
+
...WEAVE_SHAPE_LABEL_DEFAULTS
|
|
15742
17393
|
}
|
|
15743
17394
|
};
|
|
15744
17395
|
}
|
|
@@ -15746,38 +17397,103 @@ var WeaveRegularPolygonNode = class extends WeaveNode {
|
|
|
15746
17397
|
return mergeExceptArrays(defaultNodeState, { props: {
|
|
15747
17398
|
x: props.x,
|
|
15748
17399
|
y: props.y,
|
|
17400
|
+
width: props.width,
|
|
17401
|
+
height: props.height,
|
|
15749
17402
|
sides: props.sides,
|
|
15750
|
-
|
|
17403
|
+
points: props.points,
|
|
17404
|
+
innerRect: props.innerRect,
|
|
15751
17405
|
rotation: props.rotation,
|
|
15752
17406
|
fill: props.fill,
|
|
15753
17407
|
...props.stroke && { stroke: props.stroke },
|
|
15754
|
-
...props.strokeWidth && { strokeWidth: props.strokeWidth }
|
|
17408
|
+
...props.strokeWidth !== void 0 && { strokeWidth: props.strokeWidth },
|
|
17409
|
+
...props.labelText !== void 0 && { labelText: props.labelText },
|
|
17410
|
+
...props.labelFontFamily !== void 0 && { labelFontFamily: props.labelFontFamily },
|
|
17411
|
+
...props.labelFontSize !== void 0 && { labelFontSize: props.labelFontSize },
|
|
17412
|
+
...props.labelFontStyle !== void 0 && { labelFontStyle: props.labelFontStyle },
|
|
17413
|
+
...props.labelFontVariant !== void 0 && { labelFontVariant: props.labelFontVariant },
|
|
17414
|
+
...props.labelFill !== void 0 && { labelFill: props.labelFill },
|
|
17415
|
+
...props.labelAlign !== void 0 && { labelAlign: props.labelAlign },
|
|
17416
|
+
...props.labelVerticalAlign !== void 0 && { labelVerticalAlign: props.labelVerticalAlign },
|
|
17417
|
+
...props.labelLetterSpacing !== void 0 && { labelLetterSpacing: props.labelLetterSpacing },
|
|
17418
|
+
...props.labelLineHeight !== void 0 && { labelLineHeight: props.labelLineHeight },
|
|
17419
|
+
...props.labelPaddingX !== void 0 && { labelPaddingX: props.labelPaddingX },
|
|
17420
|
+
...props.labelPaddingY !== void 0 && { labelPaddingY: props.labelPaddingY }
|
|
15755
17421
|
} });
|
|
15756
17422
|
}
|
|
15757
17423
|
static updateNodeState(prevNodeState, nextProps) {
|
|
15758
17424
|
return mergeExceptArrays(prevNodeState, { props: {
|
|
15759
17425
|
x: nextProps.x,
|
|
15760
17426
|
y: nextProps.y,
|
|
17427
|
+
...nextProps.width !== void 0 && { width: nextProps.width },
|
|
17428
|
+
...nextProps.height !== void 0 && { height: nextProps.height },
|
|
15761
17429
|
sides: nextProps.sides,
|
|
15762
|
-
|
|
17430
|
+
points: nextProps.points,
|
|
17431
|
+
innerRect: nextProps.innerRect,
|
|
15763
17432
|
rotation: nextProps.rotation,
|
|
15764
17433
|
fill: nextProps.fill,
|
|
15765
17434
|
...nextProps.stroke && { stroke: nextProps.stroke },
|
|
15766
|
-
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth }
|
|
17435
|
+
...nextProps.strokeWidth !== void 0 && { strokeWidth: nextProps.strokeWidth },
|
|
17436
|
+
...nextProps.labelText !== void 0 && { labelText: nextProps.labelText },
|
|
17437
|
+
...nextProps.labelFontFamily !== void 0 && { labelFontFamily: nextProps.labelFontFamily },
|
|
17438
|
+
...nextProps.labelFontSize !== void 0 && { labelFontSize: nextProps.labelFontSize },
|
|
17439
|
+
...nextProps.labelFontStyle !== void 0 && { labelFontStyle: nextProps.labelFontStyle },
|
|
17440
|
+
...nextProps.labelFontVariant !== void 0 && { labelFontVariant: nextProps.labelFontVariant },
|
|
17441
|
+
...nextProps.labelFill !== void 0 && { labelFill: nextProps.labelFill },
|
|
17442
|
+
...nextProps.labelAlign !== void 0 && { labelAlign: nextProps.labelAlign },
|
|
17443
|
+
...nextProps.labelVerticalAlign !== void 0 && { labelVerticalAlign: nextProps.labelVerticalAlign },
|
|
17444
|
+
...nextProps.labelLetterSpacing !== void 0 && { labelLetterSpacing: nextProps.labelLetterSpacing },
|
|
17445
|
+
...nextProps.labelLineHeight !== void 0 && { labelLineHeight: nextProps.labelLineHeight },
|
|
17446
|
+
...nextProps.labelPaddingX !== void 0 && { labelPaddingX: nextProps.labelPaddingX },
|
|
17447
|
+
...nextProps.labelPaddingY !== void 0 && { labelPaddingY: nextProps.labelPaddingY }
|
|
15767
17448
|
} });
|
|
15768
17449
|
}
|
|
15769
17450
|
static getSchema() {
|
|
15770
17451
|
const baseSchema = super.getSchema();
|
|
15771
17452
|
const nodeSchema = baseSchema.extend({
|
|
15772
|
-
type: z.literal(
|
|
17453
|
+
type: z.literal(WEAVE_POLYGON_NODE_TYPE).describe(`Type of the node, for a polygon node it will always be "${WEAVE_POLYGON_NODE_TYPE}"`),
|
|
15773
17454
|
props: baseSchema.shape.props.extend({
|
|
15774
|
-
nodeType: z.literal(
|
|
15775
|
-
sides: z.number().describe("Number of sides of the
|
|
15776
|
-
|
|
15777
|
-
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
|
|
17455
|
+
nodeType: z.literal(WEAVE_POLYGON_NODE_TYPE).describe(`Type of the node, for a polygon node it will always be "${WEAVE_POLYGON_NODE_TYPE}"`),
|
|
17456
|
+
sides: z.number().describe("Number of sides of the polygon (3 or more)"),
|
|
17457
|
+
width: z.number().optional().describe("Visual width of the polygon in pixels (= maxX of vertices). Setting this rescales vertices proportionally."),
|
|
17458
|
+
height: z.number().optional().describe("Visual height of the polygon in pixels (= maxY of vertices). Setting this rescales vertices proportionally."),
|
|
17459
|
+
points: z.array(z.object({
|
|
17460
|
+
x: z.number(),
|
|
17461
|
+
y: z.number()
|
|
17462
|
+
})).describe("Vertex positions of the polygon in group-local pixel space"),
|
|
17463
|
+
innerRect: z.object({
|
|
17464
|
+
tl: z.object({
|
|
17465
|
+
x: z.number(),
|
|
17466
|
+
y: z.number()
|
|
17467
|
+
}),
|
|
17468
|
+
tr: z.object({
|
|
17469
|
+
x: z.number(),
|
|
17470
|
+
y: z.number()
|
|
17471
|
+
}),
|
|
17472
|
+
bl: z.object({
|
|
17473
|
+
x: z.number(),
|
|
17474
|
+
y: z.number()
|
|
17475
|
+
}),
|
|
17476
|
+
br: z.object({
|
|
17477
|
+
x: z.number(),
|
|
17478
|
+
y: z.number()
|
|
17479
|
+
})
|
|
17480
|
+
}).describe("Largest inscribed axis-aligned rectangle inside the polygon (used for label bounds)"),
|
|
17481
|
+
fill: z.string().describe("Fill color of the polygon in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
17482
|
+
stroke: z.string().describe("Stroke color of the polygon in hex format with alpha channel (e.g. #RRGGBBAA)"),
|
|
17483
|
+
strokeWidth: z.number().describe("Stroke width of the polygon in pixels"),
|
|
17484
|
+
strokeScaleEnabled: z.boolean().describe("Whether the polygon stroke width should scale when the node is scaled. Defaults to false."),
|
|
17485
|
+
labelText: z.string().optional().describe("Text label displayed inside the polygon"),
|
|
17486
|
+
labelFontFamily: z.string().optional().describe("Font family for the label text"),
|
|
17487
|
+
labelFontSize: z.number().optional().describe("Font size for the label text in pixels"),
|
|
17488
|
+
labelFontStyle: z.string().optional().describe("Font style for the label text (e.g. \"normal\", \"bold\", \"italic\", \"bold italic\")"),
|
|
17489
|
+
labelFontVariant: z.string().optional().describe("Font variant for the label text (e.g. \"normal\", \"small-caps\")"),
|
|
17490
|
+
labelFill: z.string().optional().describe("Color of the label text in hex format (e.g. #RRGGBBAA)"),
|
|
17491
|
+
labelAlign: z.string().optional().describe("Horizontal alignment of the label text (\"left\", \"center\", \"right\")"),
|
|
17492
|
+
labelVerticalAlign: z.string().optional().describe("Vertical alignment of the label text (\"top\", \"middle\", \"bottom\")"),
|
|
17493
|
+
labelLetterSpacing: z.number().optional().describe("Letter spacing for the label text in pixels"),
|
|
17494
|
+
labelLineHeight: z.number().optional().describe("Line height multiplier for the label text"),
|
|
17495
|
+
labelPaddingX: z.number().optional().describe("Horizontal inset (padding) in pixels applied on each side of the label"),
|
|
17496
|
+
labelPaddingY: z.number().optional().describe("Vertical inset (padding) in pixels applied on top and bottom of the label")
|
|
15781
17497
|
})
|
|
15782
17498
|
});
|
|
15783
17499
|
return nodeSchema;
|
|
@@ -16283,9 +17999,48 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
16283
17999
|
result.push(pts[pts.length - 1]);
|
|
16284
18000
|
return result;
|
|
16285
18001
|
}
|
|
18002
|
+
drawRoundCap(ctx, a, b, color) {
|
|
18003
|
+
const cx = (a.x + b.x) / 2;
|
|
18004
|
+
const cy = (a.y + b.y) / 2;
|
|
18005
|
+
const r = Math.hypot(a.x - b.x, a.y - b.y) / 2;
|
|
18006
|
+
ctx.beginPath();
|
|
18007
|
+
ctx.fillStyle = color;
|
|
18008
|
+
ctx.arc(cx, cy, r, 0, Math.PI * 2);
|
|
18009
|
+
ctx.fill();
|
|
18010
|
+
}
|
|
18011
|
+
/**
|
|
18012
|
+
* Draws a filled polygon from the accumulated left/right outline points of a
|
|
18013
|
+
* dash segment and adds round caps at both ends.
|
|
18014
|
+
* NOTE: mutates `rightSide` via Array.reverse() — callers must not reuse it after this call.
|
|
18015
|
+
*/
|
|
18016
|
+
drawDashPolygon(ctx, leftSide, rightSide, color) {
|
|
18017
|
+
const capStartL = leftSide[0];
|
|
18018
|
+
const capStartR = rightSide[0];
|
|
18019
|
+
const capEndL = leftSide.at(-1);
|
|
18020
|
+
const capEndR = rightSide.at(-1);
|
|
18021
|
+
const smoothLeft = this.getSplinePoints(leftSide, 4);
|
|
18022
|
+
const smoothRight = this.getSplinePoints(rightSide.reverse(), 4);
|
|
18023
|
+
ctx.beginPath();
|
|
18024
|
+
ctx.fillStyle = color;
|
|
18025
|
+
ctx.moveTo(smoothLeft[0].x, smoothLeft[0].y);
|
|
18026
|
+
for (const p of smoothLeft) ctx.lineTo(p.x, p.y);
|
|
18027
|
+
for (const p of smoothRight) ctx.lineTo(p.x, p.y);
|
|
18028
|
+
ctx.closePath();
|
|
18029
|
+
ctx.fill();
|
|
18030
|
+
this.drawRoundCap(ctx, capStartL, capStartR, color);
|
|
18031
|
+
this.drawRoundCap(ctx, capEndL, capEndR, color);
|
|
18032
|
+
}
|
|
16286
18033
|
drawRibbonWithDash(ctx, pts, baseW, color, dash) {
|
|
16287
18034
|
if (!pts) return;
|
|
16288
|
-
if (pts.length < 2)
|
|
18035
|
+
if (pts.length < 2) {
|
|
18036
|
+
const pt = pts[0];
|
|
18037
|
+
const r = Math.max(baseW * pt.pressure / 2, .5);
|
|
18038
|
+
ctx.beginPath();
|
|
18039
|
+
ctx.fillStyle = color;
|
|
18040
|
+
ctx.arc(pt.x, pt.y, r, 0, Math.PI * 2);
|
|
18041
|
+
ctx.fill();
|
|
18042
|
+
return;
|
|
18043
|
+
}
|
|
16289
18044
|
const filtered = this.resamplePoints(pts, 2);
|
|
16290
18045
|
const centerline = this.getSplinePoints(filtered, 8);
|
|
16291
18046
|
let dashIndex = 0;
|
|
@@ -16338,17 +18093,7 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
16338
18093
|
}
|
|
16339
18094
|
dashRemaining -= step;
|
|
16340
18095
|
if (dashRemaining <= 0) {
|
|
16341
|
-
if (dashOn && leftSide.length && rightSide.length)
|
|
16342
|
-
const smoothLeft = this.getSplinePoints(leftSide, 4);
|
|
16343
|
-
const smoothRight = this.getSplinePoints(rightSide.reverse(), 4);
|
|
16344
|
-
ctx.beginPath();
|
|
16345
|
-
ctx.fillStyle = color;
|
|
16346
|
-
ctx.moveTo(smoothLeft[0].x, smoothLeft[0].y);
|
|
16347
|
-
for (const p of smoothLeft) ctx.lineTo(p.x, p.y);
|
|
16348
|
-
for (const p of smoothRight) ctx.lineTo(p.x, p.y);
|
|
16349
|
-
ctx.closePath();
|
|
16350
|
-
ctx.fill();
|
|
16351
|
-
}
|
|
18096
|
+
if (dashOn && leftSide.length && rightSide.length) this.drawDashPolygon(ctx, leftSide, rightSide, color);
|
|
16352
18097
|
leftSide = [];
|
|
16353
18098
|
rightSide = [];
|
|
16354
18099
|
dashOn = !dashOn;
|
|
@@ -16358,17 +18103,7 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
16358
18103
|
traveled += step;
|
|
16359
18104
|
}
|
|
16360
18105
|
}
|
|
16361
|
-
if (dashOn && leftSide.length && rightSide.length)
|
|
16362
|
-
const smoothLeft = this.getSplinePoints(leftSide, 4);
|
|
16363
|
-
const smoothRight = this.getSplinePoints(rightSide.reverse(), 4);
|
|
16364
|
-
ctx.beginPath();
|
|
16365
|
-
ctx.fillStyle = color;
|
|
16366
|
-
ctx.moveTo(smoothLeft[0].x, smoothLeft[0].y);
|
|
16367
|
-
for (const p of smoothLeft) ctx.lineTo(p.x, p.y);
|
|
16368
|
-
for (const p of smoothRight) ctx.lineTo(p.x, p.y);
|
|
16369
|
-
ctx.closePath();
|
|
16370
|
-
ctx.fill();
|
|
16371
|
-
}
|
|
18106
|
+
if (dashOn && leftSide.length && rightSide.length) this.drawDashPolygon(ctx, leftSide, rightSide, color);
|
|
16372
18107
|
}
|
|
16373
18108
|
drawShape(ctx, shape) {
|
|
16374
18109
|
const strokeElements = shape.getAttrs().strokeElements;
|
|
@@ -16385,8 +18120,6 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
16385
18120
|
sceneFunc: (ctx, shape) => {
|
|
16386
18121
|
this.drawShape(ctx, shape);
|
|
16387
18122
|
},
|
|
16388
|
-
lineCap: "round",
|
|
16389
|
-
lineJoin: "round",
|
|
16390
18123
|
dashEnabled: false,
|
|
16391
18124
|
hitFunc: (context, shape) => {
|
|
16392
18125
|
context.beginPath();
|
|
@@ -21659,6 +23392,7 @@ var WeaveRectangleToolAction = class extends WeaveAction {
|
|
|
21659
23392
|
if (node) selectionPlugin.setSelectedNodes([node]);
|
|
21660
23393
|
this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
|
|
21661
23394
|
}
|
|
23395
|
+
if (this.tempRectNode) this.tempRectNode.destroy();
|
|
21662
23396
|
this.rectId = null;
|
|
21663
23397
|
this.tempRectNode = null;
|
|
21664
23398
|
this.moved = false;
|
|
@@ -22668,34 +24402,40 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
22668
24402
|
if (nodeHandler) nodeHandler.onUpdate(tempStroke, tempStroke.getAttrs());
|
|
22669
24403
|
}
|
|
22670
24404
|
}
|
|
24405
|
+
finalizeStroke(tempStroke, nodeHandler) {
|
|
24406
|
+
const box = this.getBoundingBox(tempStroke.getAttrs().strokeElements);
|
|
24407
|
+
let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
|
|
24408
|
+
if (this.predictedCount > 0) {
|
|
24409
|
+
newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
|
|
24410
|
+
this.predictedCount = 0;
|
|
24411
|
+
}
|
|
24412
|
+
newStrokeElements = newStrokeElements.map((point) => ({
|
|
24413
|
+
...point,
|
|
24414
|
+
x: point.x - box.x,
|
|
24415
|
+
y: point.y - box.y
|
|
24416
|
+
}));
|
|
24417
|
+
const compressedPoints = simplify(newStrokeElements, 1, true);
|
|
24418
|
+
const sw = tempStroke.getAttrs().strokeWidth ?? 1;
|
|
24419
|
+
const finalWidth = Math.max(box.width, sw);
|
|
24420
|
+
const finalHeight = Math.max(box.height, sw);
|
|
24421
|
+
const finalX = box.width === 0 ? box.x - sw / 2 : box.x;
|
|
24422
|
+
const finalY = box.height === 0 ? box.y - sw / 2 : box.y;
|
|
24423
|
+
tempStroke.setAttrs({
|
|
24424
|
+
width: finalWidth,
|
|
24425
|
+
height: finalHeight,
|
|
24426
|
+
x: finalX,
|
|
24427
|
+
y: finalY,
|
|
24428
|
+
strokeElements: compressedPoints
|
|
24429
|
+
});
|
|
24430
|
+
const realNode = this.instance.getStage().findOne(`#${tempStroke.getAttrs().id}`);
|
|
24431
|
+
if (realNode) realNode.destroy();
|
|
24432
|
+
if (tempStroke.getAttrs().strokeElements.length >= 1) this.instance.addNode(nodeHandler.serialize(tempStroke), this.container?.getAttrs().id);
|
|
24433
|
+
}
|
|
22671
24434
|
handleEndStroke() {
|
|
22672
24435
|
const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
|
|
22673
24436
|
if (tempStroke) {
|
|
22674
24437
|
const nodeHandler = this.instance.getNodeHandler("stroke");
|
|
22675
|
-
if (nodeHandler)
|
|
22676
|
-
const box = this.getBoundingBox(tempStroke.getAttrs().strokeElements);
|
|
22677
|
-
let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
|
|
22678
|
-
if (this.predictedCount > 0) {
|
|
22679
|
-
newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
|
|
22680
|
-
this.predictedCount = 0;
|
|
22681
|
-
}
|
|
22682
|
-
newStrokeElements = newStrokeElements.map((point) => ({
|
|
22683
|
-
...point,
|
|
22684
|
-
x: point.x - box.x,
|
|
22685
|
-
y: point.y - box.y
|
|
22686
|
-
}));
|
|
22687
|
-
const compressedPoints = simplify(newStrokeElements, 1, true);
|
|
22688
|
-
tempStroke.setAttrs({
|
|
22689
|
-
width: box.width,
|
|
22690
|
-
height: box.height,
|
|
22691
|
-
x: box.x,
|
|
22692
|
-
y: box.y,
|
|
22693
|
-
strokeElements: compressedPoints
|
|
22694
|
-
});
|
|
22695
|
-
const realNode = this.instance.getStage().findOne(`#${tempStroke.getAttrs().id}`);
|
|
22696
|
-
if (realNode) realNode.destroy();
|
|
22697
|
-
if (tempStroke.getAttrs().strokeElements.length >= 3) this.instance.addNode(nodeHandler.serialize(tempStroke), this.container?.getAttrs().id);
|
|
22698
|
-
}
|
|
24438
|
+
if (nodeHandler) this.finalizeStroke(tempStroke, nodeHandler);
|
|
22699
24439
|
this.clickPoint = null;
|
|
22700
24440
|
this.setCursor();
|
|
22701
24441
|
this.setFocusStage();
|
|
@@ -24763,6 +26503,137 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
|
|
|
24763
26503
|
}
|
|
24764
26504
|
};
|
|
24765
26505
|
|
|
26506
|
+
//#endregion
|
|
26507
|
+
//#region src/actions/polygon-tool/constants.ts
|
|
26508
|
+
const POLYGON_TOOL_ACTION_NAME = "polygonTool";
|
|
26509
|
+
const POLYGON_TOOL_STATE = {
|
|
26510
|
+
["IDLE"]: "idle",
|
|
26511
|
+
["ADDING"]: "adding",
|
|
26512
|
+
["ADDED"]: "added"
|
|
26513
|
+
};
|
|
26514
|
+
|
|
26515
|
+
//#endregion
|
|
26516
|
+
//#region src/actions/polygon-tool/polygon-tool.ts
|
|
26517
|
+
var WeavePolygonToolAction = class extends WeaveAction {
|
|
26518
|
+
initialized = false;
|
|
26519
|
+
onPropsChange = void 0;
|
|
26520
|
+
onInit = void 0;
|
|
26521
|
+
constructor(preset) {
|
|
26522
|
+
super();
|
|
26523
|
+
this.preset = preset ?? "pentagon";
|
|
26524
|
+
this.initialize();
|
|
26525
|
+
}
|
|
26526
|
+
initialize() {
|
|
26527
|
+
this.initialized = false;
|
|
26528
|
+
this.state = POLYGON_TOOL_STATE.IDLE;
|
|
26529
|
+
this.polygonId = null;
|
|
26530
|
+
this.props = this.initProps();
|
|
26531
|
+
}
|
|
26532
|
+
getName() {
|
|
26533
|
+
return POLYGON_TOOL_ACTION_NAME;
|
|
26534
|
+
}
|
|
26535
|
+
initProps() {
|
|
26536
|
+
return {
|
|
26537
|
+
opacity: 1,
|
|
26538
|
+
fill: "#ffffffff",
|
|
26539
|
+
stroke: "#000000ff",
|
|
26540
|
+
strokeWidth: 1
|
|
26541
|
+
};
|
|
26542
|
+
}
|
|
26543
|
+
getPolygonsPresets() {
|
|
26544
|
+
return WEAVE_POLYGON_PRESETS;
|
|
26545
|
+
}
|
|
26546
|
+
getPolygonPreset() {
|
|
26547
|
+
return this.preset;
|
|
26548
|
+
}
|
|
26549
|
+
setPolygonPreset(preset) {
|
|
26550
|
+
this.preset = preset;
|
|
26551
|
+
}
|
|
26552
|
+
setupEvents() {
|
|
26553
|
+
const stage = this.instance.getStage();
|
|
26554
|
+
window.addEventListener("keydown", (e) => {
|
|
26555
|
+
if ((e.code === "Enter" || e.code === "Escape") && this.instance.getActiveAction() === POLYGON_TOOL_ACTION_NAME) this.cancelAction();
|
|
26556
|
+
}, { signal: this.instance.getEventsController().signal });
|
|
26557
|
+
stage.on("pointermove", () => {
|
|
26558
|
+
if (this.state === POLYGON_TOOL_STATE.IDLE) return;
|
|
26559
|
+
this.setCursor();
|
|
26560
|
+
});
|
|
26561
|
+
stage.on("pointerdown", (e) => {
|
|
26562
|
+
this.setTapStart(e);
|
|
26563
|
+
if (this.state !== POLYGON_TOOL_STATE.ADDING) return;
|
|
26564
|
+
this.handleAdding();
|
|
26565
|
+
});
|
|
26566
|
+
this.initialized = true;
|
|
26567
|
+
}
|
|
26568
|
+
setState(state) {
|
|
26569
|
+
this.state = state;
|
|
26570
|
+
}
|
|
26571
|
+
addPolygon() {
|
|
26572
|
+
this.setCursor();
|
|
26573
|
+
this.setFocusStage();
|
|
26574
|
+
this.instance.emitEvent("onAddingPolygon");
|
|
26575
|
+
this.setState(POLYGON_TOOL_STATE.ADDING);
|
|
26576
|
+
}
|
|
26577
|
+
handleAdding() {
|
|
26578
|
+
const { mousePoint, container } = this.instance.getMousePointer();
|
|
26579
|
+
this.polygonId = v4_default();
|
|
26580
|
+
const presetDef = WEAVE_POLYGON_PRESETS[this.preset];
|
|
26581
|
+
const scaleFactor = this.props.scaleFactor ?? 1;
|
|
26582
|
+
const { points, innerRect, width, height } = instantiatePreset(presetDef, presetDef.defaultWidth * scaleFactor, presetDef.defaultHeight * scaleFactor);
|
|
26583
|
+
const nodeHandler = this.instance.getNodeHandler(WEAVE_POLYGON_NODE_TYPE);
|
|
26584
|
+
if (nodeHandler) {
|
|
26585
|
+
const node = nodeHandler.create(this.polygonId, {
|
|
26586
|
+
...this.props,
|
|
26587
|
+
x: mousePoint?.x ?? 0,
|
|
26588
|
+
y: mousePoint?.y ?? 0,
|
|
26589
|
+
width,
|
|
26590
|
+
height,
|
|
26591
|
+
sides: presetDef.sides,
|
|
26592
|
+
points,
|
|
26593
|
+
innerRect
|
|
26594
|
+
});
|
|
26595
|
+
this.instance.addNode(node, container?.getAttrs().id);
|
|
26596
|
+
}
|
|
26597
|
+
this.instance.emitEvent("onAddedPolygon");
|
|
26598
|
+
this.cancelAction();
|
|
26599
|
+
}
|
|
26600
|
+
trigger(cancelAction, params) {
|
|
26601
|
+
if (!this.instance) throw new Error("Instance not defined");
|
|
26602
|
+
if (!this.initialized) this.setupEvents();
|
|
26603
|
+
this.preset = params?.presetId ?? "pentagon";
|
|
26604
|
+
const stage = this.instance.getStage();
|
|
26605
|
+
stage.container().tabIndex = 1;
|
|
26606
|
+
stage.container().focus();
|
|
26607
|
+
this.cancelAction = cancelAction;
|
|
26608
|
+
const selectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
26609
|
+
if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
|
|
26610
|
+
this.props = this.initProps();
|
|
26611
|
+
this.addPolygon();
|
|
26612
|
+
}
|
|
26613
|
+
cleanup() {
|
|
26614
|
+
const stage = this.instance.getStage();
|
|
26615
|
+
stage.container().style.cursor = "default";
|
|
26616
|
+
const selectionPlugin = this.instance.getPlugin("nodesSelection");
|
|
26617
|
+
if (selectionPlugin) {
|
|
26618
|
+
const node = stage.findOne(`#${this.polygonId}`);
|
|
26619
|
+
if (node) selectionPlugin.setSelectedNodes([node]);
|
|
26620
|
+
this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
|
|
26621
|
+
}
|
|
26622
|
+
this.polygonId = null;
|
|
26623
|
+
this.setState(POLYGON_TOOL_STATE.IDLE);
|
|
26624
|
+
}
|
|
26625
|
+
setCursor() {
|
|
26626
|
+
const stage = this.instance.getStage();
|
|
26627
|
+
stage.container().style.cursor = "crosshair";
|
|
26628
|
+
}
|
|
26629
|
+
setFocusStage() {
|
|
26630
|
+
const stage = this.instance.getStage();
|
|
26631
|
+
stage.container().tabIndex = 1;
|
|
26632
|
+
stage.container().blur();
|
|
26633
|
+
stage.container().focus();
|
|
26634
|
+
}
|
|
26635
|
+
};
|
|
26636
|
+
|
|
24766
26637
|
//#endregion
|
|
24767
26638
|
//#region src/actions/frame-tool/constants.ts
|
|
24768
26639
|
const FRAME_TOOL_ACTION_NAME = "frameTool";
|
|
@@ -30859,14 +32730,20 @@ var WeaveNodesSnappingPlugin = class extends WeavePlugin {
|
|
|
30859
32730
|
}
|
|
30860
32731
|
return updatedBox;
|
|
30861
32732
|
};
|
|
30862
|
-
const
|
|
30863
|
-
|
|
32733
|
+
const snapBoundingBoxFunc = boundingBoxFunc.bind(this);
|
|
32734
|
+
const newBoundFunc = (oldBox, newBox) => {
|
|
32735
|
+
const mainBoundBoxFunc = nodesSelectionPlugin.getBoundBoxFunc();
|
|
32736
|
+
const actualBox = mainBoundBoxFunc(oldBox, newBox);
|
|
32737
|
+
if (actualBox === oldBox) return actualBox;
|
|
32738
|
+
return snapBoundingBoxFunc(oldBox, newBox);
|
|
32739
|
+
};
|
|
32740
|
+
tr.boundBoxFunc(newBoundFunc);
|
|
30864
32741
|
}
|
|
30865
32742
|
transformEndHandler() {
|
|
30866
32743
|
const nodesSelectionPlugin = this.getNodesSelectionPlugin();
|
|
30867
32744
|
if (nodesSelectionPlugin) {
|
|
30868
32745
|
const tr = nodesSelectionPlugin.getTransformer();
|
|
30869
|
-
tr.boundBoxFunc(
|
|
32746
|
+
tr.boundBoxFunc(nodesSelectionPlugin.getBoundBoxFunc());
|
|
30870
32747
|
}
|
|
30871
32748
|
this.snappingGuides = [];
|
|
30872
32749
|
}
|
|
@@ -31064,5 +32941,5 @@ var WeaveNodesSnappingPlugin = class extends WeavePlugin {
|
|
|
31064
32941
|
};
|
|
31065
32942
|
|
|
31066
32943
|
//#endregion
|
|
31067
|
-
export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, DEFAULT_GUIDE_TOOL_ACTION_CONFIG, DEFAULT_SNAPPING_MANAGER_CONFIG, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_NAME, GUIDE_DISTANCE_ORIGIN, GUIDE_KIND, GUIDE_NAME, GUIDE_ORIENTATION, GUIDE_STATE, GUIDE_TOOL_ACTION_NAME, GUIDE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_ORIENTATION, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_ARROW_TOOL_ACTION_NAME, WEAVE_ARROW_TOOL_STATE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_CONFIG, WEAVE_GRID_DOT_TYPES, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGES_TOOL_ACTION_NAME, WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, WEAVE_IMAGES_TOOL_STATE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_IMAGE_TOOL_ACTION_NAME, WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, WEAVE_IMAGE_TOOL_STATE, WEAVE_IMAGE_TOOL_UPLOAD_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_NODES_SNAPPING_PLUGIN_KEY, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_DROP_AREA_KEY, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_IMAGE_CROPPING_MODE, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_KEYBOARD_MOVE_ORIENTATION, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAGE_TEXT_EDITION_MODE, WEAVE_STAGE_ZOOM_DEFAULT_CONFIG, WEAVE_STAGE_ZOOM_KEY, WEAVE_STAGE_ZOOM_TYPE, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE, WEAVE_STROKE_SINGLE_NODE_TIP_TYPE, WEAVE_STROKE_SINGLE_NODE_TYPE, WEAVE_STROKE_TOOL_ACTION_NAME, WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES, WEAVE_STROKE_TOOL_DEFAULT_CONFIG, WEAVE_STROKE_TOOL_STATE, WEAVE_TEXT_NODE_DEFAULT_CONFIG, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveGuideToolAction, WeaveImageNode, WeaveImageToolAction, WeaveImagesToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeaveNodesSnappingPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveRenderer, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStateManipulation, WeaveStore, WeaveStrokeNode, WeaveStrokeSingleNode, WeaveStrokeToolAction, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, downscaleImageFile, downscaleImageFromURL, getBoundingBox, getDownscaleRatio, getExportBoundingBox, getImageSizeFromFile, getJSONFromYjsBinary, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isNumber, isObject, isServer, loadImageSource, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, setupCanvasBackend, setupSkiaBackend, weavejsToYjsBinary };
|
|
32944
|
+
export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, DEFAULT_GUIDE_TOOL_ACTION_CONFIG, DEFAULT_SNAPPING_MANAGER_CONFIG, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_NAME, GUIDE_DISTANCE_ORIGIN, GUIDE_KIND, GUIDE_NAME, GUIDE_ORIENTATION, GUIDE_STATE, GUIDE_TOOL_ACTION_NAME, GUIDE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_ORIENTATION, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, POLYGON_TOOL_ACTION_NAME, POLYGON_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_ARROW_TOOL_ACTION_NAME, WEAVE_ARROW_TOOL_STATE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_CONFIG, WEAVE_GRID_DOT_TYPES, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGES_TOOL_ACTION_NAME, WEAVE_IMAGES_TOOL_DEFAULT_CONFIG, WEAVE_IMAGES_TOOL_STATE, WEAVE_IMAGES_TOOL_UPLOAD_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_IMAGE_TOOL_ACTION_NAME, WEAVE_IMAGE_TOOL_CONFIG_DEFAULT, WEAVE_IMAGE_TOOL_STATE, WEAVE_IMAGE_TOOL_UPLOAD_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_NODES_SNAPPING_PLUGIN_KEY, WEAVE_POLYGON_NODE_TYPE, WEAVE_POLYGON_PRESETS, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_SHAPE_LABEL_DEFAULTS, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_DROP_AREA_KEY, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_IMAGE_CROPPING_MODE, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_KEYBOARD_MOVE_ORIENTATION, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAGE_SHAPE_LABEL_EDITION_MODE, WEAVE_STAGE_TEXT_EDITION_MODE, WEAVE_STAGE_ZOOM_DEFAULT_CONFIG, WEAVE_STAGE_ZOOM_KEY, WEAVE_STAGE_ZOOM_TYPE, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE, WEAVE_STROKE_SINGLE_NODE_TIP_TYPE, WEAVE_STROKE_SINGLE_NODE_TYPE, WEAVE_STROKE_TOOL_ACTION_NAME, WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES, WEAVE_STROKE_TOOL_DEFAULT_CONFIG, WEAVE_STROKE_TOOL_STATE, WEAVE_TEXT_NODE_DEFAULT_CONFIG, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveGuideToolAction, WeaveImageNode, WeaveImageToolAction, WeaveImagesToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeaveNodesSnappingPlugin, WeavePenToolAction, WeavePlugin, WeavePolygonNode, WeavePolygonToolAction, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveRenderer, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStateManipulation, WeaveStore, WeaveStrokeNode, WeaveStrokeSingleNode, WeaveStrokeToolAction, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, computeEllipseLabelMinSize, computePolygonLabelMinSize, computeRectangleLabelMinSize, containerOverCursor, containsNodeDeep, defaultInitialState, downscaleImageFile, downscaleImageFromURL, getBoundingBox, getDownscaleRatio, getExportBoundingBox, getImageSizeFromFile, getJSONFromYjsBinary, getSelectedNodesMetadata, getShapeLabelSchemaFields, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, instantiatePreset, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isNumber, isObject, isServer, labelId, loadImageSource, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, moveNodeToContainerNT, resetScale, setupCanvasBackend, setupSkiaBackend, spreadLabelProps, weavejsToYjsBinary };
|
|
31068
32945
|
//# sourceMappingURL=types.js.map
|