@orbat-mapper/tactical-draw 0.2.0-alpha.23 → 0.2.0-alpha.24

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
@@ -264,6 +264,12 @@ interface MapAdapter {
264
264
  */
265
265
  onViewChange(handler: () => void): void;
266
266
  offViewChange(handler: () => void): void;
267
+ /**
268
+ * The engine evaluates the meters→pixels clamp for ground-sized point
269
+ * symbols inside its own style layer, so meters-sized point symbols don't
270
+ * need view-change re-renders for size.
271
+ */
272
+ readonly scalesGroundPointSymbolsNatively?: boolean;
267
273
  /**
268
274
  * Construct an {@link EditPointerDriver} for `TacticalDraw`'s edit
269
275
  * controller. The controller subscribes to pointer events on the returned
@@ -465,7 +471,9 @@ type PointSymbolSize = {
465
471
  unit: "pixels";
466
472
  } | {
467
473
  value: number;
468
- unit: "meters";
474
+ unit: "meters"; /** Floor for the on-screen projection of the ground-based size; none when omitted. */
475
+ minPixels?: number; /** Cap on the on-screen projection of the ground-based size — typically the pixel size the symbol had when anchored to ground; unclamped when omitted. */
476
+ maxPixels?: number;
469
477
  };
470
478
  interface PointSymbolGraphicModifiers {
471
479
  /** Radians clockwise, relative to the point symbol's own orientation. */
package/dist/index.mjs CHANGED
@@ -4633,7 +4633,10 @@ function runGroupTransform(opts) {
4633
4633
  //#region src/tactical-draw/point-symbol-rendering.ts
4634
4634
  function effectivePointSymbolPixelSize(symbol, resolution) {
4635
4635
  if (symbol.size.unit === "pixels") return symbol.size.value;
4636
- return resolution !== void 0 && resolution > 0 ? symbol.size.value / resolution : symbol.size.value;
4636
+ if (resolution === void 0 || resolution <= 0) return symbol.size.value;
4637
+ const px = symbol.size.value / resolution;
4638
+ const { minPixels, maxPixels } = symbol.size;
4639
+ return Math.max(Number.isFinite(minPixels) && minPixels > 0 ? minPixels : 0, Math.min(Number.isFinite(maxPixels) && maxPixels > 0 ? maxPixels : Infinity, px));
4637
4640
  }
4638
4641
  function pointSymbolPixelScale(symbol, render, resolution) {
4639
4642
  if (!Number.isFinite(render.octagonSize) || render.octagonSize <= 0) throw new TypeError("PointSymbolRender.octagonSize must be a positive finite number");
@@ -4675,6 +4678,12 @@ function renderPointSymbolForAdapter(adapter, capability, symbol) {
4675
4678
  };
4676
4679
  }
4677
4680
  function pointSymbolFeature(symbol, render, resolution) {
4681
+ const groundSizeProperties = symbol.size.unit === "meters" ? {
4682
+ iconSizeMeters: symbol.size.value,
4683
+ iconOctagonSize: render.octagonSize,
4684
+ ...boundProperty("iconMinPixels", symbol.size.minPixels),
4685
+ ...boundProperty("iconMaxPixels", symbol.size.maxPixels)
4686
+ } : void 0;
4678
4687
  return {
4679
4688
  type: "Feature",
4680
4689
  id: `${symbol.id}:point-symbol`,
@@ -4689,10 +4698,14 @@ function pointSymbolFeature(symbol, render, resolution) {
4689
4698
  iconId: render.resourceId,
4690
4699
  iconScale: pointSymbolPixelScale(symbol, render, resolution),
4691
4700
  iconRotation: symbol.rotation,
4692
- iconOpacity: symbol.style?.opacity ?? 1
4701
+ iconOpacity: symbol.style?.opacity ?? 1,
4702
+ ...groundSizeProperties
4693
4703
  }
4694
4704
  };
4695
4705
  }
4706
+ function boundProperty(key, value) {
4707
+ return value !== void 0 && Number.isFinite(value) && value > 0 ? { [key]: value } : {};
4708
+ }
4696
4709
  //#endregion
4697
4710
  //#region src/tactical-draw/graphic-transform-controller.ts
4698
4711
  const HIT_TOLERANCE_PX$1 = 12;
@@ -5495,7 +5508,8 @@ var TacticalDraw = class {
5495
5508
  if (this.destroyed || !this.hasRendered) return;
5496
5509
  const excluded = this.excludedInteractionIds();
5497
5510
  const visible = excluded.size > 0 ? this.lastRenderedMeasures.filter((m) => !excluded.has(m.id)) : this.lastRenderedMeasures;
5498
- if (!visible.some(graphicRendersFromViewState)) return;
5511
+ const nativeGroundIconScaling = this.adapter.scalesGroundPointSymbolsNatively === true;
5512
+ if (!visible.some((g) => graphicRendersFromViewState(g, nativeGroundIconScaling))) return;
5499
5513
  this.renderMeasuresToGraphics(visible);
5500
5514
  };
5501
5515
  /**
@@ -6206,8 +6220,8 @@ var TacticalDraw = class {
6206
6220
  if (this.destroyed) throw new TacticalDrawDestroyedError();
6207
6221
  }
6208
6222
  };
6209
- function graphicRendersFromViewState(graphic) {
6210
- return isPointSymbol(graphic) ? graphic.size.unit === "meters" : measureRendersFromViewState(graphic);
6223
+ function graphicRendersFromViewState(graphic, nativeGroundIconScaling) {
6224
+ return isPointSymbol(graphic) ? graphic.size.unit === "meters" && !nativeGroundIconScaling : measureRendersFromViewState(graphic);
6211
6225
  }
6212
6226
  function normalisePointEditModes(modes) {
6213
6227
  for (const mode of modes ?? ["transform"]) if (mode !== "transform" && mode !== "delete") throw new TypeError(`Point-symbol editing does not support mode "${mode}"`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbat-mapper/tactical-draw",
3
- "version": "0.2.0-alpha.23",
3
+ "version": "0.2.0-alpha.24",
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",