@inditextech/weave-sdk 5.3.0 → 5.4.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 +441 -82
- package/dist/sdk.node.js +442 -83
- package/dist/sdk.node.stats.html +1 -1
- package/dist/sdk.stats.html +1 -1
- package/dist/types.d.ts +159 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +441 -82
- package/dist/types.js.map +1 -1
- package/dist/types.stats.html +1 -1
- package/package.json +2 -2
package/dist/types.js
CHANGED
|
@@ -4676,7 +4676,15 @@ function handleClickOrTap(ctx, e) {
|
|
|
4676
4676
|
nodeTargeted.dblClick();
|
|
4677
4677
|
return;
|
|
4678
4678
|
}
|
|
4679
|
-
|
|
4679
|
+
const isCtrlOrCmdPressed = e.evt.ctrlKey || e.evt.metaKey;
|
|
4680
|
+
if (!e.evt.shiftKey) {
|
|
4681
|
+
const wasSelectedBeforeThisClick = tr.nodes().findIndex((node) => node.getAttrs().id === nodeTargeted.getAttrs().id) !== -1;
|
|
4682
|
+
nodeTargeted.click({
|
|
4683
|
+
wasSelected: wasSelectedBeforeThisClick,
|
|
4684
|
+
ctrlOrMetaPressed: isCtrlOrCmdPressed
|
|
4685
|
+
});
|
|
4686
|
+
}
|
|
4687
|
+
if (isCtrlOrCmdPressed) return;
|
|
4680
4688
|
if (!metaPressed) {
|
|
4681
4689
|
tr.nodes([nodeTargeted]);
|
|
4682
4690
|
tr.show();
|
|
@@ -5945,6 +5953,7 @@ const augmentKonvaNodeClass = (config) => {
|
|
|
5945
5953
|
Konva.Node.prototype.closeCrop = function() {};
|
|
5946
5954
|
Konva.Node.prototype.resetCrop = function() {};
|
|
5947
5955
|
Konva.Node.prototype.dblClick = function() {};
|
|
5956
|
+
Konva.Node.prototype.click = function() {};
|
|
5948
5957
|
Konva.Node.prototype.allowedAnchors = function() {
|
|
5949
5958
|
return [];
|
|
5950
5959
|
};
|
|
@@ -9457,7 +9466,7 @@ var WeaveRegisterManager = class {
|
|
|
9457
9466
|
};
|
|
9458
9467
|
//#endregion
|
|
9459
9468
|
//#region package.json
|
|
9460
|
-
var version = "5.
|
|
9469
|
+
var version = "5.4.1";
|
|
9461
9470
|
//#endregion
|
|
9462
9471
|
//#region src/managers/setup.ts
|
|
9463
9472
|
var WeaveSetupManager = class {
|
|
@@ -13430,8 +13439,13 @@ const WEAVE_TEXT_NODE_DEFAULT_CONFIG = {
|
|
|
13430
13439
|
transform: { ...WEAVE_NODES_SELECTION_DEFAULT_CONFIG.selection },
|
|
13431
13440
|
outline: { enabled: false },
|
|
13432
13441
|
cursor: { color: "#000000" },
|
|
13433
|
-
edition: { borderSize: 2 }
|
|
13442
|
+
edition: { borderSize: 2 },
|
|
13443
|
+
link: {
|
|
13444
|
+
defaultColor: "#1155ccff",
|
|
13445
|
+
hoverColor: "#3d7be0ff"
|
|
13446
|
+
}
|
|
13434
13447
|
};
|
|
13448
|
+
const WEAVE_TEXT_LINK_ALLOWED_PROTOCOLS = ["http:", "https:"];
|
|
13435
13449
|
const TEXT_LAYOUT = {
|
|
13436
13450
|
["SMART"]: "smart",
|
|
13437
13451
|
["AUTO_ALL"]: "auto-all",
|
|
@@ -13440,6 +13454,21 @@ const TEXT_LAYOUT = {
|
|
|
13440
13454
|
};
|
|
13441
13455
|
//#endregion
|
|
13442
13456
|
//#region src/nodes/text/text.ts
|
|
13457
|
+
/**
|
|
13458
|
+
* Validates that a link is an absolute http(s) URL. Used both by the zod
|
|
13459
|
+
* schema (getSchema()) and defensively again at click-time (setLink() and
|
|
13460
|
+
* the pointerclick handler), since the value is user-authored content
|
|
13461
|
+
* rendered and clicked on by other collaborators — schemes like
|
|
13462
|
+
* `javascript:` or `data:` must never reach `window.open`.
|
|
13463
|
+
*/
|
|
13464
|
+
function isValidTextLink(value) {
|
|
13465
|
+
try {
|
|
13466
|
+
const url = new URL(value);
|
|
13467
|
+
return WEAVE_TEXT_LINK_ALLOWED_PROTOCOLS.includes(url.protocol);
|
|
13468
|
+
} catch {
|
|
13469
|
+
return false;
|
|
13470
|
+
}
|
|
13471
|
+
}
|
|
13443
13472
|
var WeaveTextNode = class extends WeaveNode {
|
|
13444
13473
|
config;
|
|
13445
13474
|
nodeType = WEAVE_TEXT_NODE_TYPE;
|
|
@@ -13503,6 +13532,8 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13503
13532
|
}
|
|
13504
13533
|
}
|
|
13505
13534
|
onRender(props) {
|
|
13535
|
+
const linkPreviousFill = props.link ? props.linkPreviousFill ?? props.fill : props.linkPreviousFill;
|
|
13536
|
+
const linkPreviousTextDecoration = props.link ? props.linkPreviousTextDecoration ?? props.textDecoration : props.linkPreviousTextDecoration;
|
|
13506
13537
|
const text = new Konva.Text({
|
|
13507
13538
|
...props,
|
|
13508
13539
|
name: "node",
|
|
@@ -13512,6 +13543,12 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13512
13543
|
stroke: this.config.outline.color,
|
|
13513
13544
|
strokeWidth: this.config.outline.width,
|
|
13514
13545
|
fillAfterStrokeEnabled: true
|
|
13546
|
+
},
|
|
13547
|
+
...props.link && {
|
|
13548
|
+
textDecoration: "underline",
|
|
13549
|
+
fill: this.config.link.defaultColor,
|
|
13550
|
+
linkPreviousFill,
|
|
13551
|
+
linkPreviousTextDecoration
|
|
13515
13552
|
}
|
|
13516
13553
|
});
|
|
13517
13554
|
this.setupDefaultNodeAugmentation(text);
|
|
@@ -13570,6 +13607,7 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13570
13607
|
this.triggerEditMode(text);
|
|
13571
13608
|
};
|
|
13572
13609
|
text.setAttr("triggerEditMode", this.triggerEditMode.bind(this));
|
|
13610
|
+
this.setupLinkBehavior(text);
|
|
13573
13611
|
let actualAnchor = void 0;
|
|
13574
13612
|
text.on("transformstart", (e) => {
|
|
13575
13613
|
const isCtrlOrMetaPressed = e.evt.ctrlKey || e.evt.metaKey;
|
|
@@ -13666,6 +13704,9 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13666
13704
|
return text;
|
|
13667
13705
|
}
|
|
13668
13706
|
onUpdate(nodeInstance, nextProps) {
|
|
13707
|
+
const isLinked = Boolean(nextProps.link);
|
|
13708
|
+
const linkPreviousFill = nextProps.link ? nextProps.linkPreviousFill ?? nextProps.fill : nextProps.linkPreviousFill;
|
|
13709
|
+
const linkPreviousTextDecoration = nextProps.link ? nextProps.linkPreviousTextDecoration ?? nextProps.textDecoration : nextProps.linkPreviousTextDecoration;
|
|
13669
13710
|
nodeInstance.setAttrs({
|
|
13670
13711
|
...nextProps,
|
|
13671
13712
|
...!this.config.outline.enabled && { strokeEnabled: false },
|
|
@@ -13674,6 +13715,13 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13674
13715
|
stroke: this.config.outline.color,
|
|
13675
13716
|
strokeWidth: this.config.outline.width,
|
|
13676
13717
|
fillAfterStrokeEnabled: true
|
|
13718
|
+
},
|
|
13719
|
+
link: nextProps.link,
|
|
13720
|
+
linkPreviousFill: isLinked ? linkPreviousFill : void 0,
|
|
13721
|
+
linkPreviousTextDecoration: isLinked ? linkPreviousTextDecoration : void 0,
|
|
13722
|
+
...isLinked && {
|
|
13723
|
+
textDecoration: "underline",
|
|
13724
|
+
fill: this.config.link.defaultColor
|
|
13677
13725
|
}
|
|
13678
13726
|
});
|
|
13679
13727
|
let width = nextProps.width;
|
|
@@ -13715,6 +13763,10 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
13715
13763
|
delete cleanedAttrs.overridesMouseControl;
|
|
13716
13764
|
delete cleanedAttrs.shouldUpdateOnTransform;
|
|
13717
13765
|
delete cleanedAttrs.dragBoundFunc;
|
|
13766
|
+
if (cleanedAttrs.link) {
|
|
13767
|
+
if (typeof cleanedAttrs.linkPreviousFill === "string") cleanedAttrs.fill = cleanedAttrs.linkPreviousFill;
|
|
13768
|
+
if (typeof cleanedAttrs.linkPreviousTextDecoration === "string") cleanedAttrs.textDecoration = cleanedAttrs.linkPreviousTextDecoration;
|
|
13769
|
+
}
|
|
13718
13770
|
return {
|
|
13719
13771
|
key: attrs.id ?? "",
|
|
13720
13772
|
type: attrs.nodeType,
|
|
@@ -14120,6 +14172,94 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
14120
14172
|
this.createTextAreaDOM(textNode, areaPosition);
|
|
14121
14173
|
this.instance.emitEvent("onEnterTextNodeEditMode", { node: textNode });
|
|
14122
14174
|
}
|
|
14175
|
+
/**
|
|
14176
|
+
* Wires the hover colour swap, link cursor and click-to-open behaviour for
|
|
14177
|
+
* a rendered text node. Runs on top of (not instead of) the generic
|
|
14178
|
+
* selection-hover-halo handling in setupDefaultNodeEvents()/node.ts, the
|
|
14179
|
+
* same way connector.ts layers its own handleMouseover/handleMouseout.
|
|
14180
|
+
*/
|
|
14181
|
+
setupLinkBehavior(text) {
|
|
14182
|
+
text.handleMouseover = () => {
|
|
14183
|
+
if (!text.getAttrs().link) return;
|
|
14184
|
+
text.fill(this.config.link.hoverColor);
|
|
14185
|
+
text.getLayer()?.batchDraw();
|
|
14186
|
+
};
|
|
14187
|
+
text.handleMouseout = () => {
|
|
14188
|
+
if (!text.getAttrs().link) return;
|
|
14189
|
+
text.fill(this.config.link.defaultColor);
|
|
14190
|
+
text.getLayer()?.batchDraw();
|
|
14191
|
+
};
|
|
14192
|
+
text.defineMousePointer = () => {
|
|
14193
|
+
return text.getAttrs().link ? "pointer" : "default";
|
|
14194
|
+
};
|
|
14195
|
+
let linkClickTimeout;
|
|
14196
|
+
const clearLinkClickTimeout = () => {
|
|
14197
|
+
if (linkClickTimeout) {
|
|
14198
|
+
clearTimeout(linkClickTimeout);
|
|
14199
|
+
linkClickTimeout = void 0;
|
|
14200
|
+
}
|
|
14201
|
+
};
|
|
14202
|
+
const previousDblClick = text.dblClick.bind(text);
|
|
14203
|
+
text.dblClick = () => {
|
|
14204
|
+
clearLinkClickTimeout();
|
|
14205
|
+
previousDblClick();
|
|
14206
|
+
};
|
|
14207
|
+
text.click = ({ wasSelected, ctrlOrMetaPressed }) => {
|
|
14208
|
+
if (!text.getAttrs().link) return;
|
|
14209
|
+
if (ctrlOrMetaPressed) {
|
|
14210
|
+
clearLinkClickTimeout();
|
|
14211
|
+
this.openTextLink(text);
|
|
14212
|
+
return;
|
|
14213
|
+
}
|
|
14214
|
+
if (wasSelected) {
|
|
14215
|
+
clearLinkClickTimeout();
|
|
14216
|
+
linkClickTimeout = setTimeout(() => {
|
|
14217
|
+
linkClickTimeout = void 0;
|
|
14218
|
+
if (!this.editing) this.openTextLink(text);
|
|
14219
|
+
}, Konva.dblClickWindow);
|
|
14220
|
+
}
|
|
14221
|
+
};
|
|
14222
|
+
}
|
|
14223
|
+
openTextLink(textNode) {
|
|
14224
|
+
if (this.instance.isServerSide()) return;
|
|
14225
|
+
const link = textNode.getAttrs().link;
|
|
14226
|
+
if (typeof link !== "string" || !isValidTextLink(link)) return;
|
|
14227
|
+
window.open(link, "_blank", "noopener,noreferrer");
|
|
14228
|
+
}
|
|
14229
|
+
/**
|
|
14230
|
+
* Public API to read/set/remove the URL a text node links to. Setting an
|
|
14231
|
+
* invalid or non-http(s) URL is a no-op (see isValidTextLink()).
|
|
14232
|
+
*
|
|
14233
|
+
* The node's real fill/textDecoration are captured once into
|
|
14234
|
+
* `linkPreviousFill`/`linkPreviousTextDecoration` the first time a link is
|
|
14235
|
+
* rendered (see onRender()/onUpdate()) and restored by serialize()
|
|
14236
|
+
* whenever the node is re-serialized while linked — so they survive any
|
|
14237
|
+
* number of resizes/drags/edits while the link is active. removeLink()
|
|
14238
|
+
* relies on that: it omits `link` *and* those two bookkeeping props from
|
|
14239
|
+
* the serialized props entirely, so all three are deleted from shared
|
|
14240
|
+
* state (see updateYjsMapFromObject in managers/state.ts) rather than
|
|
14241
|
+
* persisted as `undefined`, and the node's original fill/text decoration
|
|
14242
|
+
* reappear immediately.
|
|
14243
|
+
*/
|
|
14244
|
+
getLink(nodeInstance) {
|
|
14245
|
+
const link = nodeInstance.getAttrs().link;
|
|
14246
|
+
return typeof link === "string" ? link : void 0;
|
|
14247
|
+
}
|
|
14248
|
+
setLink(nodeInstance, url) {
|
|
14249
|
+
if (!isValidTextLink(url)) return;
|
|
14250
|
+
const serialized = this.serialize(nodeInstance);
|
|
14251
|
+
serialized.props.linkPreviousFill = serialized.props.fill;
|
|
14252
|
+
serialized.props.linkPreviousTextDecoration = serialized.props.textDecoration;
|
|
14253
|
+
serialized.props.link = url;
|
|
14254
|
+
this.instance.updateNode(serialized);
|
|
14255
|
+
}
|
|
14256
|
+
removeLink(nodeInstance) {
|
|
14257
|
+
const serialized = this.serialize(nodeInstance);
|
|
14258
|
+
delete serialized.props.link;
|
|
14259
|
+
delete serialized.props.linkPreviousFill;
|
|
14260
|
+
delete serialized.props.linkPreviousTextDecoration;
|
|
14261
|
+
this.instance.updateNode(serialized);
|
|
14262
|
+
}
|
|
14123
14263
|
onDestroyInstance() {
|
|
14124
14264
|
super.onDestroyInstance();
|
|
14125
14265
|
if (!this.instance.isServerSide() && this.keyPressHandler) {
|
|
@@ -14185,7 +14325,8 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
14185
14325
|
...props.strokeEnabled && { strokeEnabled: props.strokeEnabled },
|
|
14186
14326
|
...props.stroke && { stroke: props.stroke },
|
|
14187
14327
|
...props.strokeWidth && { strokeWidth: props.strokeWidth },
|
|
14188
|
-
...props.fillAfterStrokeEnabled && { fillAfterStrokeEnabled: props.fillAfterStrokeEnabled }
|
|
14328
|
+
...props.fillAfterStrokeEnabled && { fillAfterStrokeEnabled: props.fillAfterStrokeEnabled },
|
|
14329
|
+
...props.link && { link: props.link }
|
|
14189
14330
|
} });
|
|
14190
14331
|
}
|
|
14191
14332
|
static updateNodeState(prevNodeState, nextProps) {
|
|
@@ -14210,7 +14351,8 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
14210
14351
|
...nextProps.strokeEnabled && { strokeEnabled: nextProps.strokeEnabled },
|
|
14211
14352
|
...nextProps.stroke && { stroke: nextProps.stroke },
|
|
14212
14353
|
...nextProps.strokeWidth && { strokeWidth: nextProps.strokeWidth },
|
|
14213
|
-
...nextProps.fillAfterStrokeEnabled && { fillAfterStrokeEnabled: nextProps.fillAfterStrokeEnabled }
|
|
14354
|
+
...nextProps.fillAfterStrokeEnabled && { fillAfterStrokeEnabled: nextProps.fillAfterStrokeEnabled },
|
|
14355
|
+
...nextProps.link && { link: nextProps.link }
|
|
14214
14356
|
} });
|
|
14215
14357
|
}
|
|
14216
14358
|
static getSchema() {
|
|
@@ -14244,6 +14386,9 @@ var WeaveTextNode = class extends WeaveNode {
|
|
|
14244
14386
|
]).default("top").describe("Vertical alignment of the text, can be 'top', 'middle' or 'bottom'."),
|
|
14245
14387
|
fill: z.string().default("#000000ff").describe("Fill color of the text in hex format with alpha channel (e.g. #RRGGBBAA)."),
|
|
14246
14388
|
text: z.string().default("text").describe("The actual text content of the node."),
|
|
14389
|
+
link: z.string().url().refine((value) => isValidTextLink(value), { message: "Link must be an absolute http:// or https:// URL." }).optional().describe("External URL the whole text of the node links to. When set, the text is forced underlined and coloured with the configured link colours regardless of fill/textDecoration, is clickable, and opens the URL in a new tab. Only http(s) URLs are accepted. Omit/remove to make the node plain text again."),
|
|
14390
|
+
linkPreviousFill: z.string().optional().describe("Internal bookkeeping: the fill colour the node had right before a link was set, captured automatically so it can be restored when the link is removed. Managed automatically — do not set directly."),
|
|
14391
|
+
linkPreviousTextDecoration: z.string().optional().describe("Internal bookkeeping: the textDecoration the node had right before a link was set, captured automatically so it can be restored when the link is removed. Managed automatically — do not set directly."),
|
|
14247
14392
|
strokeEnabled: z.boolean().default(false).describe("Whether the text outline is enabled."),
|
|
14248
14393
|
stroke: z.string().optional().default("#d6d6d6").describe("Color of the text outline in hex format with alpha channel (e.g. #RRGGBBAA)."),
|
|
14249
14394
|
strokeWidth: z.number().optional().default(2).describe("Width of the text outline in pixels."),
|
|
@@ -17923,21 +18068,29 @@ var WeaveFrameNode = class extends WeaveNode {
|
|
|
17923
18068
|
const WEAVE_STROKE_NODE_TYPE = "stroke";
|
|
17924
18069
|
const WEAVE_STROKE_NODE_DEFAULT_CONFIG = {
|
|
17925
18070
|
splineResolution: 8,
|
|
18071
|
+
splineTargetEdge: 1,
|
|
18072
|
+
splineMaxSteps: 48,
|
|
17926
18073
|
resamplingSpacing: 2,
|
|
17927
18074
|
isEraser: false
|
|
17928
18075
|
};
|
|
17929
18076
|
//#endregion
|
|
17930
18077
|
//#region src/nodes/stroke/stroke.ts
|
|
17931
|
-
var WeaveStrokeNode = class extends WeaveNode {
|
|
18078
|
+
var WeaveStrokeNode = class WeaveStrokeNode extends WeaveNode {
|
|
17932
18079
|
config;
|
|
17933
18080
|
nodeType = WEAVE_STROKE_NODE_TYPE;
|
|
17934
18081
|
initialize = void 0;
|
|
18082
|
+
/**
|
|
18083
|
+
* Below this chord deviation (in canvas units) a spline span is treated as
|
|
18084
|
+
* straight and emitted as a single edge. Subdividing a straight span costs
|
|
18085
|
+
* vertices without changing any pixel.
|
|
18086
|
+
*/
|
|
18087
|
+
static SPLINE_FLATNESS_EPSILON = .08;
|
|
17935
18088
|
constructor(params) {
|
|
17936
18089
|
super();
|
|
17937
18090
|
const { config } = params ?? {};
|
|
17938
18091
|
this.config = mergeExceptArrays(WEAVE_STROKE_NODE_DEFAULT_CONFIG, config);
|
|
17939
18092
|
}
|
|
17940
|
-
resamplePoints(pts, minDist =
|
|
18093
|
+
resamplePoints(pts, minDist = this.config.resamplingSpacing) {
|
|
17941
18094
|
if (pts.length < 2) return pts;
|
|
17942
18095
|
const result = [pts[0]];
|
|
17943
18096
|
let last = pts[0];
|
|
@@ -17951,29 +18104,73 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
17951
18104
|
}
|
|
17952
18105
|
return result;
|
|
17953
18106
|
}
|
|
17954
|
-
|
|
18107
|
+
/** Perpendicular distance from `p` to the segment `a`-`b`. */
|
|
18108
|
+
distanceToSegment(p, a, b) {
|
|
18109
|
+
const dx = b.x - a.x;
|
|
18110
|
+
const dy = b.y - a.y;
|
|
18111
|
+
const lengthSq = dx * dx + dy * dy;
|
|
18112
|
+
let t = lengthSq ? ((p.x - a.x) * dx + (p.y - a.y) * dy) / lengthSq : 0;
|
|
18113
|
+
t = Math.max(0, Math.min(1, t));
|
|
18114
|
+
return Math.hypot(p.x - (a.x + dx * t), p.y - (a.y + dy * t));
|
|
18115
|
+
}
|
|
18116
|
+
/**
|
|
18117
|
+
* Evaluates the uniform Catmull-Rom basis for one 4-point window at `t`.
|
|
18118
|
+
*/
|
|
18119
|
+
catmullRomAt(p0, p1, p2, p3, t) {
|
|
18120
|
+
const tt = t * t;
|
|
18121
|
+
const ttt = tt * t;
|
|
18122
|
+
const q1 = -ttt + 2 * tt - t;
|
|
18123
|
+
const q2 = 3 * ttt - 5 * tt + 2;
|
|
18124
|
+
const q3 = -3 * ttt + 4 * tt + t;
|
|
18125
|
+
const q4 = ttt - tt;
|
|
18126
|
+
return {
|
|
18127
|
+
x: (q1 * p0.x + q2 * p1.x + q3 * p2.x + q4 * p3.x) / 2,
|
|
18128
|
+
y: (q1 * p0.y + q2 * p1.y + q3 * p2.y + q4 * p3.y) / 2,
|
|
18129
|
+
pressure: (q1 * p0.pressure + q2 * p1.pressure + q3 * p2.pressure + q4 * p3.pressure) / 2
|
|
18130
|
+
};
|
|
18131
|
+
}
|
|
18132
|
+
/**
|
|
18133
|
+
* Samples a Catmull-Rom spline through `pts`, subdividing each span by its
|
|
18134
|
+
* ARC LENGTH rather than by a fixed step count.
|
|
18135
|
+
*
|
|
18136
|
+
* A fixed count is the reason a finished stroke looks faceted while the
|
|
18137
|
+
* one being drawn looks smooth: both render with the same number of
|
|
18138
|
+
* subdivisions per span, but a live stroke's control points sit ~1-2px
|
|
18139
|
+
* apart while a finalized stroke's - after Douglas-Peucker simplification
|
|
18140
|
+
* - sit a median 9-28px apart. The same 8 subdivisions therefore produce
|
|
18141
|
+
* sub-pixel edges live and edges up to ~15px long once finalized, with
|
|
18142
|
+
* visible turns between them.
|
|
18143
|
+
*
|
|
18144
|
+
* `resolution` is now the MINIMUM number of subdivisions for a curved
|
|
18145
|
+
* span (so dense, live-drawn spans behave exactly as before); long spans
|
|
18146
|
+
* get proportionally more, capped so pathological input cannot explode
|
|
18147
|
+
* the vertex count. Spans whose midpoint deviates from their chord by
|
|
18148
|
+
* less than `SPLINE_FLATNESS_EPSILON` are effectively straight and are
|
|
18149
|
+
* emitted as a single edge - subdividing a straight line adds vertices
|
|
18150
|
+
* without changing a pixel.
|
|
18151
|
+
*/
|
|
18152
|
+
getSplinePoints(pts, resolution = this.config.splineResolution) {
|
|
18153
|
+
if (pts.length < 2) return [...pts];
|
|
18154
|
+
const targetEdge = this.config.splineTargetEdge;
|
|
18155
|
+
const maxSteps = this.config.splineMaxSteps;
|
|
17955
18156
|
const result = [];
|
|
17956
18157
|
for (let i = -1; i < pts.length - 2; i++) {
|
|
17957
18158
|
const p0 = pts[Math.max(i, 0)];
|
|
17958
18159
|
const p1 = pts[i + 1];
|
|
17959
18160
|
const p2 = pts[i + 2];
|
|
17960
18161
|
const p3 = pts[Math.min(i + 3, pts.length - 1)];
|
|
17961
|
-
|
|
17962
|
-
|
|
17963
|
-
|
|
17964
|
-
|
|
17965
|
-
|
|
17966
|
-
|
|
17967
|
-
|
|
17968
|
-
const
|
|
17969
|
-
|
|
17970
|
-
|
|
17971
|
-
|
|
17972
|
-
|
|
17973
|
-
y,
|
|
17974
|
-
pressure
|
|
17975
|
-
});
|
|
17976
|
-
}
|
|
18162
|
+
const chord = Math.hypot(p2.x - p1.x, p2.y - p1.y);
|
|
18163
|
+
let deviation = 0;
|
|
18164
|
+
for (const probe of [
|
|
18165
|
+
.25,
|
|
18166
|
+
.5,
|
|
18167
|
+
.75
|
|
18168
|
+
]) {
|
|
18169
|
+
const at = this.catmullRomAt(p0, p1, p2, p3, probe);
|
|
18170
|
+
deviation = Math.max(deviation, this.distanceToSegment(at, p1, p2));
|
|
18171
|
+
}
|
|
18172
|
+
const steps = deviation < WeaveStrokeNode.SPLINE_FLATNESS_EPSILON ? 1 : Math.min(Math.max(Math.ceil(chord / targetEdge), resolution), maxSteps);
|
|
18173
|
+
for (let s = 0; s < steps; s++) result.push(this.catmullRomAt(p0, p1, p2, p3, s / steps));
|
|
17977
18174
|
}
|
|
17978
18175
|
result.push(pts[pts.length - 1]);
|
|
17979
18176
|
return result;
|
|
@@ -17991,19 +18188,26 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
17991
18188
|
* Draws a filled polygon from the accumulated left/right outline points of a
|
|
17992
18189
|
* dash segment and adds round caps at both ends.
|
|
17993
18190
|
* NOTE: mutates `rightSide` via Array.reverse() — callers must not reuse it after this call.
|
|
18191
|
+
*
|
|
18192
|
+
* The outline is NOT re-smoothed here. It used to be, back when the
|
|
18193
|
+
* centerline was sampled at a fixed subdivision count and could be coarse;
|
|
18194
|
+
* now that the centerline is subdivided by arc length, its offset curves
|
|
18195
|
+
* are already smooth, and measurement showed the extra spline pass cost
|
|
18196
|
+
* roughly half of the node's total render time while changing the drawn
|
|
18197
|
+
* result by well under a pixel (95th-percentile outline edge 1.72px vs
|
|
18198
|
+
* 1.76px; byte-identical on long, gently-curved strokes).
|
|
17994
18199
|
*/
|
|
17995
18200
|
drawDashPolygon(ctx, leftSide, rightSide, color) {
|
|
17996
18201
|
const capStartL = leftSide[0];
|
|
17997
18202
|
const capStartR = rightSide[0];
|
|
17998
18203
|
const capEndL = leftSide.at(-1);
|
|
17999
18204
|
const capEndR = rightSide.at(-1);
|
|
18000
|
-
const
|
|
18001
|
-
const smoothRight = this.getSplinePoints(rightSide.reverse(), 4);
|
|
18205
|
+
const outlineRight = rightSide.reverse();
|
|
18002
18206
|
ctx.beginPath();
|
|
18003
18207
|
ctx.fillStyle = color;
|
|
18004
|
-
ctx.moveTo(
|
|
18005
|
-
for (const p of
|
|
18006
|
-
for (const p of
|
|
18208
|
+
ctx.moveTo(leftSide[0].x, leftSide[0].y);
|
|
18209
|
+
for (const p of leftSide) ctx.lineTo(p.x, p.y);
|
|
18210
|
+
for (const p of outlineRight) ctx.lineTo(p.x, p.y);
|
|
18007
18211
|
ctx.closePath();
|
|
18008
18212
|
ctx.fill();
|
|
18009
18213
|
this.drawRoundCap(ctx, capStartL, capStartR, color);
|
|
@@ -18020,13 +18224,23 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
18020
18224
|
ctx.fill();
|
|
18021
18225
|
return;
|
|
18022
18226
|
}
|
|
18023
|
-
const filtered = this.resamplePoints(pts,
|
|
18024
|
-
const centerline = this.getSplinePoints(filtered,
|
|
18227
|
+
const filtered = this.resamplePoints(pts, this.config.resamplingSpacing);
|
|
18228
|
+
const centerline = this.getSplinePoints(filtered, this.config.splineResolution);
|
|
18025
18229
|
let dashIndex = 0;
|
|
18026
18230
|
let dashOn = true;
|
|
18027
18231
|
let dashRemaining = dash.length ? dash[0] : Infinity;
|
|
18028
18232
|
let leftSide = [];
|
|
18029
18233
|
let rightSide = [];
|
|
18234
|
+
let pendingEndLeft = null;
|
|
18235
|
+
let pendingEndRight = null;
|
|
18236
|
+
const flushRun = () => {
|
|
18237
|
+
if (!dashOn || !leftSide.length || !rightSide.length) return;
|
|
18238
|
+
if (pendingEndLeft && pendingEndRight) {
|
|
18239
|
+
leftSide.push(pendingEndLeft);
|
|
18240
|
+
rightSide.push(pendingEndRight);
|
|
18241
|
+
}
|
|
18242
|
+
this.drawDashPolygon(ctx, leftSide, rightSide, color);
|
|
18243
|
+
};
|
|
18030
18244
|
for (let i = 0; i < centerline.length - 1; i++) {
|
|
18031
18245
|
const p0 = centerline[i];
|
|
18032
18246
|
const p1 = centerline[i + 1];
|
|
@@ -18059,22 +18273,24 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
18059
18273
|
y: y0 - ny * pw0,
|
|
18060
18274
|
pressure: 1
|
|
18061
18275
|
});
|
|
18062
|
-
|
|
18276
|
+
pendingEndLeft = {
|
|
18063
18277
|
x: x1 + nx * pw1,
|
|
18064
18278
|
y: y1 + ny * pw1,
|
|
18065
18279
|
pressure: 1
|
|
18066
|
-
}
|
|
18067
|
-
|
|
18280
|
+
};
|
|
18281
|
+
pendingEndRight = {
|
|
18068
18282
|
x: x1 - nx * pw1,
|
|
18069
18283
|
y: y1 - ny * pw1,
|
|
18070
18284
|
pressure: 1
|
|
18071
|
-
}
|
|
18285
|
+
};
|
|
18072
18286
|
}
|
|
18073
18287
|
dashRemaining -= step;
|
|
18074
18288
|
if (dashRemaining <= 0) {
|
|
18075
|
-
|
|
18289
|
+
flushRun();
|
|
18076
18290
|
leftSide = [];
|
|
18077
18291
|
rightSide = [];
|
|
18292
|
+
pendingEndLeft = null;
|
|
18293
|
+
pendingEndRight = null;
|
|
18078
18294
|
dashOn = !dashOn;
|
|
18079
18295
|
dashIndex = (dashIndex + 1) % dash.length;
|
|
18080
18296
|
dashRemaining = dash[dashIndex];
|
|
@@ -18082,7 +18298,7 @@ var WeaveStrokeNode = class extends WeaveNode {
|
|
|
18082
18298
|
traveled += step;
|
|
18083
18299
|
}
|
|
18084
18300
|
}
|
|
18085
|
-
|
|
18301
|
+
flushRun();
|
|
18086
18302
|
}
|
|
18087
18303
|
drawShape(ctx, shape) {
|
|
18088
18304
|
const strokeElements = shape.getAttrs().strokeElements;
|
|
@@ -24086,7 +24302,22 @@ const BRUSH_TOOL_STATE = {
|
|
|
24086
24302
|
["IDLE"]: "idle",
|
|
24087
24303
|
["DEFINE_STROKE"]: "defineStroke"
|
|
24088
24304
|
};
|
|
24089
|
-
|
|
24305
|
+
/**
|
|
24306
|
+
* Suffix applied to a finished stroke's preview node while it is briefly
|
|
24307
|
+
* kept on screen alongside the persisted node, so the two cannot collide on
|
|
24308
|
+
* the same id.
|
|
24309
|
+
*/
|
|
24310
|
+
const PREVIEW_ID_SUFFIX = "--preview";
|
|
24311
|
+
/**
|
|
24312
|
+
* How many frames the preview of a finished stroke may wait for its
|
|
24313
|
+
* persisted counterpart to be rendered before it is removed regardless.
|
|
24314
|
+
* Bounds the handover so a preview can never be orphaned on screen.
|
|
24315
|
+
*/
|
|
24316
|
+
const PREVIEW_HANDOVER_MAX_FRAMES = 30;
|
|
24317
|
+
const BRUSH_TOOL_DEFAULT_CONFIG = {
|
|
24318
|
+
interpolationSteps: 10,
|
|
24319
|
+
simplifyTolerance: .5
|
|
24320
|
+
};
|
|
24090
24321
|
//#endregion
|
|
24091
24322
|
//#region src/actions/brush-tool/brush-tool.ts
|
|
24092
24323
|
var WeaveBrushToolAction = class extends WeaveAction {
|
|
@@ -24103,6 +24334,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24103
24334
|
prevTouchAction;
|
|
24104
24335
|
penActive = false;
|
|
24105
24336
|
lastSmoothedPressure = .5;
|
|
24337
|
+
hasPressureSample = false;
|
|
24106
24338
|
lastPointerPos = null;
|
|
24107
24339
|
lastPointerTime = 0;
|
|
24108
24340
|
predictedCount = 0;
|
|
@@ -24134,26 +24366,84 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24134
24366
|
opacity: 1
|
|
24135
24367
|
};
|
|
24136
24368
|
}
|
|
24137
|
-
|
|
24369
|
+
/**
|
|
24370
|
+
* Velocity-adaptive exponential smoothing of a single raw pressure sample.
|
|
24371
|
+
*
|
|
24372
|
+
* This is the one place pressure smoothing happens. Every sample that
|
|
24373
|
+
* becomes a stroke point must go through it - including the
|
|
24374
|
+
* high-frequency coalesced samples a stylus reports (see
|
|
24375
|
+
* `handlePointerMove`), which previously bypassed it entirely and so
|
|
24376
|
+
* landed in the stroke with their raw value, no pressure floor, and
|
|
24377
|
+
* without advancing the smoothing state for later samples.
|
|
24378
|
+
*
|
|
24379
|
+
* Timing intentionally uses `performance.now()` (not the event's own
|
|
24380
|
+
* `timeStamp`), matching the original behaviour: the two are not
|
|
24381
|
+
* guaranteed to share a time origin, and mixing them corrupts the
|
|
24382
|
+
* velocity term that drives `alpha`.
|
|
24383
|
+
*
|
|
24384
|
+
* The first sample of a stroke SEEDS the filter with its own value
|
|
24385
|
+
* rather than being blended toward the neutral 0.5 baseline. Blending
|
|
24386
|
+
* from a constant gives every stroke a warm-up transient: the filter
|
|
24387
|
+
* starts at 0.5 and converges toward the pressure actually being
|
|
24388
|
+
* applied, so a stroke drawn lighter than 0.5 renders visibly fatter at
|
|
24389
|
+
* its start (and heavier than 0.5, thinner) until the filter catches
|
|
24390
|
+
* up. Seeding removes that transient entirely - smoothing then only
|
|
24391
|
+
* ever acts between real samples, which is its actual purpose.
|
|
24392
|
+
*/
|
|
24393
|
+
smoothPressureSample(raw, clientX, clientY) {
|
|
24138
24394
|
const now = performance.now();
|
|
24139
24395
|
let velocity = 0;
|
|
24140
|
-
|
|
24141
|
-
|
|
24142
|
-
const
|
|
24396
|
+
const hasPosition = Number.isFinite(clientX) && Number.isFinite(clientY);
|
|
24397
|
+
if (hasPosition && this.lastPointerPos && now - this.lastPointerTime > 0) {
|
|
24398
|
+
const dx = clientX - this.lastPointerPos.x;
|
|
24399
|
+
const dy = clientY - this.lastPointerPos.y;
|
|
24143
24400
|
velocity = Math.hypot(dx, dy) / (now - this.lastPointerTime) * 1e3;
|
|
24144
24401
|
}
|
|
24145
|
-
this.lastPointerPos = {
|
|
24146
|
-
x:
|
|
24147
|
-
y:
|
|
24402
|
+
if (hasPosition) this.lastPointerPos = {
|
|
24403
|
+
x: clientX,
|
|
24404
|
+
y: clientY
|
|
24148
24405
|
};
|
|
24149
24406
|
this.lastPointerTime = now;
|
|
24407
|
+
const safeRaw = Number.isFinite(raw) ? raw : .5;
|
|
24408
|
+
if (!this.hasPressureSample) {
|
|
24409
|
+
this.hasPressureSample = true;
|
|
24410
|
+
this.lastSmoothedPressure = safeRaw;
|
|
24411
|
+
return Math.max(this.lastSmoothedPressure, .15);
|
|
24412
|
+
}
|
|
24150
24413
|
const alpha = Math.min(Math.max(velocity / 1500, .15), .6);
|
|
24151
|
-
|
|
24152
|
-
|
|
24153
|
-
else raw = .5;
|
|
24154
|
-
this.lastSmoothedPressure = alpha * raw + (1 - alpha) * this.lastSmoothedPressure;
|
|
24414
|
+
const smoothed = alpha * safeRaw + (1 - alpha) * this.lastSmoothedPressure;
|
|
24415
|
+
this.lastSmoothedPressure = Number.isFinite(smoothed) ? smoothed : safeRaw;
|
|
24155
24416
|
return Math.max(this.lastSmoothedPressure, .15);
|
|
24156
24417
|
}
|
|
24418
|
+
/**
|
|
24419
|
+
* Raw pressure a pointer sample reports: the device's own reading for a
|
|
24420
|
+
* pen, a neutral constant for devices that do not sense pressure.
|
|
24421
|
+
*/
|
|
24422
|
+
getRawPressure(pointerType, pressure) {
|
|
24423
|
+
if (pointerType === "pen") return (typeof pressure === "number" ? pressure : 0) || .5;
|
|
24424
|
+
return .5;
|
|
24425
|
+
}
|
|
24426
|
+
getEventPressure(e) {
|
|
24427
|
+
return this.smoothPressureSample(this.getRawPressure(e.evt.pointerType, e.evt.pressure), e.evt.clientX, e.evt.clientY);
|
|
24428
|
+
}
|
|
24429
|
+
/**
|
|
24430
|
+
* Resets the pressure-smoothing state (smoothed pressure, last known pointer
|
|
24431
|
+
* position/time, and predicted-point bookkeeping) to a neutral baseline.
|
|
24432
|
+
*
|
|
24433
|
+
* This state is scoped to a single stroke: it must be reset before the
|
|
24434
|
+
* first pressure sample of a new stroke is computed (in `handlePointerDown`,
|
|
24435
|
+
* ahead of the `getEventPressure` call for point 0), not only afterwards -
|
|
24436
|
+
* otherwise that first sample can inherit smoothing state left behind by
|
|
24437
|
+
* the previous stroke (its ending pressure, pointer position and time),
|
|
24438
|
+
* inflating the very first point's pressure.
|
|
24439
|
+
*/
|
|
24440
|
+
resetPressureSmoothingState() {
|
|
24441
|
+
this.lastSmoothedPressure = .5;
|
|
24442
|
+
this.hasPressureSample = false;
|
|
24443
|
+
this.lastPointerPos = null;
|
|
24444
|
+
this.lastPointerTime = 0;
|
|
24445
|
+
this.predictedCount = 0;
|
|
24446
|
+
}
|
|
24157
24447
|
setupEvents() {
|
|
24158
24448
|
const stage = this.instance.getStage();
|
|
24159
24449
|
this.prevTouchAction = stage.container().style.touchAction;
|
|
@@ -24185,6 +24475,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24185
24475
|
if (e?.evt?.button !== 0) return;
|
|
24186
24476
|
if (e.evt.pointerType === "touch" && this.penActive) return;
|
|
24187
24477
|
if (e.evt.pointerType === "pen") this.penActive = true;
|
|
24478
|
+
this.resetPressureSmoothingState();
|
|
24188
24479
|
const pointPressure = this.getEventPressure(e);
|
|
24189
24480
|
this.handleStartStroke(pointPressure);
|
|
24190
24481
|
e.evt.stopPropagation();
|
|
@@ -24197,16 +24488,21 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24197
24488
|
if (this.getZoomPlugin()?.isPinching()) return;
|
|
24198
24489
|
const coalescedEvents = e.evt.getCoalescedEvents ? e.evt.getCoalescedEvents() : [];
|
|
24199
24490
|
if (coalescedEvents.length > 1) {
|
|
24200
|
-
|
|
24201
|
-
|
|
24202
|
-
|
|
24203
|
-
}
|
|
24491
|
+
const samples = coalescedEvents.map((ce) => ({
|
|
24492
|
+
pressure: this.smoothPressureSample(this.getRawPressure(ce.pointerType, ce.pressure), ce.clientX, ce.clientY),
|
|
24493
|
+
isPredicted: false
|
|
24494
|
+
}));
|
|
24204
24495
|
const predictedEvents = e.evt.getPredictedEvents ? e.evt.getPredictedEvents() : [];
|
|
24205
24496
|
if (predictedEvents.length > 0) {
|
|
24206
24497
|
const last = predictedEvents[predictedEvents.length - 1];
|
|
24207
|
-
const predPressure = last.pointerType
|
|
24208
|
-
|
|
24498
|
+
const predPressure = Math.max(.15 * this.getRawPressure(last.pointerType, last.pressure) + .85 * this.lastSmoothedPressure, .15);
|
|
24499
|
+
samples.push({
|
|
24500
|
+
pressure: predPressure,
|
|
24501
|
+
sourceEvent: last,
|
|
24502
|
+
isPredicted: true
|
|
24503
|
+
});
|
|
24209
24504
|
}
|
|
24505
|
+
this.applyMovementSamples(samples);
|
|
24210
24506
|
} else {
|
|
24211
24507
|
const pointPressure = this.getEventPressure(e);
|
|
24212
24508
|
this.handleMovement(pointPressure, void 0, false);
|
|
@@ -24252,10 +24548,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24252
24548
|
};
|
|
24253
24549
|
}
|
|
24254
24550
|
handleStartStroke(pressure) {
|
|
24255
|
-
this.
|
|
24256
|
-
this.lastPointerPos = null;
|
|
24257
|
-
this.lastPointerTime = 0;
|
|
24258
|
-
this.predictedCount = 0;
|
|
24551
|
+
this.resetPressureSmoothingState();
|
|
24259
24552
|
const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
|
|
24260
24553
|
this.clickPoint = mousePoint;
|
|
24261
24554
|
this.container = container;
|
|
@@ -24284,36 +24577,60 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24284
24577
|
}
|
|
24285
24578
|
this.setState(BRUSH_TOOL_STATE.DEFINE_STROKE);
|
|
24286
24579
|
}
|
|
24287
|
-
|
|
24580
|
+
/**
|
|
24581
|
+
* Appends one or more pointer samples to the stroke in a single
|
|
24582
|
+
* read-modify-write, then renders once.
|
|
24583
|
+
*
|
|
24584
|
+
* Batching matters: a stylus reports a burst of coalesced samples per
|
|
24585
|
+
* frame, and applying them one at a time meant copying the whole point
|
|
24586
|
+
* array, recomputing the whole bounding box and issuing a full redraw
|
|
24587
|
+
* once PER SAMPLE. That is O(n) work repeated ~10x a frame, i.e.
|
|
24588
|
+
* quadratic in stroke length - which is why drawing fast could stall for
|
|
24589
|
+
* seconds. Here that O(n) work happens once per event instead.
|
|
24590
|
+
*/
|
|
24591
|
+
applyMovementSamples(samples) {
|
|
24288
24592
|
if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
|
|
24593
|
+
if (samples.length === 0) return;
|
|
24289
24594
|
const stage = this.instance.getStage();
|
|
24290
|
-
const tempStroke =
|
|
24291
|
-
if (this.measureContainer
|
|
24292
|
-
|
|
24595
|
+
const tempStroke = stage.findOne(`#${this.strokeId}`);
|
|
24596
|
+
if (!this.measureContainer || !tempStroke) return;
|
|
24597
|
+
let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
|
|
24598
|
+
for (const sample of samples) {
|
|
24599
|
+
if (sample.sourceEvent) stage.setPointersPositions(sample.sourceEvent);
|
|
24293
24600
|
const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
|
|
24294
24601
|
const currentPoint = {
|
|
24295
24602
|
x: mousePoint.x - tempStroke.x(),
|
|
24296
24603
|
y: mousePoint.y - tempStroke.y(),
|
|
24297
|
-
pressure
|
|
24604
|
+
pressure: sample.pressure
|
|
24298
24605
|
};
|
|
24299
|
-
|
|
24300
|
-
if (!isPredicted && this.predictedCount > 0) {
|
|
24606
|
+
if (!sample.isPredicted && this.predictedCount > 0) {
|
|
24301
24607
|
newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
|
|
24302
24608
|
this.predictedCount = 0;
|
|
24303
24609
|
}
|
|
24610
|
+
if (!sample.isPredicted && newStrokeElements.length === 1) newStrokeElements[0] = {
|
|
24611
|
+
...newStrokeElements[0],
|
|
24612
|
+
pressure: currentPoint.pressure
|
|
24613
|
+
};
|
|
24304
24614
|
newStrokeElements.push(currentPoint);
|
|
24305
|
-
if (isPredicted) this.predictedCount++;
|
|
24306
|
-
const box = this.getBoundingBox(newStrokeElements);
|
|
24307
|
-
tempStroke.setAttrs({
|
|
24308
|
-
width: box.width,
|
|
24309
|
-
height: box.height,
|
|
24310
|
-
x: 0,
|
|
24311
|
-
y: 0,
|
|
24312
|
-
strokeElements: newStrokeElements
|
|
24313
|
-
});
|
|
24314
|
-
const nodeHandler = this.instance.getNodeHandler("stroke");
|
|
24315
|
-
if (nodeHandler) nodeHandler.onUpdate(tempStroke, tempStroke.getAttrs());
|
|
24615
|
+
if (sample.isPredicted) this.predictedCount++;
|
|
24316
24616
|
}
|
|
24617
|
+
const box = this.getBoundingBox(newStrokeElements);
|
|
24618
|
+
tempStroke.setAttrs({
|
|
24619
|
+
width: box.width,
|
|
24620
|
+
height: box.height,
|
|
24621
|
+
x: 0,
|
|
24622
|
+
y: 0,
|
|
24623
|
+
strokeElements: newStrokeElements
|
|
24624
|
+
});
|
|
24625
|
+
const nodeHandler = this.instance.getNodeHandler("stroke");
|
|
24626
|
+
if (nodeHandler) nodeHandler.onUpdate(tempStroke, tempStroke.getAttrs());
|
|
24627
|
+
}
|
|
24628
|
+
handleMovement(pressure, predictedEvent, isPredicted = false) {
|
|
24629
|
+
this.applyMovementSamples([{
|
|
24630
|
+
pressure,
|
|
24631
|
+
sourceEvent: predictedEvent,
|
|
24632
|
+
isPredicted
|
|
24633
|
+
}]);
|
|
24317
24634
|
}
|
|
24318
24635
|
finalizeStroke(tempStroke, nodeHandler) {
|
|
24319
24636
|
const box = this.getBoundingBox(tempStroke.getAttrs().strokeElements);
|
|
@@ -24322,12 +24639,19 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24322
24639
|
newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
|
|
24323
24640
|
this.predictedCount = 0;
|
|
24324
24641
|
}
|
|
24642
|
+
if (newStrokeElements.length >= 2) {
|
|
24643
|
+
const lastIndex = newStrokeElements.length - 1;
|
|
24644
|
+
newStrokeElements[lastIndex] = {
|
|
24645
|
+
...newStrokeElements[lastIndex],
|
|
24646
|
+
pressure: newStrokeElements[lastIndex - 1].pressure
|
|
24647
|
+
};
|
|
24648
|
+
}
|
|
24325
24649
|
newStrokeElements = newStrokeElements.map((point) => ({
|
|
24326
24650
|
...point,
|
|
24327
24651
|
x: point.x - box.x,
|
|
24328
24652
|
y: point.y - box.y
|
|
24329
24653
|
}));
|
|
24330
|
-
const compressedPoints = simplify(newStrokeElements,
|
|
24654
|
+
const compressedPoints = simplify(newStrokeElements, this.config.simplifyTolerance, true);
|
|
24331
24655
|
const sw = tempStroke.getAttrs().strokeWidth ?? 1;
|
|
24332
24656
|
const finalWidth = Math.max(box.width, sw);
|
|
24333
24657
|
const finalHeight = Math.max(box.height, sw);
|
|
@@ -24340,9 +24664,44 @@ var WeaveBrushToolAction = class extends WeaveAction {
|
|
|
24340
24664
|
y: finalY,
|
|
24341
24665
|
strokeElements: compressedPoints
|
|
24342
24666
|
});
|
|
24343
|
-
const
|
|
24344
|
-
|
|
24345
|
-
|
|
24667
|
+
const strokeNodeId = tempStroke.getAttrs().id ?? "";
|
|
24668
|
+
const serializedNode = nodeHandler.serialize(tempStroke);
|
|
24669
|
+
const hasPoints = tempStroke.getAttrs().strokeElements.length >= 1;
|
|
24670
|
+
const preview = this.instance.getStage().findOne(`#${strokeNodeId}`);
|
|
24671
|
+
if (!hasPoints) {
|
|
24672
|
+
preview?.destroy();
|
|
24673
|
+
return;
|
|
24674
|
+
}
|
|
24675
|
+
if (preview) preview.setAttrs({ id: `${strokeNodeId}${PREVIEW_ID_SUFFIX}` });
|
|
24676
|
+
this.instance.addNode(serializedNode, this.container?.getAttrs().id);
|
|
24677
|
+
this.removePreviewWhenRendered(preview, strokeNodeId);
|
|
24678
|
+
}
|
|
24679
|
+
/**
|
|
24680
|
+
* Destroys the finished stroke's preview node once its persisted
|
|
24681
|
+
* counterpart has actually been rendered onto the stage, so the stroke is
|
|
24682
|
+
* never absent from the canvas between the two.
|
|
24683
|
+
*
|
|
24684
|
+
* Falls back to destroying immediately where no frame scheduler exists
|
|
24685
|
+
* (non-browser hosts), and gives up waiting after a bounded number of
|
|
24686
|
+
* frames so a preview can never be orphaned if the node never arrives.
|
|
24687
|
+
*/
|
|
24688
|
+
removePreviewWhenRendered(preview, realNodeId) {
|
|
24689
|
+
if (!preview) return;
|
|
24690
|
+
const scheduleFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : void 0;
|
|
24691
|
+
if (!scheduleFrame) {
|
|
24692
|
+
preview.destroy();
|
|
24693
|
+
return;
|
|
24694
|
+
}
|
|
24695
|
+
let framesWaited = 0;
|
|
24696
|
+
const check = () => {
|
|
24697
|
+
if (this.instance.getStage().findOne(`#${realNodeId}`) || framesWaited >= 30) {
|
|
24698
|
+
preview.destroy();
|
|
24699
|
+
return;
|
|
24700
|
+
}
|
|
24701
|
+
framesWaited++;
|
|
24702
|
+
scheduleFrame(check);
|
|
24703
|
+
};
|
|
24704
|
+
check();
|
|
24346
24705
|
}
|
|
24347
24706
|
handleEndStroke() {
|
|
24348
24707
|
const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
|
|
@@ -32954,6 +33313,6 @@ var WeaveNodesSnappingPlugin = class extends WeavePlugin {
|
|
|
32954
33313
|
}
|
|
32955
33314
|
};
|
|
32956
33315
|
//#endregion
|
|
32957
|
-
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, buildAncestorGroupIds, 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, sleep, spreadLabelProps, weavejsToYjsBinary };
|
|
33316
|
+
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, PREVIEW_HANDOVER_MAX_FRAMES, PREVIEW_ID_SUFFIX, 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_LINK_ALLOWED_PROTOCOLS, 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, buildAncestorGroupIds, 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, sleep, spreadLabelProps, weavejsToYjsBinary };
|
|
32958
33317
|
|
|
32959
33318
|
//# sourceMappingURL=types.js.map
|