@orbat-mapper/tactical-draw 0.14.1 → 0.15.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/index.d.mts +2 -0
- package/dist/index.mjs +49 -6
- package/package.json +2 -2
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
|
|
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(
|
|
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") {
|
|
@@ -6225,6 +6246,7 @@ function runGroupTransform(opts) {
|
|
|
6225
6246
|
optionsOverride: null,
|
|
6226
6247
|
box: null,
|
|
6227
6248
|
lastBoxPixels: [],
|
|
6249
|
+
lastFeatures: [],
|
|
6228
6250
|
usesGraphicStack: isOnGraphicsLayer(graphic.id)
|
|
6229
6251
|
};
|
|
6230
6252
|
}
|
|
@@ -6241,6 +6263,7 @@ function runGroupTransform(opts) {
|
|
|
6241
6263
|
optionsOverride: null,
|
|
6242
6264
|
box: null,
|
|
6243
6265
|
lastBoxPixels: [],
|
|
6266
|
+
lastFeatures: [],
|
|
6244
6267
|
usesGraphicStack: isOnGraphicsLayer(graphic.id)
|
|
6245
6268
|
};
|
|
6246
6269
|
}
|
|
@@ -6418,6 +6441,15 @@ function runGroupTransform(opts) {
|
|
|
6418
6441
|
return box ? boxCorners(box) : null;
|
|
6419
6442
|
}
|
|
6420
6443
|
/**
|
|
6444
|
+
* The pixels a measure member's box is fitted from. A Text member renders a
|
|
6445
|
+
* single Point; use its rotated-text footprint corners so the group box grows
|
|
6446
|
+
* to contain the text extent (else the lone Point contributes a degenerate,
|
|
6447
|
+
* unscalable box).
|
|
6448
|
+
*/
|
|
6449
|
+
function measureBoxPixels(kind, features) {
|
|
6450
|
+
return (kind === "text" ? textFootprintCorners(features) : null) ?? pixelsFromFeatures(features);
|
|
6451
|
+
}
|
|
6452
|
+
/**
|
|
6421
6453
|
* Fold a box gesture's delta (`box` vs the pre-drag box) into each measure
|
|
6422
6454
|
* member that persists orientation/size as options (e.g. Text), off the
|
|
6423
6455
|
* per-member `baseOverrides` so live ticks recompute rather than compound.
|
|
@@ -6524,13 +6556,14 @@ function runGroupTransform(opts) {
|
|
|
6524
6556
|
} else {
|
|
6525
6557
|
const working = workingGraphicFor(i);
|
|
6526
6558
|
features = renderMeasureForAdapter(adapter, working, renderOpts).features;
|
|
6527
|
-
boxPixels = (working.kind
|
|
6559
|
+
boxPixels = measureBoxPixels(working.kind, features);
|
|
6528
6560
|
}
|
|
6529
6561
|
} catch {
|
|
6530
6562
|
features = [];
|
|
6531
6563
|
boxPixels = [];
|
|
6532
6564
|
}
|
|
6533
6565
|
member.lastBoxPixels = boxPixels;
|
|
6566
|
+
member.lastFeatures = features;
|
|
6534
6567
|
(member.usesGraphicStack ? workingGroups : previewGroups).push({
|
|
6535
6568
|
id: member.graphic.id,
|
|
6536
6569
|
features,
|
|
@@ -6546,7 +6579,10 @@ function runGroupTransform(opts) {
|
|
|
6546
6579
|
function rescaleOnViewChange() {
|
|
6547
6580
|
if (ctx.settled) return;
|
|
6548
6581
|
if (members.some((m) => isAnchoredMember(m) || measureRendersFromViewState(m.graphic))) renderAllPreviews();
|
|
6549
|
-
else
|
|
6582
|
+
else {
|
|
6583
|
+
for (const member of members) member.lastBoxPixels = measureBoxPixels(member.graphic.kind, member.lastFeatures);
|
|
6584
|
+
refitBoxes();
|
|
6585
|
+
}
|
|
6550
6586
|
renderHandlesLayer();
|
|
6551
6587
|
}
|
|
6552
6588
|
function renderHandlesLayer() {
|
|
@@ -9812,6 +9848,12 @@ const BUILT_IN_INTERACTION_STYLE = {
|
|
|
9812
9848
|
strokeColor: "#f59e0b",
|
|
9813
9849
|
strokeWidth: 2
|
|
9814
9850
|
},
|
|
9851
|
+
geometryHandle: {
|
|
9852
|
+
pointRadius: 5,
|
|
9853
|
+
fillColor: "#ffffff",
|
|
9854
|
+
strokeColor: "#4f7cff",
|
|
9855
|
+
strokeWidth: 2
|
|
9856
|
+
},
|
|
9815
9857
|
labelHandle: {
|
|
9816
9858
|
pointRadius: 6,
|
|
9817
9859
|
fillColor: "#7c3aed",
|
|
@@ -9836,6 +9878,7 @@ const HANDLE_SLOTS = [
|
|
|
9836
9878
|
"midpointHandle",
|
|
9837
9879
|
"optionHandle",
|
|
9838
9880
|
"unsetOptionHandle",
|
|
9881
|
+
"geometryHandle",
|
|
9839
9882
|
"labelHandle",
|
|
9840
9883
|
"scaleHandle",
|
|
9841
9884
|
"rotateHandle"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orbat-mapper/tactical-draw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
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.
|
|
42
|
+
"@orbat-mapper/control-measures": "^0.34.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"vitest": ">=4.0.0"
|