@orbat-mapper/tactical-draw 0.2.0-alpha.12 → 0.2.0-alpha.13

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
@@ -1167,11 +1167,12 @@ declare class TacticalDraw {
1167
1167
  private renderMeasuresToGraphics;
1168
1168
  /**
1169
1169
  * Re-render the graphics layer on a view (zoom) change so pixel-denominated
1170
- * measures rescale live. Skipped entirely when nothing rendered carries a
1171
- * resolution-dependent size — meter geometry is zoom-independent, so a rebuild
1172
- * would be wasted layer writes. During an active edit the edited measure lives
1173
- * on the preview layer (lifted from graphics), so it is excluded here exactly
1174
- * as in `render()`; the preview's own view-change subscription rescales it.
1170
+ * and not-yet-committed label-sized measures rescale live. Skipped entirely
1171
+ * when nothing rendered still reads live view state — meter geometry with a
1172
+ * captured label size is zoom-independent, so a rebuild would be wasted
1173
+ * layer writes. During an active edit the edited measure lives on the
1174
+ * preview layer (lifted from graphics), so it is excluded here exactly as
1175
+ * in `render()`; the preview's own view-change subscription rescales it.
1175
1176
  */
1176
1177
  private readonly handleViewChange;
1177
1178
  /**
package/dist/index.mjs CHANGED
@@ -563,6 +563,21 @@ function measureUsesAdapterResolution(measure) {
563
563
  return measure.options?.[spec.pixels] !== void 0;
564
564
  }
565
565
  /**
566
+ * Whether rendering `measure` through [[renderMeasureForAdapter]] reads live
567
+ * adapter view state — either a pixel-denominated size
568
+ * ([[measureUsesAdapterResolution]]) or draw-time label sizing that
569
+ * [[withCommittedAdapterMeasureOptions]] would still capture (a
570
+ * `capturesLabelSize` kind not yet carrying `labelSizePixels`). The
571
+ * view-change rerender gates key off this so such measures rescale live;
572
+ * committed label-sized measures already carry `labelSizePixels`, stay
573
+ * zoom-independent, and keep skipping the rebuild.
574
+ */
575
+ function measureRendersFromViewState(measure) {
576
+ if (measureUsesAdapterResolution(measure)) return true;
577
+ if (!getControlMeasureMetadata(measure.kind).capturesLabelSize) return false;
578
+ return typeof measure.options?.labelSizePixels !== "number";
579
+ }
580
+ /**
566
581
  * The [[SizeAnchor]] a measure currently encodes (ADR-0020): `screen` when it
567
582
  * carries its kind's pixel-denominated size option, `ground` otherwise. Keys off
568
583
  * the same `PIXEL_SIZE_OPTIONS` table as the bake, so a consumer deciding how to
@@ -617,9 +632,11 @@ function withAdapterMeasureOptions(measure, adapter) {
617
632
  };
618
633
  }
619
634
  /**
620
- * Capture draw-time label sizing options on commit. These are stable feature
621
- * style inputs; adapters scale from them without TacticalDraw re-rendering on
622
- * every zoom.
635
+ * Capture draw-time label sizing options. These are stable feature style
636
+ * inputs; adapters scale from them without TacticalDraw re-rendering on every
637
+ * zoom. No-op if the measure already carries `labelSizePixels` (e.g. already
638
+ * committed), so it's safe to call on every render as well as on commit
639
+ * itself — see [[renderMeasureForAdapter]].
623
640
  */
624
641
  function withCommittedAdapterMeasureOptions(measure, adapter) {
625
642
  if (!getControlMeasureMetadata(measure.kind).capturesLabelSize) return measure;
@@ -641,10 +658,17 @@ function withCommittedAdapterMeasureOptions(measure, adapter) {
641
658
  * "turn a measure into features against the live map" — every TacticalDraw
642
659
  * layer write (graphics reconcile, draw preview, edit preview, commit snapshot)
643
660
  * routes through here so pixel sizing is resolved identically everywhere and no
644
- * call site can forget the injection. See [[withAdapterMeasureOptions]].
661
+ * call site can forget the injection. Composes [[withAdapterMeasureOptions]]
662
+ * (pixel size → `metersPerPixel`) with [[withCommittedAdapterMeasureOptions]]
663
+ * (label size defaults for `capturesLabelSize` kinds), so draw/edit previews
664
+ * get the same label clearance a commit would bake in — the input `measure`
665
+ * is never mutated, and callers that need the persisted/working measure to
666
+ * stay free of these render-only options must keep using that separately
667
+ * (draw/edit commit paths call [[withCommittedAdapterMeasureOptions]]
668
+ * directly to produce the value they persist).
645
669
  */
646
670
  function renderMeasureForAdapter(adapter, measure, opts) {
647
- return renderControlMeasure(withAdapterMeasureOptions(measure, adapter), opts);
671
+ return renderControlMeasure(withAdapterMeasureOptions(withCommittedAdapterMeasureOptions(measure, adapter), adapter), opts);
648
672
  }
649
673
  //#endregion
650
674
  //#region src/tactical-draw/run-interaction.ts
@@ -923,7 +947,7 @@ function runFixedLengthDraw(options) {
923
947
  ctx.writeLayer(guideLayer, guideFeatures);
924
948
  }
925
949
  function rescaleOnViewChange() {
926
- if (!measureUsesAdapterResolution({
950
+ if (!measureRendersFromViewState({
927
951
  kind,
928
952
  options: measureOptions
929
953
  })) return;
@@ -1296,7 +1320,7 @@ function runVariableLengthDraw(options) {
1296
1320
  ctx.writeLayer(guideLayer, guideFeatures);
1297
1321
  }
1298
1322
  function rescaleOnViewChange() {
1299
- if (!measureUsesAdapterResolution({
1323
+ if (!measureRendersFromViewState({
1300
1324
  kind,
1301
1325
  options: measureOptions
1302
1326
  })) return;
@@ -2107,7 +2131,7 @@ function runEdit(opts) {
2107
2131
  }
2108
2132
  function rescaleOnViewChange() {
2109
2133
  if (ctx.settled) return;
2110
- if (measureUsesAdapterResolution({
2134
+ if (measureRendersFromViewState({
2111
2135
  kind: measure.kind,
2112
2136
  options: workingOptions
2113
2137
  })) renderPreview();
@@ -3022,7 +3046,7 @@ function runGroupTransform(opts) {
3022
3046
  }
3023
3047
  function rescaleOnViewChange() {
3024
3048
  if (ctx.settled) return;
3025
- if (members.some((m) => measureUsesAdapterResolution({
3049
+ if (members.some((m) => measureRendersFromViewState({
3026
3050
  kind: m.measure.kind,
3027
3051
  options: m.measure.options
3028
3052
  }))) renderAllPreviews();
@@ -3594,17 +3618,18 @@ var TacticalDraw = class {
3594
3618
  }
3595
3619
  /**
3596
3620
  * Re-render the graphics layer on a view (zoom) change so pixel-denominated
3597
- * measures rescale live. Skipped entirely when nothing rendered carries a
3598
- * resolution-dependent size — meter geometry is zoom-independent, so a rebuild
3599
- * would be wasted layer writes. During an active edit the edited measure lives
3600
- * on the preview layer (lifted from graphics), so it is excluded here exactly
3601
- * as in `render()`; the preview's own view-change subscription rescales it.
3621
+ * and not-yet-committed label-sized measures rescale live. Skipped entirely
3622
+ * when nothing rendered still reads live view state — meter geometry with a
3623
+ * captured label size is zoom-independent, so a rebuild would be wasted
3624
+ * layer writes. During an active edit the edited measure lives on the
3625
+ * preview layer (lifted from graphics), so it is excluded here exactly as
3626
+ * in `render()`; the preview's own view-change subscription rescales it.
3602
3627
  */
3603
3628
  handleViewChange = () => {
3604
3629
  if (this.destroyed || !this.hasRendered) return;
3605
3630
  const excluded = this.excludedInteractionIds();
3606
3631
  const visible = excluded.size > 0 ? this.lastRenderedMeasures.filter((m) => !excluded.has(m.id)) : this.lastRenderedMeasures;
3607
- if (!visible.some(measureUsesAdapterResolution)) return;
3632
+ if (!visible.some(measureRendersFromViewState)) return;
3608
3633
  this.renderMeasuresToGraphics(visible);
3609
3634
  };
3610
3635
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbat-mapper/tactical-draw",
3
- "version": "0.2.0-alpha.12",
3
+ "version": "0.2.0-alpha.13",
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",
@@ -38,7 +38,7 @@
38
38
  "access": "public"
39
39
  },
40
40
  "dependencies": {
41
- "@orbat-mapper/control-measures": "^0.2.0-alpha.9"
41
+ "@orbat-mapper/control-measures": "^0.2.0-alpha.10"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@arethetypeswrong/core": "^0.18.3",