@orbat-mapper/tactical-draw 0.14.1 → 0.15.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/index.d.mts CHANGED
@@ -699,6 +699,8 @@ interface InteractionStyle {
699
699
  * `optionHandle` when unset.
700
700
  */
701
701
  unsetOptionHandle?: HandleStyle;
702
+ /** Draw-rule handle that reshapes control points without being one, such as Sector's rotate grip. */
703
+ geometryHandle?: HandleStyle;
702
704
  /** Visible grab target for a draggable rendered text label. */
703
705
  labelHandle?: HandleStyle;
704
706
  scaleHandle?: HandleStyle;
package/dist/index.mjs CHANGED
@@ -2635,13 +2635,14 @@ function runFixedLengthDraw(options) {
2635
2635
  return;
2636
2636
  }
2637
2637
  const previewThreshold = rule?.minimumPreviewPoints ?? required;
2638
- const features = buildPreviewFeatures$1(adapter, kind, rule && raw.length >= previewThreshold ? rule.derive(raw) : raw, measureOptions, measureStyle, measureTextAmplifiers, renderOpts);
2638
+ const points = rule && raw.length >= previewThreshold ? rule.derive(raw) : raw;
2639
+ const features = buildPreviewFeatures$1(adapter, kind, points, measureOptions, measureStyle, measureTextAmplifiers, renderOpts);
2639
2640
  ctx.writeLayer(previewLayer, [{
2640
2641
  id: PREVIEW_CM_ID$1,
2641
2642
  features,
2642
2643
  iconResources: []
2643
2644
  }]);
2644
- const guidePoints = rule?.guidePoints ? rule.guidePoints(raw) : raw;
2645
+ const guidePoints = rule?.guidePoints ? rule.guidePoints(points) : raw;
2645
2646
  const guideFeatures = guideEnabled ? buildGuideFeatures(guidePoints, isAreaKind) : [];
2646
2647
  ctx.writeLayer(guideLayer, [{
2647
2648
  id: GUIDE_GROUP_ID,
@@ -3285,6 +3286,7 @@ function handleFeatureId(prefix, kind, index) {
3285
3286
  case "vertex": return `${prefix}:handle-vertex:${index}`;
3286
3287
  case "midpoint": return `${prefix}:handle-midpoint:${index}`;
3287
3288
  case "option": return `${prefix}:handle-option:${index}`;
3289
+ case "geometry": return `${prefix}:handle-geometry:${index}`;
3288
3290
  case "scale": return `${prefix}:handle-scale:${index}`;
3289
3291
  case "rotate": return `${prefix}:handle-rotate`;
3290
3292
  }
@@ -3295,6 +3297,7 @@ function handleStyleFor(kind, interactionStyle, unset = false) {
3295
3297
  case "vertex": return interactionStyle?.vertexHandle;
3296
3298
  case "midpoint": return interactionStyle?.midpointHandle;
3297
3299
  case "option": return interactionStyle?.optionHandle;
3300
+ case "geometry": return interactionStyle?.geometryHandle;
3298
3301
  case "scale": return interactionStyle?.scaleHandle;
3299
3302
  case "rotate": return interactionStyle?.rotateHandle;
3300
3303
  }
@@ -3436,6 +3439,17 @@ function beginHandleDrag(args) {
3436
3439
  return move;
3437
3440
  };
3438
3441
  if (hit.kind === "vertex") return begun("vertex", preDragPoints, dragOnePoint(preDragPoints, hit.index));
3442
+ if (hit.kind === "geometry") {
3443
+ const geometryHandles = rule?.geometryHandles;
3444
+ const handleId = hit.geometryId;
3445
+ if (!geometryHandles || handleId === void 0) throw new TypeError("A geometry handle drag needs a rule with geometryHandles");
3446
+ return begun("geometry", preDragPoints, (pixel, modifiers) => ({ points: geometryHandles.drag({
3447
+ previous: preDragPoints,
3448
+ handleId,
3449
+ position: fromPixel(pixel),
3450
+ constrainAngles: modifiers?.constrainAngles
3451
+ }) }));
3452
+ }
3439
3453
  if (hit.kind !== "midpoint") throw new TypeError(`Unsupported control-point handle kind: ${hit.kind}`);
3440
3454
  const insertIndex = hit.index + 1;
3441
3455
  const segmentEndIndex = (hit.index + 1) % preDragPoints.length;
@@ -4671,6 +4685,13 @@ function runEdit(opts) {
4671
4685
  closedRing
4672
4686
  });
4673
4687
  if (modes.includes("reshape")) {
4688
+ const geometryHandles = rule?.geometryHandles?.get(workingPoints) ?? [];
4689
+ handles.push(...geometryHandles.map((handle, index) => ({
4690
+ kind: "geometry",
4691
+ index,
4692
+ geometryId: handle.id,
4693
+ position: [...handle.position]
4694
+ })));
4674
4695
  const optionHandles = getControlMeasureOptionHandles(measure.kind, workingPoints, workingOptions, {
4675
4696
  detail: detailHandles,
4676
4697
  ...optionHandleContext()
@@ -5217,7 +5238,7 @@ function runEdit(opts) {
5217
5238
  pixel,
5218
5239
  interaction,
5219
5240
  graphicId: measure.id,
5220
- controlPointIndex,
5241
+ controlPointIndex: controlPointIndex ?? void 0,
5221
5242
  originalEvent: info?.native
5222
5243
  })?.pixel ?? pixel;
5223
5244
  }
@@ -5359,7 +5380,7 @@ function runEdit(opts) {
5359
5380
  fsm,
5360
5381
  preDragPoints,
5361
5382
  preDragOptions: workingOptions,
5362
- controlPointIndex: hit.kind === "midpoint" ? hit.index + 1 : hit.index
5383
+ controlPointIndex: hit.kind === "geometry" ? null : hit.kind === "midpoint" ? hit.index + 1 : hit.index
5363
5384
  };
5364
5385
  emitTransient("start", fsm.kind === "midpoint" ? initialPoints : preDragPoints, activeDrag.controlPointIndex);
5365
5386
  if (fsm.kind === "midpoint") {
@@ -9812,6 +9833,12 @@ const BUILT_IN_INTERACTION_STYLE = {
9812
9833
  strokeColor: "#f59e0b",
9813
9834
  strokeWidth: 2
9814
9835
  },
9836
+ geometryHandle: {
9837
+ pointRadius: 5,
9838
+ fillColor: "#ffffff",
9839
+ strokeColor: "#4f7cff",
9840
+ strokeWidth: 2
9841
+ },
9815
9842
  labelHandle: {
9816
9843
  pointRadius: 6,
9817
9844
  fillColor: "#7c3aed",
@@ -9836,6 +9863,7 @@ const HANDLE_SLOTS = [
9836
9863
  "midpointHandle",
9837
9864
  "optionHandle",
9838
9865
  "unsetOptionHandle",
9866
+ "geometryHandle",
9839
9867
  "labelHandle",
9840
9868
  "scaleHandle",
9841
9869
  "rotateHandle"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbat-mapper/tactical-draw",
3
- "version": "0.14.1",
3
+ "version": "0.15.0",
4
4
  "description": "Engine-agnostic draw/edit core for tactical control measures (MIL-STD-2525 / APP-6). The MapAdapter ABI and bring-your-own-engine entry point for the tactical-draw package family.",
5
5
  "license": "MIT",
6
6
  "author": "Orbat Mapper",
@@ -39,7 +39,7 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@orbat-mapper/control-measures": "^0.33.0"
42
+ "@orbat-mapper/control-measures": "^0.34.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "vitest": ">=4.0.0"