@inditextech/weave-sdk 0.55.1 → 0.56.0

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.cjs CHANGED
@@ -18239,6 +18239,9 @@ function memoize(fn) {
18239
18239
  return result;
18240
18240
  };
18241
18241
  }
18242
+ function isIOS() {
18243
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
18244
+ }
18242
18245
 
18243
18246
  //#endregion
18244
18247
  //#region src/actions/selection-tool/constants.ts
@@ -19542,8 +19545,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19542
19545
  let transformerAttrs = { ...this.config.selection };
19543
19546
  const currentAttrs = this.tr.getAttrs();
19544
19547
  Object.keys(currentAttrs).forEach((key) => {
19545
- if (["rotationSnaps", "enabledAnchors"].includes(key)) this.tr.setAttr(key, []);
19546
- else this.tr.setAttr(key, void 0);
19548
+ if (["rotationSnaps", "enabledAnchors"].includes(key)) this.tr?.setAttr(key, []);
19549
+ else this.tr?.setAttr(key, void 0);
19547
19550
  });
19548
19551
  if (nodesSelected === 1) {
19549
19552
  transformerAttrs = (0, import_merge.default)(transformerAttrs, nodes[0].getTransformerProperties());
@@ -19554,8 +19557,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19554
19557
  for (const node of nodes) anchorsArrays.push(node.allowedAnchors());
19555
19558
  transformerAttrs.enabledAnchors = intersectArrays(anchorsArrays);
19556
19559
  }
19557
- this.tr.setAttrs(transformerAttrs);
19558
- this.tr.forceUpdate();
19560
+ this.tr?.setAttrs(transformerAttrs);
19561
+ this.tr?.forceUpdate();
19559
19562
  }
19560
19563
  setSelectedNodes(nodes) {
19561
19564
  this.tr.setNodes(nodes);
@@ -20599,15 +20602,15 @@ var WeaveReconciler = class {
20599
20602
  child,
20600
20603
  beforeChild
20601
20604
  }, "insertBefore ");
20602
- if (parentInstance instanceof konva.default.Layer) {
20603
- parentInstance.add(child);
20604
- const beforeChildZIndex = beforeChild.zIndex();
20605
- child.zIndex(beforeChildZIndex - 1);
20606
- }
20607
- if (parentInstance instanceof konva.default.Group) {
20608
- parentInstance.add(child);
20609
- const beforeChildZIndex = beforeChild.zIndex();
20610
- child.zIndex(beforeChildZIndex - 1);
20605
+ if (parentInstance instanceof konva.default.Layer || parentInstance instanceof konva.default.Group) {
20606
+ const children = parentInstance.getChildren();
20607
+ const fromIndex = children.indexOf(child);
20608
+ const toIndex = children.indexOf(beforeChild);
20609
+ if (fromIndex === -1 || toIndex === -1) return;
20610
+ children.splice(fromIndex, 1);
20611
+ const adjustedIndex = fromIndex < toIndex ? toIndex - 1 : toIndex;
20612
+ parentInstance.getChildren().splice(adjustedIndex, 0, child);
20613
+ parentInstance.children = parentInstance.getChildren();
20611
20614
  }
20612
20615
  },
20613
20616
  appendChild(parentInstance, child) {
@@ -21565,7 +21568,6 @@ var WeaveZIndexManager = class {
21565
21568
  }
21566
21569
  moveUp(instance) {
21567
21570
  this.logger.debug(`Moving instance with id [${instance.getAttrs().id}], up one step of z-index`);
21568
- instance.moveUp();
21569
21571
  const handler = this.instance.getNodeHandler(instance.getAttrs().nodeType);
21570
21572
  if (handler) {
21571
21573
  const nodeState = handler.serialize(instance);
@@ -21574,7 +21576,6 @@ var WeaveZIndexManager = class {
21574
21576
  }
21575
21577
  moveDown(instance) {
21576
21578
  this.logger.debug(`Moving instance with id [${instance.getAttrs().id}], down one step of z-index`);
21577
- instance.moveDown();
21578
21579
  const handler = this.instance.getNodeHandler(instance.getAttrs().nodeType);
21579
21580
  if (handler) {
21580
21581
  const nodeState = handler.serialize(instance);
@@ -21585,7 +21586,6 @@ var WeaveZIndexManager = class {
21585
21586
  const nodes = Array.isArray(instances) ? instances : [instances];
21586
21587
  const nodesDescending = nodes.toSorted((a, b) => b.zIndex() - a.zIndex());
21587
21588
  for (const node of nodesDescending) {
21588
- node.moveToBottom();
21589
21589
  const handler = this.instance.getNodeHandler(node.getAttrs().nodeType);
21590
21590
  if (handler) {
21591
21591
  const nodeState = handler.serialize(node);
@@ -21597,7 +21597,6 @@ var WeaveZIndexManager = class {
21597
21597
  const nodes = Array.isArray(instances) ? instances : [instances];
21598
21598
  const nodesAscending = nodes.toSorted((a, b) => a.zIndex() - b.zIndex());
21599
21599
  for (const node of nodesAscending) {
21600
- node.moveToTop();
21601
21600
  const handler = this.instance.getNodeHandler(node.getAttrs().nodeType);
21602
21601
  if (handler) {
21603
21602
  const nodeState = handler.serialize(node);
@@ -21924,7 +21923,7 @@ var WeaveRegisterManager = class {
21924
21923
 
21925
21924
  //#endregion
21926
21925
  //#region package.json
21927
- var version = "0.55.1";
21926
+ var version = "0.56.0";
21928
21927
 
21929
21928
  //#endregion
21930
21929
  //#region src/managers/setup.ts
@@ -22125,6 +22124,25 @@ var WeaveStoreManager = class {
22125
22124
  }
22126
22125
  };
22127
22126
 
22127
+ //#endregion
22128
+ //#region src/plugins/stage-grid/constants.ts
22129
+ const WEAVE_STAGE_GRID_KEY = "stageGrid";
22130
+ const WEAVE_GRID_TYPES = {
22131
+ ["LINES"]: "lines",
22132
+ ["DOTS"]: "dots"
22133
+ };
22134
+ const WEAVE_GRID_DEFAULT_SIZE = 50;
22135
+ const WEAVE_GRID_DEFAULT_TYPE = WEAVE_GRID_TYPES.LINES;
22136
+ const WEAVE_GRID_DEFAULT_COLOR = "rgba(0,0,0,0.1)";
22137
+ const WEAVE_GRID_DEFAULT_ORIGIN_COLOR = "rgba(255,0,0,0.1)";
22138
+ const WEAVE_GRID_DEFAULT_STROKE = .5;
22139
+ const WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO = 4;
22140
+ const WEAVE_GRID_DEFAULT_RADIUS = 1;
22141
+ const WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO = 2;
22142
+ const WEAVE_GRID_DEFAULT_MAJOR_EVERY = 10;
22143
+ const WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS = 250;
22144
+ const WEAVE_GRID_LAYER_ID = "gridLayer";
22145
+
22128
22146
  //#endregion
22129
22147
  //#region src/managers/export.ts
22130
22148
  var WeaveExportManager = class {
@@ -22133,9 +22151,30 @@ var WeaveExportManager = class {
22133
22151
  this.logger = this.instance.getChildLogger("export-manager");
22134
22152
  this.logger.debug("Export manager created");
22135
22153
  }
22154
+ fitKonvaPixelRatio(sw, sh, targetPR = 1, maxArea = 16777216) {
22155
+ if (sw <= 0 || sh <= 0) return {
22156
+ pixelRatio: 0,
22157
+ outW: 0,
22158
+ outH: 0
22159
+ };
22160
+ const desiredArea = sw * sh * targetPR * targetPR;
22161
+ let pr = targetPR;
22162
+ if (desiredArea > maxArea) pr = Math.sqrt(maxArea / (sw * sh));
22163
+ const outW = Math.max(1, Math.floor(sw * pr));
22164
+ const outH = Math.max(1, Math.floor(sh * pr));
22165
+ return {
22166
+ pixelRatio: pr,
22167
+ outW,
22168
+ outH
22169
+ };
22170
+ }
22136
22171
  exportNodes(nodes, boundingNodes, options) {
22137
22172
  return new Promise((resolve) => {
22138
22173
  const { format: format$2 = __inditextech_weave_types.WEAVE_EXPORT_FORMATS.PNG, padding = 0, pixelRatio = 1, backgroundColor = __inditextech_weave_types.WEAVE_EXPORT_BACKGROUND_COLOR } = options;
22174
+ this.getNodesSelectionPlugin()?.disable();
22175
+ this.getNodesDistanceSnappingPlugin()?.disable();
22176
+ this.getNodesEdgeSnappingPlugin()?.disable();
22177
+ this.getStageGridPlugin()?.disable();
22139
22178
  const stage = this.instance.getStage();
22140
22179
  const mainLayer = this.instance.getMainLayer();
22141
22180
  const originalPosition = {
@@ -22181,19 +22220,25 @@ var WeaveExportManager = class {
22181
22220
  }
22182
22221
  mainLayer.add(exportGroup);
22183
22222
  const backgroundRect = background.getClientRect();
22223
+ stage.batchDraw();
22224
+ const { pixelRatio: finalPixelRatio } = this.fitKonvaPixelRatio(Math.round(backgroundRect.width), Math.round(backgroundRect.height), pixelRatio);
22184
22225
  exportGroup.toImage({
22185
22226
  x: Math.round(backgroundRect.x),
22186
22227
  y: Math.round(backgroundRect.y),
22187
22228
  width: Math.round(backgroundRect.width),
22188
22229
  height: Math.round(backgroundRect.height),
22189
22230
  mimeType: format$2,
22190
- pixelRatio,
22231
+ pixelRatio: finalPixelRatio,
22191
22232
  quality: options.quality ?? 1,
22192
22233
  callback: (img) => {
22193
22234
  exportGroup.destroy();
22194
22235
  stage.position(originalPosition);
22195
22236
  stage.scale(originalScale);
22196
22237
  stage.batchDraw();
22238
+ this.getNodesSelectionPlugin()?.enable();
22239
+ this.getNodesDistanceSnappingPlugin()?.enable();
22240
+ this.getNodesEdgeSnappingPlugin()?.enable();
22241
+ this.getStageGridPlugin()?.enable();
22197
22242
  resolve(img);
22198
22243
  }
22199
22244
  });
@@ -22211,6 +22256,22 @@ var WeaveExportManager = class {
22211
22256
  canvas.remove();
22212
22257
  return URL;
22213
22258
  }
22259
+ getNodesSelectionPlugin() {
22260
+ const selectionPlugin = this.instance.getPlugin(WEAVE_NODES_SELECTION_KEY);
22261
+ return selectionPlugin;
22262
+ }
22263
+ getStageGridPlugin() {
22264
+ const gridPlugin = this.instance.getPlugin(WEAVE_STAGE_GRID_KEY);
22265
+ return gridPlugin;
22266
+ }
22267
+ getNodesEdgeSnappingPlugin() {
22268
+ const snappingPlugin = this.instance.getPlugin(WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY);
22269
+ return snappingPlugin;
22270
+ }
22271
+ getNodesDistanceSnappingPlugin() {
22272
+ const snappingPlugin = this.instance.getPlugin(WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY);
22273
+ return snappingPlugin;
22274
+ }
22214
22275
  };
22215
22276
 
22216
22277
  //#endregion
@@ -25025,6 +25086,11 @@ var WeaveFrameNode = class extends WeaveNode {
25025
25086
  //#endregion
25026
25087
  //#region src/nodes/stroke/constants.ts
25027
25088
  const WEAVE_STROKE_NODE_TYPE = "stroke";
25089
+ const WEAVE_STROKE_NODE_DEFAULT_CONFIG = {
25090
+ smoothingFactor: .1,
25091
+ resamplingSpacing: 2,
25092
+ pressureScale: 1
25093
+ };
25028
25094
 
25029
25095
  //#endregion
25030
25096
  //#region src/nodes/stroke/stroke.ts
@@ -25033,45 +25099,145 @@ var WeaveStrokeNode = class extends WeaveNode {
25033
25099
  constructor(params) {
25034
25100
  super();
25035
25101
  const { config } = params ?? {};
25036
- this.config = { transform: { ...config?.transform } };
25102
+ this.config = (0, import_merge.default)(WEAVE_STROKE_NODE_DEFAULT_CONFIG, config);
25103
+ }
25104
+ resamplePoints(pts, spacing) {
25105
+ if (pts.length < 2) return pts;
25106
+ const resampled = [pts[0]];
25107
+ for (let i = 1; i < pts.length; i++) {
25108
+ let last = resampled[resampled.length - 1];
25109
+ const current = pts[i];
25110
+ const segDist = this.dist(last, current);
25111
+ if (segDist === 0) continue;
25112
+ let remaining = segDist;
25113
+ while (remaining >= spacing) {
25114
+ const t = spacing / segDist;
25115
+ const newPt = this.lerpPoint(last, current, t);
25116
+ resampled.push(newPt);
25117
+ last = newPt;
25118
+ remaining = this.dist(last, current);
25119
+ }
25120
+ }
25121
+ return resampled;
25122
+ }
25123
+ dist(a, b) {
25124
+ const dx = b.x - a.x, dy = b.y - a.y;
25125
+ return Math.hypot(dx, dy);
25037
25126
  }
25038
- drawStroke(strokeElements, prevLineWidth, context, shape) {
25039
- const strokeWidth = shape.getAttrs().strokeWidth ?? 1;
25040
- const l = strokeElements.length - 1;
25041
- if (strokeElements.length >= 3) {
25042
- const prevPoint = strokeElements[l - 1];
25043
- const actualPoint = strokeElements[l];
25044
- const xc = (actualPoint.x + prevPoint.x) / 2;
25045
- const yc = (actualPoint.y + prevPoint.y) / 2;
25046
- context.lineWidth = Math.log(actualPoint.pressure + 1) * strokeWidth + prevLineWidth * .8;
25047
- context.quadraticCurveTo(strokeElements[l - 1].x, strokeElements[l - 1].y, xc, yc);
25048
- return context.lineWidth;
25049
- } else {
25050
- const point = strokeElements[l];
25051
- context.lineWidth = Math.log(point.pressure + 1) * strokeWidth;
25052
- return context.lineWidth;
25127
+ lerpPoint(a, b, t) {
25128
+ return {
25129
+ x: a.x + (b.x - a.x) * t,
25130
+ y: a.y + (b.y - a.y) * t,
25131
+ pressure: a.pressure + (b.pressure - a.pressure) * t
25132
+ };
25133
+ }
25134
+ buildPolygonFromPressure(pts, baseWidth) {
25135
+ if (pts.length < 2) return [];
25136
+ const left = [];
25137
+ const right = [];
25138
+ for (let i = 0; i < pts.length; i++) {
25139
+ const p = pts[i];
25140
+ const w = (baseWidth + p.pressure * this.config.pressureScale) / 2;
25141
+ let dx, dy;
25142
+ if (i === 0) {
25143
+ dx = pts[1].x - p.x;
25144
+ dy = pts[1].y - p.y;
25145
+ } else if (i === pts.length - 1) {
25146
+ dx = p.x - pts[i - 1].x;
25147
+ dy = p.y - pts[i - 1].y;
25148
+ } else {
25149
+ dx = pts[i + 1].x - pts[i - 1].x;
25150
+ dy = pts[i + 1].y - pts[i - 1].y;
25151
+ }
25152
+ const len = Math.hypot(dx, dy) || 1;
25153
+ const nx = -dy / len;
25154
+ const ny = dx / len;
25155
+ left.push({
25156
+ x: p.x + nx * w,
25157
+ y: p.y + ny * w
25158
+ });
25159
+ right.push({
25160
+ x: p.x - nx * w,
25161
+ y: p.y - ny * w
25162
+ });
25053
25163
  }
25164
+ const reversed = right.toReversed();
25165
+ return left.concat(reversed);
25166
+ }
25167
+ dashSegments(pts, pattern) {
25168
+ const segments = [];
25169
+ let patIndex = 0;
25170
+ let patDist = pattern[patIndex];
25171
+ let draw = true;
25172
+ let segPts = [pts[0]];
25173
+ for (let i = 1; i < pts.length; i++) {
25174
+ let d = this.dist(pts[i - 1], pts[i]);
25175
+ while (d >= patDist) {
25176
+ const t = patDist / d;
25177
+ const mid = this.lerpPoint(pts[i - 1], pts[i], t);
25178
+ segPts.push(mid);
25179
+ if (draw) segments.push(segPts);
25180
+ draw = !draw;
25181
+ patIndex = (patIndex + 1) % pattern.length;
25182
+ patDist = pattern[patIndex];
25183
+ segPts = [mid];
25184
+ d -= patDist;
25185
+ pts[i - 1] = mid;
25186
+ }
25187
+ segPts.push(pts[i]);
25188
+ patDist -= d;
25189
+ }
25190
+ if (draw && segPts.length > 1) segments.push(segPts);
25191
+ return segments;
25192
+ }
25193
+ catmullRomSpline(pts, spacing) {
25194
+ const curvePoints = [];
25195
+ for (let i = 0; i < pts.length - 1; i++) {
25196
+ const p0 = pts[i - 1] || pts[i];
25197
+ const p1 = pts[i];
25198
+ const p2 = pts[i + 1];
25199
+ const p3 = pts[i + 2] || p2;
25200
+ for (let t = 0; t < 1; t += spacing) {
25201
+ const t2 = t * t;
25202
+ const t3 = t2 * t;
25203
+ const x = .5 * (2 * p1.x + (-p0.x + p2.x) * t + (2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x) * t2 + (-p0.x + 3 * p1.x - 3 * p2.x + p3.x) * t3);
25204
+ const y = .5 * (2 * p1.y + (-p0.y + p2.y) * t + (2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * t2 + (-p0.y + 3 * p1.y - 3 * p2.y + p3.y) * t3);
25205
+ const pressure = .5 * (2 * p1.pressure + (-p0.pressure + p2.pressure) * t + (2 * p0.pressure - 5 * p1.pressure + 4 * p2.pressure - p3.pressure) * t2 + (-p0.pressure + 3 * p1.pressure - 3 * p2.pressure + p3.pressure) * t3);
25206
+ curvePoints.push({
25207
+ x,
25208
+ y,
25209
+ pressure
25210
+ });
25211
+ }
25212
+ }
25213
+ return curvePoints;
25054
25214
  }
25055
25215
  onRender(props) {
25056
25216
  const stroke = new konva.default.Shape({
25057
25217
  ...props,
25058
25218
  name: "node",
25059
- sceneFunc: (context, shape) => {
25060
- context.beginPath();
25061
- context.strokeStyle = shape.getAttrs().stroke ?? "black";
25062
- context.setLineDash(shape.getAttrs().dash || []);
25063
- context.lineCap = shape.getAttrs().lineCap ?? "round";
25064
- context.lineJoin = shape.getAttrs().lineJoin ?? "round";
25219
+ sceneFunc: (ctx, shape) => {
25065
25220
  const strokeElements = shape.getAttrs().strokeElements;
25066
25221
  if (strokeElements.length === 0) return;
25067
- context.moveTo(strokeElements[0].x, strokeElements[0].y);
25068
- let prevLineWidth = 0;
25069
- const strokePath = [];
25070
- strokeElements.forEach((point) => {
25071
- strokePath.push(point);
25072
- prevLineWidth = this.drawStroke(strokePath, prevLineWidth, context, shape);
25222
+ if (strokeElements.length < 2) return;
25223
+ const color = shape.getAttrs().stroke ?? "black";
25224
+ const strokeWidth = shape.getAttrs().strokeWidth ?? 1;
25225
+ const smoothPoints = this.catmullRomSpline(strokeElements, this.config.smoothingFactor);
25226
+ const evenlySpaced = this.resamplePoints(smoothPoints, this.config.resamplingSpacing);
25227
+ const dashes = this.dashSegments(evenlySpaced, shape.getAttrs().dash || []);
25228
+ dashes.forEach((segment) => {
25229
+ const poly = this.buildPolygonFromPressure(segment, strokeWidth);
25230
+ if (!poly.length) return;
25231
+ ctx.beginPath();
25232
+ ctx.moveTo(poly[0].x, poly[0].y);
25233
+ for (let i = 1; i < poly.length; i++) ctx.lineTo(poly[i].x, poly[i].y);
25234
+ ctx.strokeStyle = color;
25235
+ ctx.lineCap = shape.getAttrs().lineCap ?? "butt";
25236
+ ctx.lineJoin = shape.getAttrs().lineJoin ?? "miter";
25237
+ ctx.closePath();
25238
+ ctx.fillStyle = color;
25239
+ ctx.fill();
25073
25240
  });
25074
- context.strokeShape(shape);
25075
25241
  },
25076
25242
  dashEnabled: false,
25077
25243
  hitFunc: (context, shape) => {
@@ -26602,15 +26768,18 @@ const BRUSH_TOOL_STATE = {
26602
26768
  ["IDLE"]: "idle",
26603
26769
  ["DEFINE_STROKE"]: "defineStroke"
26604
26770
  };
26771
+ const BRUSH_TOOL_DEFAULT_CONFIG = { interpolationSteps: 10 };
26605
26772
 
26606
26773
  //#endregion
26607
26774
  //#region src/actions/brush-tool/brush-tool.ts
26608
26775
  var WeaveBrushToolAction = class extends WeaveAction {
26609
26776
  initialized = false;
26777
+ rawPoints = [];
26610
26778
  onPropsChange = void 0;
26611
26779
  onInit = void 0;
26612
- constructor() {
26780
+ constructor(params) {
26613
26781
  super();
26782
+ this.config = (0, import_merge.default)(BRUSH_TOOL_DEFAULT_CONFIG, params?.config ?? {});
26614
26783
  this.initialized = false;
26615
26784
  this.state = BRUSH_TOOL_STATE.INACTIVE;
26616
26785
  this.strokeId = null;
@@ -26655,7 +26824,8 @@ var WeaveBrushToolAction = class extends WeaveAction {
26655
26824
  this.handleStartStroke(pointPressure);
26656
26825
  e.evt.stopPropagation();
26657
26826
  };
26658
- stage.on("pointerdown touchstart", handlePointerDown);
26827
+ if (isIOS()) stage.on("touchstart", handlePointerDown);
26828
+ else stage.on("pointerdown", handlePointerDown);
26659
26829
  const handlePointerMove = (e) => {
26660
26830
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
26661
26831
  if (this.getZoomPlugin()?.isPinching()) return;
@@ -26664,14 +26834,16 @@ var WeaveBrushToolAction = class extends WeaveAction {
26664
26834
  this.handleMovement(pointPressure);
26665
26835
  e.evt.stopPropagation();
26666
26836
  };
26667
- stage.on("pointermove touchmove", handlePointerMove);
26837
+ if (isIOS()) stage.on("touchmove", handlePointerMove);
26838
+ else stage.on("pointermove", handlePointerMove);
26668
26839
  const handlePointerUp = (e) => {
26669
26840
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
26670
26841
  if (this.getZoomPlugin()?.isPinching()) return;
26671
26842
  this.handleEndStroke();
26672
26843
  e.evt.stopPropagation();
26673
26844
  };
26674
- stage.on("pointerup touchend", handlePointerUp);
26845
+ if (isIOS()) stage.on("touchend", handlePointerUp);
26846
+ else stage.on("pointerup", handlePointerUp);
26675
26847
  this.initialized = true;
26676
26848
  }
26677
26849
  setState(state) {
@@ -26729,17 +26901,44 @@ var WeaveBrushToolAction = class extends WeaveAction {
26729
26901
  }
26730
26902
  this.setState(BRUSH_TOOL_STATE.DEFINE_STROKE);
26731
26903
  }
26904
+ catmullRom1D(p0, p1, p2, p3, t) {
26905
+ const t2 = t * t;
26906
+ const t3 = t2 * t;
26907
+ return .5 * (2 * p1 + (-p0 + p2) * t + (2 * p0 - 5 * p1 + 4 * p2 - p3) * t2 + (-p0 + 3 * p1 - 3 * p2 + p3) * t3);
26908
+ }
26909
+ smoothInterpolation(last4Points, steps) {
26910
+ const [p0, p1, p2, p3] = last4Points;
26911
+ const pts = [];
26912
+ for (let i = 0; i <= steps; i++) {
26913
+ const t = i / steps;
26914
+ pts.push({
26915
+ x: this.catmullRom1D(p0.x, p1.x, p2.x, p3.x, t),
26916
+ y: this.catmullRom1D(p0.y, p1.y, p2.y, p3.y, t),
26917
+ pressure: this.catmullRom1D(p0.pressure, p1.pressure, p2.pressure, p3.pressure, t)
26918
+ });
26919
+ }
26920
+ return pts;
26921
+ }
26732
26922
  handleMovement(pressure) {
26733
26923
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
26734
26924
  const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
26735
26925
  if (this.measureContainer && tempStroke) {
26736
26926
  const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
26737
- const newStrokeElements = [...tempStroke.getAttrs().strokeElements];
26738
- newStrokeElements.push({
26927
+ const currentPoint = {
26739
26928
  x: mousePoint.x - tempStroke.x(),
26740
26929
  y: mousePoint.y - tempStroke.y(),
26741
26930
  pressure
26742
- });
26931
+ };
26932
+ this.rawPoints.push(currentPoint);
26933
+ let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
26934
+ const smoothPoints = [];
26935
+ if (isIOS()) if (this.rawPoints.length >= 4) {
26936
+ const last4 = this.rawPoints.slice(-4);
26937
+ const interpolatedPts = this.smoothInterpolation(last4, this.config.interpolationSteps);
26938
+ smoothPoints.push(...interpolatedPts);
26939
+ } else smoothPoints.push(currentPoint);
26940
+ else smoothPoints.push(currentPoint);
26941
+ newStrokeElements = [...newStrokeElements, ...smoothPoints];
26743
26942
  const box = this.getBoundingBox(newStrokeElements);
26744
26943
  tempStroke.setAttrs({
26745
26944
  width: box.width,
@@ -26776,6 +26975,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
26776
26975
  if (realNode) realNode.destroy();
26777
26976
  if (tempStroke.getAttrs().strokeElements.length >= 3) this.instance.addNode(nodeHandler.serialize(tempStroke), this.container?.getAttrs().id);
26778
26977
  }
26978
+ this.rawPoints = [];
26779
26979
  this.clickPoint = null;
26780
26980
  stage.container().style.cursor = "crosshair";
26781
26981
  stage.container().tabIndex = 1;
@@ -26811,6 +27011,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
26811
27011
  if (node) selectionPlugin.setSelectedNodes([node]);
26812
27012
  this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
26813
27013
  }
27014
+ this.rawPoints = [];
26814
27015
  this.clickPoint = null;
26815
27016
  this.setState(BRUSH_TOOL_STATE.INACTIVE);
26816
27017
  }
@@ -28041,25 +28242,6 @@ var WeaveAlignNodesToolAction = class extends WeaveAction {
28041
28242
  }
28042
28243
  };
28043
28244
 
28044
- //#endregion
28045
- //#region src/plugins/stage-grid/constants.ts
28046
- const WEAVE_STAGE_GRID_KEY = "stageGrid";
28047
- const WEAVE_GRID_TYPES = {
28048
- ["LINES"]: "lines",
28049
- ["DOTS"]: "dots"
28050
- };
28051
- const WEAVE_GRID_DEFAULT_SIZE = 50;
28052
- const WEAVE_GRID_DEFAULT_TYPE = WEAVE_GRID_TYPES.LINES;
28053
- const WEAVE_GRID_DEFAULT_COLOR = "rgba(0,0,0,0.1)";
28054
- const WEAVE_GRID_DEFAULT_ORIGIN_COLOR = "rgba(255,0,0,0.1)";
28055
- const WEAVE_GRID_DEFAULT_STROKE = .5;
28056
- const WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO = 4;
28057
- const WEAVE_GRID_DEFAULT_RADIUS = 1;
28058
- const WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO = 2;
28059
- const WEAVE_GRID_DEFAULT_MAJOR_EVERY = 10;
28060
- const WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS = 250;
28061
- const WEAVE_GRID_LAYER_ID = "gridLayer";
28062
-
28063
28245
  //#endregion
28064
28246
  //#region src/plugins/stage-grid/stage-grid.ts
28065
28247
  var WeaveStageGridPlugin = class extends WeavePlugin {
@@ -29833,6 +30015,7 @@ exports.ALIGN_NODES_TOOL_STATE = ALIGN_NODES_TOOL_STATE
29833
30015
  exports.ARROW_TOOL_ACTION_NAME = ARROW_TOOL_ACTION_NAME
29834
30016
  exports.ARROW_TOOL_STATE = ARROW_TOOL_STATE
29835
30017
  exports.BRUSH_TOOL_ACTION_NAME = BRUSH_TOOL_ACTION_NAME
30018
+ exports.BRUSH_TOOL_DEFAULT_CONFIG = BRUSH_TOOL_DEFAULT_CONFIG
29836
30019
  exports.BRUSH_TOOL_STATE = BRUSH_TOOL_STATE
29837
30020
  exports.COPY_PASTE_NODES_PLUGIN_STATE = COPY_PASTE_NODES_PLUGIN_STATE
29838
30021
  exports.ELLIPSE_TOOL_ACTION_NAME = ELLIPSE_TOOL_ACTION_NAME
@@ -29908,6 +30091,7 @@ exports.WEAVE_STAGE_DEFAULT_MODE = WEAVE_STAGE_DEFAULT_MODE
29908
30091
  exports.WEAVE_STAGE_GRID_KEY = WEAVE_STAGE_GRID_KEY
29909
30092
  exports.WEAVE_STAGE_NODE_TYPE = WEAVE_STAGE_NODE_TYPE
29910
30093
  exports.WEAVE_STAR_NODE_TYPE = WEAVE_STAR_NODE_TYPE
30094
+ exports.WEAVE_STROKE_NODE_DEFAULT_CONFIG = WEAVE_STROKE_NODE_DEFAULT_CONFIG
29911
30095
  exports.WEAVE_STROKE_NODE_TYPE = WEAVE_STROKE_NODE_TYPE
29912
30096
  exports.WEAVE_TEXT_NODE_TYPE = WEAVE_TEXT_NODE_TYPE
29913
30097
  exports.WEAVE_USERS_POINTERS_KEY = WEAVE_USERS_POINTERS_KEY
@@ -29981,6 +30165,7 @@ exports.getVisibleNodesInViewport = getVisibleNodesInViewport
29981
30165
  exports.hasFrames = hasFrames
29982
30166
  exports.hasImages = hasImages
29983
30167
  exports.intersectArrays = intersectArrays
30168
+ exports.isIOS = isIOS
29984
30169
  exports.isInShadowDOM = isInShadowDOM
29985
30170
  exports.isNodeInSelection = isNodeInSelection
29986
30171
  exports.memoize = memoize