maplibre-gl-layers 0.18.0 → 0.19.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.
Files changed (38) hide show
  1. package/dist/SpriteLayer.d.ts +3 -3
  2. package/dist/config.d.ts +2 -2
  3. package/dist/const.d.ts +7 -4
  4. package/dist/default.d.ts +2 -2
  5. package/dist/gl/atlas.d.ts +2 -2
  6. package/dist/gl/hitTest.d.ts +3 -3
  7. package/dist/gl/mouseEvents.d.ts +36 -0
  8. package/dist/gl/shader.d.ts +2 -2
  9. package/dist/gl/text.d.ts +2 -2
  10. package/dist/gl/tracking.d.ts +36 -0
  11. package/dist/host/calculationHost.d.ts +15 -13
  12. package/dist/host/mapLibreProjectionHost.d.ts +2 -2
  13. package/dist/host/projectionHost.d.ts +2 -2
  14. package/dist/host/runtime.d.ts +2 -2
  15. package/dist/host/wasmCalculationHost.d.ts +7 -7
  16. package/dist/host/wasmHost.d.ts +2 -2
  17. package/dist/host/wasmProjectionHost.d.ts +2 -2
  18. package/dist/index.cjs +1136 -1102
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.mjs +1136 -1102
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/internalTypes.d.ts +18 -46
  24. package/dist/interpolation/degreeInterpolation.d.ts +8 -40
  25. package/dist/interpolation/distanceInterpolation.d.ts +9 -23
  26. package/dist/interpolation/easing.d.ts +2 -2
  27. package/dist/interpolation/interpolationChannels.d.ts +18 -6
  28. package/dist/interpolation/locationInterpolation.d.ts +30 -0
  29. package/dist/interpolation/rotationInterpolation.d.ts +2 -3
  30. package/dist/types.d.ts +57 -53
  31. package/dist/utils/color.d.ts +2 -2
  32. package/dist/utils/image.d.ts +2 -2
  33. package/dist/utils/looseQuadTree.d.ts +2 -2
  34. package/dist/utils/math.d.ts +38 -58
  35. package/dist/utils/utils.d.ts +2 -2
  36. package/dist/wasm/config.json.d.ts +2 -2
  37. package/package.json +6 -6
  38. package/dist/interpolation/interpolation.d.ts +0 -48
package/dist/index.cjs CHANGED
@@ -4,32 +4,24 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  /*!
6
6
  * name: maplibre-gl-layers
7
- * version: 0.18.0
7
+ * version: 0.19.0
8
8
  * description: MapLibre's layer extension library enabling the display, movement, and modification of large numbers of dynamic sprite images
9
9
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
10
10
  * license: MIT
11
11
  * repository.url: https://github.com/kekyo/maplibre-gl-layers.git
12
- * git.commit.hash: ca8392c8aa3aae7e0e4e3c871e195d49b125e481
12
+ * git.commit.hash: 7bc93c11d7855dedb8d60f140af4e413252c32a7
13
13
  */
14
14
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
15
15
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
16
16
  const UNLIMITED_SPRITE_SCALING_OPTIONS = {
17
17
  metersPerPixel: 1,
18
- zoomMin: 0,
19
- zoomMax: 30,
20
- scaleMin: 1,
21
- scaleMax: 1,
22
- spriteMinPixel: 0,
23
- spriteMaxPixel: 1e5
18
+ minScaleDistanceMeters: 0,
19
+ maxScaleDistanceMeters: Number.POSITIVE_INFINITY
24
20
  };
25
21
  const STANDARD_SPRITE_SCALING_OPTIONS = {
26
22
  metersPerPixel: 1,
27
- zoomMin: 8,
28
- zoomMax: 20,
29
- scaleMin: 0.1,
30
- scaleMax: 1,
31
- spriteMinPixel: 24,
32
- spriteMaxPixel: 100
23
+ minScaleDistanceMeters: 500,
24
+ maxScaleDistanceMeters: 1e4
33
25
  };
34
26
  const DEFAULT_TEXTURE_FILTERING_OPTIONS = {
35
27
  minFilter: "linear",
@@ -22372,6 +22364,13 @@ const __CSS_KEYWORD_COLORS = {
22372
22364
  const CSS_KEYWORD_COLORS = __CSS_KEYWORD_COLORS;
22373
22365
  const DEFAULT_BORDER_COLOR = "red";
22374
22366
  const DEFAULT_BORDER_COLOR_RGBA = CSS_KEYWORD_COLORS.red;
22367
+ const resolveOffsetInput$1 = (offset) => {
22368
+ var _a, _b;
22369
+ return {
22370
+ offsetMeters: (_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : DEFAULT_IMAGE_OFFSET.offsetMeters,
22371
+ offsetDeg: (_b = offset == null ? void 0 : offset.offsetDeg) != null ? _b : DEFAULT_IMAGE_OFFSET.offsetDeg
22372
+ };
22373
+ };
22375
22374
  const cloneSpriteLocation = (location2) => {
22376
22375
  if (location2.z === void 0) {
22377
22376
  return { lng: location2.lng, lat: location2.lat };
@@ -22471,105 +22470,45 @@ const resolveScalingOptions = (options) => {
22471
22470
  }
22472
22471
  metersPerPixel = fallbackMetersPerPixel;
22473
22472
  }
22474
- const fallbackZoomMin = Number.isFinite(base.zoomMin) ? base.zoomMin : 0;
22475
- let zoomMin = (options == null ? void 0 : options.zoomMin) !== void 0 ? options.zoomMin : fallbackZoomMin;
22476
- if (!Number.isFinite(zoomMin)) {
22477
- if ((options == null ? void 0 : options.zoomMin) !== void 0) {
22478
- warnings.push(
22479
- `zoomMin(${String(options.zoomMin)}) is not finite; using ${fallbackZoomMin}`
22480
- );
22481
- }
22482
- zoomMin = fallbackZoomMin;
22483
- }
22484
- const fallbackZoomMax = Number.isFinite(base.zoomMax) && base.zoomMax > fallbackZoomMin ? base.zoomMax : fallbackZoomMin;
22485
- let zoomMax = (options == null ? void 0 : options.zoomMax) !== void 0 ? options.zoomMax : fallbackZoomMax;
22486
- if (!Number.isFinite(zoomMax)) {
22487
- if ((options == null ? void 0 : options.zoomMax) !== void 0) {
22488
- warnings.push(
22489
- `zoomMax(${String(options.zoomMax)}) is not finite; using ${fallbackZoomMax}`
22490
- );
22491
- }
22492
- zoomMax = fallbackZoomMax;
22493
- }
22494
- if (zoomMax < zoomMin) {
22495
- warnings.push(
22496
- `zoomMax(${zoomMax}) < zoomMin(${zoomMin}); swapped values to maintain ascending order`
22497
- );
22498
- [zoomMin, zoomMax] = [zoomMax, zoomMin];
22499
- }
22500
- const fallbackScaleMin = Number.isFinite(base.scaleMin) ? base.scaleMin : 1;
22501
- let scaleMin = (options == null ? void 0 : options.scaleMin) !== void 0 ? options.scaleMin : fallbackScaleMin;
22502
- if (!Number.isFinite(scaleMin)) {
22503
- if ((options == null ? void 0 : options.scaleMin) !== void 0) {
22504
- warnings.push(
22505
- `scaleMin(${String(options.scaleMin)}) is not finite; using ${fallbackScaleMin}`
22506
- );
22507
- }
22508
- scaleMin = fallbackScaleMin;
22509
- }
22510
- if (scaleMin < 0) {
22511
- warnings.push(`scaleMin(${scaleMin}) is negative; clamped to 0`);
22512
- scaleMin = 0;
22513
- }
22514
- const fallbackScaleMax = Number.isFinite(base.scaleMax) ? base.scaleMax : 1;
22515
- let scaleMax = (options == null ? void 0 : options.scaleMax) !== void 0 ? options.scaleMax : fallbackScaleMax;
22516
- if (!Number.isFinite(scaleMax)) {
22517
- if ((options == null ? void 0 : options.scaleMax) !== void 0) {
22518
- warnings.push(
22519
- `scaleMax(${String(options.scaleMax)}) is not finite; using ${fallbackScaleMax}`
22520
- );
22521
- }
22522
- scaleMax = fallbackScaleMax;
22523
- }
22524
- if (scaleMax < 0) {
22525
- warnings.push(`scaleMax(${scaleMax}) is negative; clamped to 0`);
22526
- scaleMax = 0;
22527
- }
22528
- if (scaleMax < scaleMin) {
22529
- warnings.push(
22530
- `scaleMax(${scaleMax}) < scaleMin(${scaleMin}); swapped values to maintain ascending order`
22531
- );
22532
- [scaleMin, scaleMax] = [scaleMax, scaleMin];
22533
- }
22534
- const fallbackSpriteMin = Number.isFinite(base.spriteMinPixel) && base.spriteMinPixel >= 0 ? base.spriteMinPixel : 0;
22535
- let spriteMinPixel = (options == null ? void 0 : options.spriteMinPixel) !== void 0 ? options.spriteMinPixel : fallbackSpriteMin;
22536
- if (!Number.isFinite(spriteMinPixel)) {
22537
- if ((options == null ? void 0 : options.spriteMinPixel) !== void 0) {
22473
+ const fallbackMinDistance = base.minScaleDistanceMeters !== void 0 && Number.isFinite(base.minScaleDistanceMeters) && base.minScaleDistanceMeters > 0 ? base.minScaleDistanceMeters : 0;
22474
+ let minScaleDistanceMeters = (options == null ? void 0 : options.minScaleDistanceMeters) !== void 0 ? options.minScaleDistanceMeters : fallbackMinDistance;
22475
+ if (!Number.isFinite(minScaleDistanceMeters) || minScaleDistanceMeters < 0) {
22476
+ if ((options == null ? void 0 : options.minScaleDistanceMeters) !== void 0) {
22538
22477
  warnings.push(
22539
- `spriteMinPixel(${String(
22540
- options.spriteMinPixel
22541
- )}) is not finite; using ${fallbackSpriteMin}`
22478
+ `minScaleDistanceMeters(${String(
22479
+ options.minScaleDistanceMeters
22480
+ )}) is invalid; using ${fallbackMinDistance}`
22542
22481
  );
22543
22482
  }
22544
- spriteMinPixel = fallbackSpriteMin;
22545
- } else if (spriteMinPixel < 0) {
22546
- warnings.push(
22547
- `spriteMinPixel(${spriteMinPixel}) is negative; clamped to 0`
22548
- );
22549
- spriteMinPixel = 0;
22483
+ minScaleDistanceMeters = fallbackMinDistance;
22550
22484
  }
22551
- const fallbackSpriteMax = Number.isFinite(base.spriteMaxPixel) && base.spriteMaxPixel >= 0 ? base.spriteMaxPixel : 0;
22552
- let spriteMaxPixel = (options == null ? void 0 : options.spriteMaxPixel) !== void 0 ? options.spriteMaxPixel : fallbackSpriteMax;
22553
- if (!Number.isFinite(spriteMaxPixel)) {
22554
- if ((options == null ? void 0 : options.spriteMaxPixel) !== void 0) {
22485
+ const baseMaxDistance = base.maxScaleDistanceMeters !== void 0 && base.maxScaleDistanceMeters > 0 ? base.maxScaleDistanceMeters : Number.POSITIVE_INFINITY;
22486
+ const fallbackMaxDistance = Number.isFinite(baseMaxDistance) ? baseMaxDistance : Number.POSITIVE_INFINITY;
22487
+ let maxScaleDistanceMeters = (options == null ? void 0 : options.maxScaleDistanceMeters) !== void 0 ? options.maxScaleDistanceMeters : fallbackMaxDistance;
22488
+ const maxIsInfinite = maxScaleDistanceMeters === Number.POSITIVE_INFINITY && (options == null ? void 0 : options.maxScaleDistanceMeters) !== 0;
22489
+ if (!Number.isFinite(maxScaleDistanceMeters) && !maxIsInfinite) {
22490
+ if ((options == null ? void 0 : options.maxScaleDistanceMeters) !== void 0) {
22555
22491
  warnings.push(
22556
- `spriteMaxPixel(${String(
22557
- options.spriteMaxPixel
22558
- )}) is not finite; using ${fallbackSpriteMax}`
22492
+ `maxScaleDistanceMeters(${String(
22493
+ options.maxScaleDistanceMeters
22494
+ )}) is not finite; using ${fallbackMaxDistance}`
22559
22495
  );
22560
22496
  }
22561
- spriteMaxPixel = fallbackSpriteMax;
22562
- } else if (spriteMaxPixel < 0) {
22497
+ maxScaleDistanceMeters = fallbackMaxDistance;
22498
+ } else if (Number.isFinite(maxScaleDistanceMeters) && maxScaleDistanceMeters <= 0) {
22563
22499
  warnings.push(
22564
- `spriteMaxPixel(${spriteMaxPixel}) is negative; clamped to 0`
22500
+ `maxScaleDistanceMeters(${maxScaleDistanceMeters}) is non-positive; treated as unlimited`
22565
22501
  );
22566
- spriteMaxPixel = 0;
22502
+ maxScaleDistanceMeters = fallbackMaxDistance;
22567
22503
  }
22568
- if (spriteMinPixel > 0 && spriteMaxPixel > 0 && spriteMaxPixel < spriteMinPixel) {
22504
+ if (Number.isFinite(maxScaleDistanceMeters) && maxScaleDistanceMeters < minScaleDistanceMeters) {
22569
22505
  warnings.push(
22570
- `spriteMaxPixel(${spriteMaxPixel}) < spriteMinPixel(${spriteMinPixel}); swapped values to maintain ascending order`
22506
+ `maxScaleDistanceMeters(${maxScaleDistanceMeters}) < minScaleDistanceMeters(${minScaleDistanceMeters}); swapped values to maintain ascending order`
22571
22507
  );
22572
- [spriteMinPixel, spriteMaxPixel] = [spriteMaxPixel, spriteMinPixel];
22508
+ [minScaleDistanceMeters, maxScaleDistanceMeters] = [
22509
+ maxScaleDistanceMeters,
22510
+ minScaleDistanceMeters
22511
+ ];
22573
22512
  }
22574
22513
  if (warnings.length > 0 && typeof console !== "undefined") {
22575
22514
  const warn = (_b = console.warn) != null ? _b : null;
@@ -22579,27 +22518,26 @@ const resolveScalingOptions = (options) => {
22579
22518
  }
22580
22519
  return {
22581
22520
  metersPerPixel,
22582
- zoomMin,
22583
- zoomMax,
22584
- scaleMin,
22585
- scaleMax,
22586
- spriteMinPixel,
22587
- spriteMaxPixel
22521
+ minScaleDistanceMeters,
22522
+ maxScaleDistanceMeters
22588
22523
  };
22589
22524
  };
22590
- const calculateZoomScaleFactor = (zoom, scaling) => {
22591
- const { zoomMin, zoomMax, scaleMin, scaleMax } = scaling;
22592
- if (zoomMax <= zoomMin) {
22593
- return scaleMax;
22525
+ const calculateDistanceScaleFactor = (distanceMeters, scaling) => {
22526
+ if (!Number.isFinite(distanceMeters) || distanceMeters <= 0) {
22527
+ return 1;
22594
22528
  }
22595
- if (zoom <= zoomMin) {
22596
- return scaleMin;
22529
+ const minDistance = Math.max(0, scaling.minScaleDistanceMeters);
22530
+ const hasMax = Number.isFinite(scaling.maxScaleDistanceMeters) && scaling.maxScaleDistanceMeters > 0;
22531
+ let clamped = distanceMeters;
22532
+ if (minDistance > 0 && distanceMeters < minDistance) {
22533
+ clamped = minDistance;
22534
+ } else if (hasMax && distanceMeters > scaling.maxScaleDistanceMeters) {
22535
+ clamped = scaling.maxScaleDistanceMeters;
22597
22536
  }
22598
- if (zoom >= zoomMax) {
22599
- return scaleMax;
22537
+ if (clamped === distanceMeters || clamped === 0) {
22538
+ return 1;
22600
22539
  }
22601
- const t = (zoom - zoomMin) / (zoomMax - zoomMin);
22602
- return scaleMin + (scaleMax - scaleMin) * t;
22540
+ return distanceMeters / clamped;
22603
22541
  };
22604
22542
  const calculateMetersPerPixelAtLatitude = (zoom, latitude) => {
22605
22543
  const cosLatitude = Math.cos(latitude * DEG2RAD);
@@ -22642,49 +22580,20 @@ const calculateDistanceAndBearingMeters = (from, to) => {
22642
22580
  }
22643
22581
  return { distanceMeters, bearingDeg };
22644
22582
  };
22645
- const clampSpritePixelSize = (width, height, spriteMinPixel, spriteMaxPixel) => {
22646
- const largest = Math.max(width, height);
22647
- if (!Number.isFinite(largest) || largest <= 0) {
22648
- return { width, height, scaleAdjustment: 1 };
22649
- }
22650
- let nextWidth = width;
22651
- let nextHeight = height;
22652
- let scaleAdjustment = 1;
22653
- let adjustedLargest = largest;
22654
- if (spriteMinPixel > 0 && largest < spriteMinPixel) {
22655
- const factor = spriteMinPixel / largest;
22656
- nextWidth *= factor;
22657
- nextHeight *= factor;
22658
- scaleAdjustment *= factor;
22659
- adjustedLargest *= factor;
22660
- }
22661
- if (spriteMaxPixel > 0 && adjustedLargest > spriteMaxPixel) {
22662
- const factor = spriteMaxPixel / adjustedLargest;
22663
- nextWidth *= factor;
22664
- nextHeight *= factor;
22665
- scaleAdjustment *= factor;
22666
- }
22667
- return { width: nextWidth, height: nextHeight, scaleAdjustment };
22668
- };
22669
- const calculateBillboardPixelDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, zoomScaleFactor, effectivePixelsPerMeter, spriteMinPixel, spriteMaxPixel) => {
22583
+ const calculateBillboardPixelDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, distanceScaleFactor, effectivePixelsPerMeter) => {
22670
22584
  if (!imageWidth || !imageHeight || imageWidth <= 0 || imageHeight <= 0 || baseMetersPerPixel <= 0 || effectivePixelsPerMeter <= 0) {
22671
22585
  return { width: 0, height: 0, scaleAdjustment: 1 };
22672
22586
  }
22673
- const scaleFactor = baseMetersPerPixel * imageScale * zoomScaleFactor * effectivePixelsPerMeter;
22674
- const rawWidth = ensureFinite(imageWidth * scaleFactor);
22675
- const rawHeight = ensureFinite(imageHeight * scaleFactor);
22676
- return clampSpritePixelSize(
22677
- rawWidth,
22678
- rawHeight,
22679
- spriteMinPixel,
22680
- spriteMaxPixel
22681
- );
22587
+ const scaleFactor = baseMetersPerPixel * imageScale * distanceScaleFactor * effectivePixelsPerMeter;
22588
+ const width = ensureFinite(imageWidth * scaleFactor);
22589
+ const height = ensureFinite(imageHeight * scaleFactor);
22590
+ return { width, height, scaleAdjustment: 1 };
22682
22591
  };
22683
- const calculateBillboardOffsetPixels = (offset, imageScale, zoomScaleFactor, effectivePixelsPerMeter, sizeScaleAdjustment = 1) => {
22684
- var _a, _b;
22685
- const offsetMeters = ((_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : 0) * imageScale * zoomScaleFactor;
22592
+ const calculateBillboardOffsetPixels = (offset, imageScale, distanceScaleFactor, effectivePixelsPerMeter, sizeScaleAdjustment = 1) => {
22593
+ const resolved = resolveOffsetInput$1(offset);
22594
+ const offsetMeters = resolved.offsetMeters * imageScale * distanceScaleFactor;
22686
22595
  const offsetPixels = offsetMeters * effectivePixelsPerMeter * sizeScaleAdjustment;
22687
- const offsetRad = ((_b = offset == null ? void 0 : offset.offsetDeg) != null ? _b : 0) * DEG2RAD;
22596
+ const offsetRad = resolved.offsetDeg * DEG2RAD;
22688
22597
  return {
22689
22598
  x: offsetPixels * Math.sin(offsetRad),
22690
22599
  y: offsetPixels * Math.cos(offsetRad)
@@ -22707,40 +22616,14 @@ const calculateBillboardAnchorShiftPixels = (halfWidth, halfHeight, anchor, tota
22707
22616
  const shiftY = -anchorX * sinR - anchorY * cosR;
22708
22617
  return { x: shiftX, y: shiftY };
22709
22618
  };
22710
- const calculateSurfaceWorldDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, zoomScaleFactor, options) => {
22711
- var _a, _b;
22619
+ const calculateSurfaceWorldDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, distanceScaleFactor) => {
22712
22620
  if (!imageWidth || !imageHeight || imageWidth <= 0 || imageHeight <= 0 || baseMetersPerPixel <= 0) {
22713
22621
  return { width: 0, height: 0, scaleAdjustment: 1 };
22714
22622
  }
22715
- const scaleFactor = baseMetersPerPixel * imageScale * zoomScaleFactor;
22716
- let width = ensureFinite(imageWidth * scaleFactor);
22717
- let height = ensureFinite(imageHeight * scaleFactor);
22718
- let scaleAdjustment = 1;
22719
- const effectivePixelsPerMeter = (options == null ? void 0 : options.effectivePixelsPerMeter) !== void 0 ? options.effectivePixelsPerMeter : 0;
22720
- const spriteMinPixel = (_a = options == null ? void 0 : options.spriteMinPixel) != null ? _a : 0;
22721
- const spriteMaxPixel = (_b = options == null ? void 0 : options.spriteMaxPixel) != null ? _b : 0;
22722
- if (effectivePixelsPerMeter > 0 && Number.isFinite(effectivePixelsPerMeter) && (spriteMinPixel > 0 || spriteMaxPixel > 0)) {
22723
- const largestMeters = Math.max(width, height);
22724
- if (largestMeters > 0 && Number.isFinite(largestMeters)) {
22725
- const largestPixels = largestMeters * effectivePixelsPerMeter;
22726
- if (Number.isFinite(largestPixels) && largestPixels > 0) {
22727
- let scale2 = 1;
22728
- if (spriteMinPixel > 0 && largestPixels < spriteMinPixel) {
22729
- scale2 = spriteMinPixel / largestPixels;
22730
- }
22731
- const scaledLargest = largestPixels * scale2;
22732
- if (spriteMaxPixel > 0 && scaledLargest > spriteMaxPixel) {
22733
- scale2 = spriteMaxPixel / largestPixels;
22734
- }
22735
- if (scale2 !== 1) {
22736
- width *= scale2;
22737
- height *= scale2;
22738
- scaleAdjustment *= scale2;
22739
- }
22740
- }
22741
- }
22742
- }
22743
- return { width, height, scaleAdjustment };
22623
+ const scaleFactor = baseMetersPerPixel * imageScale * distanceScaleFactor;
22624
+ const width = ensureFinite(imageWidth * scaleFactor);
22625
+ const height = ensureFinite(imageHeight * scaleFactor);
22626
+ return { width, height, scaleAdjustment: 1 };
22744
22627
  };
22745
22628
  const calculateSurfaceAnchorShiftMeters = (halfWidthMeters, halfHeightMeters, anchor, totalRotateDeg) => {
22746
22629
  var _a, _b;
@@ -22759,13 +22642,13 @@ const calculateSurfaceAnchorShiftMeters = (halfWidthMeters, halfHeightMeters, an
22759
22642
  const north = -anchorEast * sinR - anchorNorth * cosR;
22760
22643
  return { east, north };
22761
22644
  };
22762
- const calculateSurfaceOffsetMeters = (offset, imageScale, zoomScaleFactor, sizeScaleAdjustment = 1) => {
22763
- var _a, _b;
22764
- const offsetMeters = ((_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : 0) * imageScale * zoomScaleFactor;
22645
+ const calculateSurfaceOffsetMeters = (offset, imageScale, distanceScaleFactor, sizeScaleAdjustment = 1) => {
22646
+ const resolved = resolveOffsetInput$1(offset);
22647
+ const offsetMeters = resolved.offsetMeters * imageScale * distanceScaleFactor;
22765
22648
  if (offsetMeters === 0) {
22766
22649
  return { east: 0, north: 0 };
22767
22650
  }
22768
- const rad = ((_b = offset == null ? void 0 : offset.offsetDeg) != null ? _b : 0) * DEG2RAD;
22651
+ const rad = resolved.offsetDeg * DEG2RAD;
22769
22652
  return {
22770
22653
  east: offsetMeters * Math.sin(rad) * sizeScaleAdjustment,
22771
22654
  north: offsetMeters * Math.cos(rad) * sizeScaleAdjustment
@@ -22859,10 +22742,8 @@ const calculateBillboardCenterPosition = (params) => {
22859
22742
  imageHeight,
22860
22743
  baseMetersPerPixel,
22861
22744
  imageScale,
22862
- zoomScaleFactor,
22745
+ distanceScaleFactor,
22863
22746
  effectivePixelsPerMeter,
22864
- spriteMinPixel,
22865
- spriteMaxPixel,
22866
22747
  totalRotateDeg,
22867
22748
  anchor,
22868
22749
  offset
@@ -22872,10 +22753,8 @@ const calculateBillboardCenterPosition = (params) => {
22872
22753
  imageHeight,
22873
22754
  baseMetersPerPixel,
22874
22755
  imageScale,
22875
- zoomScaleFactor,
22876
- effectivePixelsPerMeter,
22877
- spriteMinPixel,
22878
- spriteMaxPixel
22756
+ distanceScaleFactor,
22757
+ effectivePixelsPerMeter
22879
22758
  );
22880
22759
  const halfWidth = pixelDims.width / 2;
22881
22760
  const halfHeight = pixelDims.height / 2;
@@ -22888,7 +22767,7 @@ const calculateBillboardCenterPosition = (params) => {
22888
22767
  const offsetShift = calculateBillboardOffsetPixels(
22889
22768
  offset,
22890
22769
  imageScale,
22891
- zoomScaleFactor,
22770
+ distanceScaleFactor,
22892
22771
  effectivePixelsPerMeter,
22893
22772
  pixelDims.scaleAdjustment
22894
22773
  );
@@ -23001,13 +22880,10 @@ const calculateSurfaceCenterPosition = (params) => {
23001
22880
  imageHeight,
23002
22881
  baseMetersPerPixel,
23003
22882
  imageScale,
23004
- zoomScaleFactor,
22883
+ distanceScaleFactor,
23005
22884
  totalRotateDeg,
23006
22885
  anchor,
23007
22886
  offset,
23008
- effectivePixelsPerMeter = 0,
23009
- spriteMinPixel = 0,
23010
- spriteMaxPixel = 0,
23011
22887
  project,
23012
22888
  projectToClipSpace,
23013
22889
  drawingBufferWidth,
@@ -23038,12 +22914,7 @@ const calculateSurfaceCenterPosition = (params) => {
23038
22914
  imageHeight,
23039
22915
  baseMetersPerPixel,
23040
22916
  imageScale,
23041
- zoomScaleFactor,
23042
- {
23043
- effectivePixelsPerMeter,
23044
- spriteMinPixel,
23045
- spriteMaxPixel
23046
- }
22917
+ distanceScaleFactor
23047
22918
  );
23048
22919
  const halfWidthMeters = worldDims.width / 2;
23049
22920
  const halfHeightMeters = worldDims.height / 2;
@@ -23056,7 +22927,7 @@ const calculateSurfaceCenterPosition = (params) => {
23056
22927
  const offsetMeters = calculateSurfaceOffsetMeters(
23057
22928
  offset,
23058
22929
  imageScale,
23059
- zoomScaleFactor,
22930
+ distanceScaleFactor,
23060
22931
  worldDims.scaleAdjustment
23061
22932
  );
23062
22933
  const totalDisplacement = {
@@ -23151,6 +23022,17 @@ const clampOpacity = (value) => {
23151
23022
  }
23152
23023
  return value;
23153
23024
  };
23025
+ const normalizeDuration$2 = (durationMs) => Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 0;
23026
+ const normalizeOptions$2 = (options) => {
23027
+ var _a;
23028
+ const resolved = resolveEasing(options.easing);
23029
+ return {
23030
+ durationMs: normalizeDuration$2(options.durationMs),
23031
+ easingFunc: resolved.func,
23032
+ easingParam: resolved.param,
23033
+ mode: (_a = options.mode) != null ? _a : "feedback"
23034
+ };
23035
+ };
23154
23036
  const computeFeedforwardTarget = (previous, next) => {
23155
23037
  var _a, _b;
23156
23038
  if (!previous) {
@@ -23159,27 +23041,16 @@ const computeFeedforwardTarget = (previous, next) => {
23159
23041
  const prevZ = (_a = previous.z) != null ? _a : 0;
23160
23042
  const nextZ = (_b = next.z) != null ? _b : 0;
23161
23043
  const hasZ = previous.z !== void 0 || next.z !== void 0;
23162
- const target = {
23044
+ return {
23163
23045
  lng: next.lng + (next.lng - previous.lng),
23164
23046
  lat: next.lat + (next.lat - previous.lat),
23165
- // Only extrapolate altitude when either point includes z; otherwise we maintain the 2D assumption.
23166
23047
  z: hasZ ? nextZ + (nextZ - prevZ) : void 0
23167
23048
  };
23168
- return target;
23169
23049
  };
23170
- const normalizeOptions$2 = (options) => {
23171
- var _a;
23172
- return {
23173
- durationMs: Math.max(0, options.durationMs),
23174
- mode: (_a = options.mode) != null ? _a : "feedback",
23175
- easing: options.easing
23176
- };
23177
- };
23178
- const createInterpolationState = (params) => {
23050
+ const createLocationInterpolationState = (params) => {
23179
23051
  const { currentLocation, lastCommandLocation, nextCommandLocation } = params;
23180
23052
  const options = normalizeOptions$2(params.options);
23181
23053
  const from = cloneSpriteLocation(currentLocation);
23182
- const resolvedEasing = resolveEasing(options.easing);
23183
23054
  const commandTarget = cloneSpriteLocation(nextCommandLocation);
23184
23055
  let pathTarget;
23185
23056
  if (options.mode === "feedforward") {
@@ -23192,8 +23063,8 @@ const createInterpolationState = (params) => {
23192
23063
  const state = {
23193
23064
  mode: options.mode,
23194
23065
  durationMs: options.durationMs,
23195
- easingFunc: resolvedEasing.func,
23196
- easingParam: resolvedEasing.param,
23066
+ easingFunc: options.easingFunc,
23067
+ easingParam: options.easingParam,
23197
23068
  startTimestamp: -1,
23198
23069
  from,
23199
23070
  to: commandTarget,
@@ -23201,17 +23072,15 @@ const createInterpolationState = (params) => {
23201
23072
  };
23202
23073
  return { state, requiresInterpolation };
23203
23074
  };
23204
- const evaluateInterpolation = (params) => {
23075
+ const evaluateLocationInterpolation = (state, timestamp) => {
23205
23076
  var _a;
23206
- const { state } = params;
23207
23077
  const easingFn = state.easingFunc;
23208
- const timestamp = Number.isFinite(params.timestamp) ? params.timestamp : Date.now();
23209
23078
  const duration = Math.max(0, state.durationMs);
23210
23079
  const effectiveStart = state.startTimestamp >= 0 ? state.startTimestamp : timestamp;
23211
23080
  const target = (_a = state.pathTarget) != null ? _a : state.to;
23212
23081
  if (duration === 0 || spriteLocationsEqual(state.from, target)) {
23213
23082
  return {
23214
- location: cloneSpriteLocation(state.to),
23083
+ value: cloneSpriteLocation(state.to),
23215
23084
  completed: true,
23216
23085
  effectiveStartTimestamp: effectiveStart
23217
23086
  };
@@ -23219,14 +23088,155 @@ const evaluateInterpolation = (params) => {
23219
23088
  const elapsed = timestamp - effectiveStart;
23220
23089
  const rawProgress = duration <= 0 ? 1 : elapsed / duration;
23221
23090
  const eased = easingFn(rawProgress);
23222
- const location2 = lerpSpriteLocation(state.from, target, eased);
23091
+ const value = lerpSpriteLocation(state.from, target, eased);
23223
23092
  const completed = rawProgress >= 1;
23224
23093
  return {
23225
- location: location2,
23094
+ value,
23226
23095
  completed,
23227
23096
  effectiveStartTimestamp: effectiveStart
23228
23097
  };
23229
23098
  };
23099
+ const evaluateLocationInterpolationsBatch = (states, timestamp) => {
23100
+ if (!states.length) {
23101
+ return [];
23102
+ }
23103
+ return states.map((state) => evaluateLocationInterpolation(state, timestamp));
23104
+ };
23105
+ const collectLocationInterpolationWorkItems = (sprite, workItems) => {
23106
+ const state = sprite.location.interpolation.state;
23107
+ if (state) {
23108
+ workItems.push({ ...state, sprite });
23109
+ }
23110
+ };
23111
+ const applyLocationInterpolationEvaluations = (workItems, evaluations, timestamp) => {
23112
+ var _a;
23113
+ let active = false;
23114
+ for (let index = 0; index < workItems.length; index += 1) {
23115
+ const item = workItems[index];
23116
+ const { sprite } = item;
23117
+ const evaluation = (_a = evaluations[index]) != null ? _a : evaluateLocationInterpolation(item, timestamp);
23118
+ if (item.startTimestamp < 0) {
23119
+ const effectiveStart = evaluation.effectiveStartTimestamp;
23120
+ item.startTimestamp = effectiveStart;
23121
+ const interpolationState = sprite.location.interpolation.state;
23122
+ if (interpolationState && interpolationState.startTimestamp < 0) {
23123
+ interpolationState.startTimestamp = effectiveStart;
23124
+ }
23125
+ }
23126
+ sprite.location.current = evaluation.value;
23127
+ if (evaluation.completed) {
23128
+ sprite.location.current = cloneSpriteLocation(item.to);
23129
+ sprite.location.from = void 0;
23130
+ sprite.location.to = void 0;
23131
+ sprite.location.interpolation.state = null;
23132
+ } else {
23133
+ active = true;
23134
+ }
23135
+ }
23136
+ return active;
23137
+ };
23138
+ const clamp01$2 = (value) => Math.min(1, Math.max(0, value));
23139
+ const clamp255 = (value) => Math.min(255, Math.max(0, value));
23140
+ const normalizeRgba = (r, g, b, a) => [
23141
+ clamp255(r) / 255,
23142
+ clamp255(g) / 255,
23143
+ clamp255(b) / 255,
23144
+ clamp01$2(a)
23145
+ ];
23146
+ const tryParseHexColor = (value) => {
23147
+ var _a;
23148
+ const match = /^#([0-9a-f]{3,8})$/i.exec(value.trim());
23149
+ if (!match) {
23150
+ return null;
23151
+ }
23152
+ const hex = (_a = match[1]) != null ? _a : "";
23153
+ if (hex.length === 3) {
23154
+ const [r, g, b] = hex.split("").map((c) => parseInt(c + c, 16));
23155
+ return normalizeRgba(r, g, b, 1);
23156
+ }
23157
+ if (hex.length === 4) {
23158
+ const [r, g, b, a] = hex.split("").map((c) => parseInt(c + c, 16));
23159
+ return normalizeRgba(r, g, b, a / 255);
23160
+ }
23161
+ if (hex.length === 6 || hex.length === 8) {
23162
+ const r = parseInt(hex.slice(0, 2), 16);
23163
+ const g = parseInt(hex.slice(2, 4), 16);
23164
+ const b = parseInt(hex.slice(4, 6), 16);
23165
+ const a = hex.length === 8 ? parseInt(hex.slice(6, 8), 16) : 255;
23166
+ return normalizeRgba(r, g, b, a / 255);
23167
+ }
23168
+ return null;
23169
+ };
23170
+ const parseChannel = (value) => {
23171
+ if (value.endsWith("%")) {
23172
+ const percent = Number.parseFloat(value.slice(0, -1));
23173
+ if (!Number.isFinite(percent)) {
23174
+ return Number.NaN;
23175
+ }
23176
+ return clamp255(percent / 100 * 255);
23177
+ }
23178
+ const number = Number.parseFloat(value);
23179
+ return Number.isFinite(number) ? clamp255(number) : Number.NaN;
23180
+ };
23181
+ const parseAlpha = (value) => {
23182
+ if (value === void 0) {
23183
+ return 1;
23184
+ }
23185
+ if (value.endsWith("%")) {
23186
+ const percent = Number.parseFloat(value.slice(0, -1));
23187
+ if (!Number.isFinite(percent)) {
23188
+ return Number.NaN;
23189
+ }
23190
+ return clamp01$2(percent / 100);
23191
+ }
23192
+ const number = Number.parseFloat(value);
23193
+ return Number.isFinite(number) ? clamp01$2(number) : Number.NaN;
23194
+ };
23195
+ const tryParseRgbFunction = (value) => {
23196
+ var _a, _b, _c;
23197
+ const match = /^rgba?\(\s*([^,]+?)\s*,\s*([^,]+?)\s*,\s*([^,]+?)(?:\s*,\s*([^,]+?)\s*)?\)$/i.exec(
23198
+ value.trim()
23199
+ );
23200
+ if (!match) {
23201
+ return null;
23202
+ }
23203
+ const r = parseChannel((_a = match[1]) != null ? _a : "");
23204
+ const g = parseChannel((_b = match[2]) != null ? _b : "");
23205
+ const b = parseChannel((_c = match[3]) != null ? _c : "");
23206
+ const a = parseAlpha(match[4]);
23207
+ if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) || Number.isNaN(a)) {
23208
+ return null;
23209
+ }
23210
+ return normalizeRgba(r, g, b, a);
23211
+ };
23212
+ const parseColorUsingDom = (value) => {
23213
+ var _a;
23214
+ if (typeof document === "undefined") {
23215
+ return null;
23216
+ }
23217
+ const element = document.createElement("div");
23218
+ element.style.color = "";
23219
+ element.style.color = value;
23220
+ if (!element.style.color) {
23221
+ return null;
23222
+ }
23223
+ return (_a = tryParseRgbFunction(element.style.color)) != null ? _a : tryParseHexColor(element.style.color.toLowerCase());
23224
+ };
23225
+ const parseCssColorToRgba = (color, fallback2) => {
23226
+ var _a, _b, _c;
23227
+ if (!color) {
23228
+ return fallback2;
23229
+ }
23230
+ const trimmed = color.trim();
23231
+ if (trimmed.length === 0) {
23232
+ return fallback2;
23233
+ }
23234
+ const keyword = CSS_KEYWORD_COLORS[trimmed.toLowerCase()];
23235
+ if (keyword) {
23236
+ return keyword;
23237
+ }
23238
+ return (_c = (_b = (_a = tryParseHexColor(trimmed)) != null ? _a : tryParseRgbFunction(trimmed)) != null ? _b : parseColorUsingDom(trimmed)) != null ? _c : fallback2;
23239
+ };
23230
23240
  const NUMERIC_EPSILON = 1e-6;
23231
23241
  const normalizeDuration$1 = (durationMs) => Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 0;
23232
23242
  const normalizeDelta = (delta) => {
@@ -23279,7 +23289,7 @@ const createDegreeInterpolationState = (params) => {
23279
23289
  requiresInterpolation
23280
23290
  };
23281
23291
  };
23282
- const clamp01$2 = (value) => {
23292
+ const clamp01$1 = (value) => {
23283
23293
  if (!Number.isFinite(value)) {
23284
23294
  return 1;
23285
23295
  }
@@ -23291,11 +23301,9 @@ const clamp01$2 = (value) => {
23291
23301
  }
23292
23302
  return value;
23293
23303
  };
23294
- const evaluateDegreeInterpolation = (params) => {
23304
+ const evaluateDegreeInterpolation = (state, timestamp) => {
23295
23305
  var _a;
23296
- const { state } = params;
23297
23306
  const targetValue = (_a = state.pathTarget) != null ? _a : state.to;
23298
- const timestamp = Number.isFinite(params.timestamp) ? params.timestamp : Date.now();
23299
23307
  const duration = Math.max(0, state.durationMs);
23300
23308
  const effectiveStart = state.startTimestamp >= 0 ? state.startTimestamp : timestamp;
23301
23309
  if (duration === 0 || Math.abs(targetValue - state.from) <= NUMERIC_EPSILON) {
@@ -23307,7 +23315,7 @@ const evaluateDegreeInterpolation = (params) => {
23307
23315
  }
23308
23316
  const elapsed = timestamp - effectiveStart;
23309
23317
  const rawProgress = duration <= 0 ? 1 : elapsed / duration;
23310
- const eased = clamp01$2(state.easingFunc(rawProgress));
23318
+ const eased = clamp01$1(state.easingFunc(rawProgress));
23311
23319
  const interpolated = state.from + (targetValue - state.from) * eased;
23312
23320
  const completed = rawProgress >= 1;
23313
23321
  return {
@@ -23318,10 +23326,15 @@ const evaluateDegreeInterpolation = (params) => {
23318
23326
  };
23319
23327
  const DEGREE_INTERPOLATION_CHANNELS = {
23320
23328
  rotation: {
23321
- resolveInterpolation: (image) => image.rotateDeg.interpolation,
23329
+ resolveInterpolation: (image) => image.finalRotateDeg.interpolation,
23322
23330
  normalize: normalizeAngleDeg,
23323
23331
  applyValue: (image, value) => {
23324
- image.displayedRotateDeg = value;
23332
+ image.finalRotateDeg.current = normalizeAngleDeg(value);
23333
+ },
23334
+ applyFinalValue: (image, value) => {
23335
+ image.finalRotateDeg.current = normalizeAngleDeg(value);
23336
+ image.finalRotateDeg.from = void 0;
23337
+ image.finalRotateDeg.to = void 0;
23325
23338
  }
23326
23339
  },
23327
23340
  offsetDeg: {
@@ -23343,17 +23356,17 @@ const collectDegreeInterpolationWorkItems = (image, workItems) => {
23343
23356
  const rotationState = DEGREE_INTERPOLATION_CHANNELS.rotation.resolveInterpolation(image).state;
23344
23357
  if (rotationState) {
23345
23358
  workItems.push({
23359
+ ...rotationState,
23346
23360
  descriptor: DEGREE_INTERPOLATION_CHANNELS.rotation,
23347
- image,
23348
- state: rotationState
23361
+ image
23349
23362
  });
23350
23363
  }
23351
23364
  const offsetState = DEGREE_INTERPOLATION_CHANNELS.offsetDeg.resolveInterpolation(image).state;
23352
23365
  if (offsetState) {
23353
23366
  workItems.push({
23367
+ ...offsetState,
23354
23368
  descriptor: DEGREE_INTERPOLATION_CHANNELS.offsetDeg,
23355
- image,
23356
- state: offsetState
23369
+ image
23357
23370
  });
23358
23371
  }
23359
23372
  };
@@ -23362,158 +23375,25 @@ const applyDegreeInterpolationEvaluations = (workItems, evaluations, timestamp)
23362
23375
  let active = false;
23363
23376
  for (let index = 0; index < workItems.length; index += 1) {
23364
23377
  const item = workItems[index];
23365
- const evaluation = (_a = evaluations[index]) != null ? _a : evaluateDegreeInterpolation({
23366
- state: item.state,
23367
- timestamp
23368
- });
23369
- if (item.state.startTimestamp < 0) {
23370
- item.state.startTimestamp = evaluation.effectiveStartTimestamp;
23378
+ const evaluation = (_a = evaluations[index]) != null ? _a : evaluateDegreeInterpolation(item, timestamp);
23379
+ if (item.startTimestamp < 0) {
23380
+ item.startTimestamp = evaluation.effectiveStartTimestamp;
23371
23381
  }
23372
23382
  const normalize = (_b = item.descriptor.normalize) != null ? _b : ((value) => value);
23373
23383
  const applyFinalValue = (_c = item.descriptor.applyFinalValue) != null ? _c : item.descriptor.applyValue;
23374
23384
  const interpolatedValue = normalize(evaluation.value);
23375
23385
  item.descriptor.applyValue(item.image, interpolatedValue);
23376
23386
  if (evaluation.completed) {
23377
- const finalValue = normalize(item.state.to);
23387
+ const finalValue = normalize(item.to);
23378
23388
  applyFinalValue(item.image, finalValue);
23379
23389
  updateDegreeInterpolationState(item.image, item.descriptor, null);
23380
23390
  } else {
23381
- updateDegreeInterpolationState(item.image, item.descriptor, item.state);
23391
+ updateDegreeInterpolationState(item.image, item.descriptor, item);
23382
23392
  active = true;
23383
23393
  }
23384
23394
  }
23385
23395
  return active;
23386
23396
  };
23387
- const resolveRotationTarget = (params) => {
23388
- const options = params.options;
23389
- const targetAngle = normalizeAngleDeg(params.targetAngleDeg);
23390
- const currentAngle = normalizeAngleDeg(params.currentAngleDeg);
23391
- const previousCommandAngleDeg = params.previousCommandAngleDeg !== void 0 ? normalizeAngleDeg(params.previousCommandAngleDeg) : void 0;
23392
- if (!options || options.durationMs <= 0) {
23393
- return {
23394
- nextAngleDeg: targetAngle,
23395
- interpolationState: null
23396
- };
23397
- }
23398
- const { state, requiresInterpolation } = createDegreeInterpolationState({
23399
- currentValue: currentAngle,
23400
- targetValue: targetAngle,
23401
- previousCommandValue: previousCommandAngleDeg,
23402
- options
23403
- });
23404
- if (!requiresInterpolation) {
23405
- return {
23406
- nextAngleDeg: targetAngle,
23407
- interpolationState: null
23408
- };
23409
- }
23410
- return {
23411
- nextAngleDeg: currentAngle,
23412
- interpolationState: state
23413
- };
23414
- };
23415
- const clamp01$1 = (value) => Math.min(1, Math.max(0, value));
23416
- const clamp255 = (value) => Math.min(255, Math.max(0, value));
23417
- const normalizeRgba = (r, g, b, a) => [
23418
- clamp255(r) / 255,
23419
- clamp255(g) / 255,
23420
- clamp255(b) / 255,
23421
- clamp01$1(a)
23422
- ];
23423
- const tryParseHexColor = (value) => {
23424
- var _a;
23425
- const match = /^#([0-9a-f]{3,8})$/i.exec(value.trim());
23426
- if (!match) {
23427
- return null;
23428
- }
23429
- const hex = (_a = match[1]) != null ? _a : "";
23430
- if (hex.length === 3) {
23431
- const [r, g, b] = hex.split("").map((c) => parseInt(c + c, 16));
23432
- return normalizeRgba(r, g, b, 1);
23433
- }
23434
- if (hex.length === 4) {
23435
- const [r, g, b, a] = hex.split("").map((c) => parseInt(c + c, 16));
23436
- return normalizeRgba(r, g, b, a / 255);
23437
- }
23438
- if (hex.length === 6 || hex.length === 8) {
23439
- const r = parseInt(hex.slice(0, 2), 16);
23440
- const g = parseInt(hex.slice(2, 4), 16);
23441
- const b = parseInt(hex.slice(4, 6), 16);
23442
- const a = hex.length === 8 ? parseInt(hex.slice(6, 8), 16) : 255;
23443
- return normalizeRgba(r, g, b, a / 255);
23444
- }
23445
- return null;
23446
- };
23447
- const parseChannel = (value) => {
23448
- if (value.endsWith("%")) {
23449
- const percent = Number.parseFloat(value.slice(0, -1));
23450
- if (!Number.isFinite(percent)) {
23451
- return Number.NaN;
23452
- }
23453
- return clamp255(percent / 100 * 255);
23454
- }
23455
- const number = Number.parseFloat(value);
23456
- return Number.isFinite(number) ? clamp255(number) : Number.NaN;
23457
- };
23458
- const parseAlpha = (value) => {
23459
- if (value === void 0) {
23460
- return 1;
23461
- }
23462
- if (value.endsWith("%")) {
23463
- const percent = Number.parseFloat(value.slice(0, -1));
23464
- if (!Number.isFinite(percent)) {
23465
- return Number.NaN;
23466
- }
23467
- return clamp01$1(percent / 100);
23468
- }
23469
- const number = Number.parseFloat(value);
23470
- return Number.isFinite(number) ? clamp01$1(number) : Number.NaN;
23471
- };
23472
- const tryParseRgbFunction = (value) => {
23473
- var _a, _b, _c;
23474
- const match = /^rgba?\(\s*([^,]+?)\s*,\s*([^,]+?)\s*,\s*([^,]+?)(?:\s*,\s*([^,]+?)\s*)?\)$/i.exec(
23475
- value.trim()
23476
- );
23477
- if (!match) {
23478
- return null;
23479
- }
23480
- const r = parseChannel((_a = match[1]) != null ? _a : "");
23481
- const g = parseChannel((_b = match[2]) != null ? _b : "");
23482
- const b = parseChannel((_c = match[3]) != null ? _c : "");
23483
- const a = parseAlpha(match[4]);
23484
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) || Number.isNaN(a)) {
23485
- return null;
23486
- }
23487
- return normalizeRgba(r, g, b, a);
23488
- };
23489
- const parseColorUsingDom = (value) => {
23490
- var _a;
23491
- if (typeof document === "undefined") {
23492
- return null;
23493
- }
23494
- const element = document.createElement("div");
23495
- element.style.color = "";
23496
- element.style.color = value;
23497
- if (!element.style.color) {
23498
- return null;
23499
- }
23500
- return (_a = tryParseRgbFunction(element.style.color)) != null ? _a : tryParseHexColor(element.style.color.toLowerCase());
23501
- };
23502
- const parseCssColorToRgba = (color, fallback2) => {
23503
- var _a, _b, _c;
23504
- if (!color) {
23505
- return fallback2;
23506
- }
23507
- const trimmed = color.trim();
23508
- if (trimmed.length === 0) {
23509
- return fallback2;
23510
- }
23511
- const keyword = CSS_KEYWORD_COLORS[trimmed.toLowerCase()];
23512
- if (keyword) {
23513
- return keyword;
23514
- }
23515
- return (_c = (_b = (_a = tryParseHexColor(trimmed)) != null ? _a : tryParseRgbFunction(trimmed)) != null ? _b : parseColorUsingDom(trimmed)) != null ? _c : fallback2;
23516
- };
23517
23397
  const DISTANCE_EPSILON = 1e-6;
23518
23398
  const normalizeDuration = (durationMs) => Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 0;
23519
23399
  const normalizeOptions = (options) => {
@@ -23566,11 +23446,9 @@ const clamp01 = (value) => {
23566
23446
  }
23567
23447
  return value;
23568
23448
  };
23569
- const evaluateDistanceInterpolation = (params) => {
23449
+ const evaluateDistanceInterpolation = (state, timestamp) => {
23570
23450
  var _a;
23571
- const { state } = params;
23572
23451
  const targetValue = (_a = state.pathTarget) != null ? _a : state.to;
23573
- const timestamp = Number.isFinite(params.timestamp) ? params.timestamp : Date.now();
23574
23452
  const duration = Math.max(0, state.durationMs);
23575
23453
  const effectiveStart = state.startTimestamp >= 0 ? state.startTimestamp : timestamp;
23576
23454
  if (duration === 0 || Math.abs(targetValue - state.from) <= DISTANCE_EPSILON) {
@@ -23604,80 +23482,105 @@ const DISTANCE_INTERPOLATION_CHANNELS = {
23604
23482
  }
23605
23483
  },
23606
23484
  opacity: {
23607
- resolveInterpolation: (image) => image.opacity.interpolation,
23485
+ resolveInterpolation: (image) => image.finalOpacity.interpolation,
23608
23486
  normalize: clampOpacity,
23609
23487
  applyValue: (image, value) => {
23610
- image.opacity.current = value;
23488
+ image.finalOpacity.current = value;
23611
23489
  },
23612
23490
  applyFinalValue: (image, value) => {
23613
- image.opacity.current = value;
23614
- image.opacity.from = void 0;
23615
- image.opacity.to = void 0;
23491
+ image.finalOpacity.current = value;
23492
+ image.finalOpacity.from = void 0;
23493
+ image.finalOpacity.to = void 0;
23616
23494
  }
23617
23495
  }
23618
23496
  };
23619
- const collectDistanceInterpolationWorkItems = (image, workItems, options) => {
23620
- var _a, _b;
23621
- const includeOffsetMeters = (_a = options == null ? void 0 : options.includeOffsetMeters) != null ? _a : true;
23622
- const includeOpacity = (_b = options == null ? void 0 : options.includeOpacity) != null ? _b : true;
23497
+ const updateDistanceInterpolationState = (image, descriptor, nextState) => {
23498
+ descriptor.resolveInterpolation(image).state = nextState;
23499
+ };
23500
+ const collectDistanceInterpolationWorkItems = (image, workItems, includeOffsetMeters, includeOpacity) => {
23623
23501
  const offsetMetersState = DISTANCE_INTERPOLATION_CHANNELS.offsetMeters.resolveInterpolation(
23624
23502
  image
23625
23503
  ).state;
23626
23504
  if (includeOffsetMeters && offsetMetersState) {
23627
23505
  workItems.push({
23506
+ ...offsetMetersState,
23628
23507
  descriptor: DISTANCE_INTERPOLATION_CHANNELS.offsetMeters,
23629
- image,
23630
- state: offsetMetersState
23508
+ image
23631
23509
  });
23632
23510
  }
23633
23511
  const opacityState = DISTANCE_INTERPOLATION_CHANNELS.opacity.resolveInterpolation(image).state;
23634
23512
  if (includeOpacity && opacityState) {
23635
23513
  workItems.push({
23514
+ ...opacityState,
23636
23515
  descriptor: DISTANCE_INTERPOLATION_CHANNELS.opacity,
23637
- image,
23638
- state: opacityState
23516
+ image
23639
23517
  });
23640
23518
  }
23641
23519
  };
23642
- const updateDistanceInterpolationState = (image, descriptor, nextState) => {
23643
- descriptor.resolveInterpolation(image).state = nextState;
23644
- };
23645
23520
  const applyDistanceInterpolationEvaluations = (workItems, evaluations, timestamp) => {
23646
23521
  var _a, _b, _c;
23647
23522
  let active = false;
23648
23523
  for (let index = 0; index < workItems.length; index += 1) {
23649
23524
  const item = workItems[index];
23650
- const evaluation = (_a = evaluations[index]) != null ? _a : evaluateDistanceInterpolation({
23651
- state: item.state,
23652
- timestamp
23653
- });
23654
- if (item.state.startTimestamp < 0) {
23655
- item.state.startTimestamp = evaluation.effectiveStartTimestamp;
23525
+ const evaluation = (_a = evaluations[index]) != null ? _a : evaluateDistanceInterpolation(item, timestamp);
23526
+ const interpolationState = item.descriptor.resolveInterpolation(
23527
+ item.image
23528
+ ).state;
23529
+ if (interpolationState && interpolationState.startTimestamp < 0) {
23530
+ interpolationState.startTimestamp = evaluation.effectiveStartTimestamp;
23531
+ }
23532
+ if (item.startTimestamp < 0) {
23533
+ item.startTimestamp = evaluation.effectiveStartTimestamp;
23656
23534
  }
23657
23535
  const normalize = (_b = item.descriptor.normalize) != null ? _b : ((value) => value);
23658
23536
  const applyFinalValue = (_c = item.descriptor.applyFinalValue) != null ? _c : item.descriptor.applyValue;
23659
23537
  const interpolatedValue = normalize(evaluation.value);
23660
23538
  item.descriptor.applyValue(item.image, interpolatedValue);
23661
23539
  if (evaluation.completed) {
23662
- const finalValue = normalize(item.state.to);
23540
+ const finalValue = normalize(item.to);
23663
23541
  applyFinalValue(item.image, finalValue);
23664
23542
  updateDistanceInterpolationState(item.image, item.descriptor, null);
23665
23543
  } else {
23666
- updateDistanceInterpolationState(item.image, item.descriptor, item.state);
23544
+ updateDistanceInterpolationState(item.image, item.descriptor, item);
23667
23545
  active = true;
23668
23546
  }
23669
23547
  }
23670
23548
  return active;
23671
23549
  };
23550
+ const resolveRotationTarget = (params) => {
23551
+ const options = params.options;
23552
+ const targetAngle = normalizeAngleDeg(params.targetAngleDeg);
23553
+ const currentAngle = normalizeAngleDeg(params.currentAngleDeg);
23554
+ const previousCommandAngleDeg = params.previousCommandAngleDeg !== void 0 ? normalizeAngleDeg(params.previousCommandAngleDeg) : void 0;
23555
+ if (!options || options.durationMs <= 0) {
23556
+ return {
23557
+ nextAngleDeg: targetAngle,
23558
+ interpolationState: null
23559
+ };
23560
+ }
23561
+ const { state, requiresInterpolation } = createDegreeInterpolationState({
23562
+ currentValue: currentAngle,
23563
+ targetValue: targetAngle,
23564
+ previousCommandValue: previousCommandAngleDeg,
23565
+ options
23566
+ });
23567
+ if (!requiresInterpolation) {
23568
+ return {
23569
+ nextAngleDeg: targetAngle,
23570
+ interpolationState: null
23571
+ };
23572
+ }
23573
+ return {
23574
+ nextAngleDeg: currentAngle,
23575
+ interpolationState: state
23576
+ };
23577
+ };
23672
23578
  const stepDegreeInterpolationState = (interpolationState, timestamp, applyValue, options) => {
23673
23579
  var _a, _b;
23674
23580
  if (!interpolationState) {
23675
23581
  return { state: null, active: false };
23676
23582
  }
23677
- const evaluation = evaluateDegreeInterpolation({
23678
- state: interpolationState,
23679
- timestamp
23680
- });
23583
+ const evaluation = evaluateDegreeInterpolation(interpolationState, timestamp);
23681
23584
  if (interpolationState.startTimestamp < 0) {
23682
23585
  interpolationState.startTimestamp = evaluation.effectiveStartTimestamp;
23683
23586
  }
@@ -23692,59 +23595,80 @@ const stepDegreeInterpolationState = (interpolationState, timestamp, applyValue,
23692
23595
  }
23693
23596
  return { state: interpolationState, active: true };
23694
23597
  };
23695
- const resolveManualRotationFromDisplayed = (image) => {
23696
- var _a;
23697
- const baseRotation = (_a = image.resolvedBaseRotateDeg) != null ? _a : 0;
23698
- const fallbackRotation = normalizeAngleDeg(
23699
- baseRotation + image.rotationCommandDeg
23598
+ const resolveAutoRotationDeg$2 = (image, spriteAutoRotationDeg) => {
23599
+ return image.autoRotation ? spriteAutoRotationDeg : 0;
23600
+ };
23601
+ const resolveCurrentRotation = (image, spriteAutoRotationDeg) => {
23602
+ const targetAngle = normalizeAngleDeg(
23603
+ resolveAutoRotationDeg$2(image, spriteAutoRotationDeg) + image.rotateDeg
23700
23604
  );
23701
- const displayedRotation = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : fallbackRotation;
23702
- return normalizeAngleDeg(displayedRotation - baseRotation);
23605
+ const current = image.finalRotateDeg.current;
23606
+ return Number.isFinite(current) ? normalizeAngleDeg(current) : targetAngle;
23703
23607
  };
23704
- const refreshRotateDegInterpolatedValues = (image) => {
23705
- image.rotateDeg.current = resolveManualRotationFromDisplayed(image);
23706
- if (!image.rotateDeg.interpolation.state) {
23707
- image.rotateDeg.from = void 0;
23708
- image.rotateDeg.to = void 0;
23608
+ const refreshRotateDegInterpolatedValues = (image, spriteAutoRotationDeg) => {
23609
+ image.finalRotateDeg.current = resolveCurrentRotation(
23610
+ image,
23611
+ spriteAutoRotationDeg
23612
+ );
23613
+ if (!image.finalRotateDeg.interpolation.state) {
23614
+ image.finalRotateDeg.from = void 0;
23615
+ image.finalRotateDeg.to = void 0;
23709
23616
  }
23710
23617
  };
23711
- const updateImageDisplayedRotation = (image, optionsOverride) => {
23618
+ const updateImageDisplayedRotation = (image, spriteAutoRotationDeg, optionsOverride) => {
23712
23619
  const targetAngle = normalizeAngleDeg(
23713
- image.resolvedBaseRotateDeg + image.rotationCommandDeg
23620
+ resolveAutoRotationDeg$2(image, spriteAutoRotationDeg) + image.rotateDeg
23714
23621
  );
23715
- const currentAngle = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : targetAngle;
23716
- const previousCommandAngle = image.rotateDeg.interpolation.lastCommandValue;
23717
- const options = optionsOverride === void 0 ? image.rotateDeg.interpolation.options : optionsOverride;
23622
+ const currentAngle = resolveCurrentRotation(image, spriteAutoRotationDeg);
23623
+ const previousCommandAngle = image.finalRotateDeg.interpolation.lastCommandValue;
23624
+ const options = optionsOverride === void 0 ? image.finalRotateDeg.interpolation.options : optionsOverride;
23718
23625
  const { nextAngleDeg, interpolationState } = resolveRotationTarget({
23719
23626
  currentAngleDeg: currentAngle,
23720
23627
  targetAngleDeg: targetAngle,
23721
23628
  previousCommandAngleDeg: previousCommandAngle,
23722
23629
  options: options != null ? options : void 0
23723
23630
  });
23724
- image.displayedRotateDeg = nextAngleDeg;
23725
- image.rotateDeg.interpolation.state = interpolationState;
23631
+ image.finalRotateDeg.current = normalizeAngleDeg(
23632
+ Number.isFinite(nextAngleDeg) ? nextAngleDeg : targetAngle
23633
+ );
23634
+ image.finalRotateDeg.interpolation.state = interpolationState;
23726
23635
  if (!interpolationState) {
23727
- image.displayedRotateDeg = targetAngle;
23636
+ image.finalRotateDeg.current = targetAngle;
23637
+ image.finalRotateDeg.from = void 0;
23638
+ image.finalRotateDeg.to = void 0;
23639
+ } else {
23640
+ image.finalRotateDeg.from = normalizeAngleDeg(currentAngle);
23641
+ image.finalRotateDeg.to = normalizeAngleDeg(targetAngle);
23728
23642
  }
23729
- image.rotateDeg.interpolation.lastCommandValue = targetAngle;
23643
+ image.finalRotateDeg.interpolation.lastCommandValue = targetAngle;
23730
23644
  };
23731
- const syncImageRotationChannel = (image, optionsOverride) => {
23732
- updateImageDisplayedRotation(image, optionsOverride);
23733
- refreshRotateDegInterpolatedValues(image);
23645
+ const syncImageRotationChannel = (image, spriteAutoRotationDeg, optionsOverride) => {
23646
+ updateImageDisplayedRotation(image, spriteAutoRotationDeg, optionsOverride);
23647
+ refreshRotateDegInterpolatedValues(image, spriteAutoRotationDeg);
23734
23648
  };
23735
- const stepRotationInterpolation = (image, timestamp) => {
23649
+ const stepRotationInterpolation = (image, spriteAutoRotationDeg, timestamp) => {
23736
23650
  const { state, active } = stepDegreeInterpolationState(
23737
- image.rotateDeg.interpolation.state,
23651
+ image.finalRotateDeg.interpolation.state,
23738
23652
  timestamp,
23739
23653
  (value) => {
23740
- image.displayedRotateDeg = value;
23654
+ const fallback2 = normalizeAngleDeg(
23655
+ resolveAutoRotationDeg$2(image, spriteAutoRotationDeg) + image.rotateDeg
23656
+ );
23657
+ image.finalRotateDeg.current = normalizeAngleDeg(
23658
+ Number.isFinite(value) ? value : fallback2
23659
+ );
23741
23660
  },
23742
23661
  {
23743
- normalize: normalizeAngleDeg
23662
+ normalize: (value) => {
23663
+ const fallback2 = normalizeAngleDeg(
23664
+ resolveAutoRotationDeg$2(image, spriteAutoRotationDeg) + image.rotateDeg
23665
+ );
23666
+ return normalizeAngleDeg(Number.isFinite(value) ? value : fallback2);
23667
+ }
23744
23668
  }
23745
23669
  );
23746
- image.rotateDeg.interpolation.state = state;
23747
- refreshRotateDegInterpolatedValues(image);
23670
+ image.finalRotateDeg.interpolation.state = state;
23671
+ refreshRotateDegInterpolatedValues(image, spriteAutoRotationDeg);
23748
23672
  return active;
23749
23673
  };
23750
23674
  const stepOffsetDegInterpolation = (image, timestamp) => {
@@ -23772,10 +23696,10 @@ const stepDistanceInterpolationState = (interpolationState, timestamp, applyValu
23772
23696
  if (!interpolationState) {
23773
23697
  return { state: null, active: false };
23774
23698
  }
23775
- const evaluation = evaluateDistanceInterpolation({
23776
- state: interpolationState,
23699
+ const evaluation = evaluateDistanceInterpolation(
23700
+ interpolationState,
23777
23701
  timestamp
23778
- });
23702
+ );
23779
23703
  if (interpolationState.startTimestamp < 0) {
23780
23704
  interpolationState.startTimestamp = evaluation.effectiveStartTimestamp;
23781
23705
  }
@@ -23796,7 +23720,9 @@ const clearOffsetMetersInterpolation = (image) => {
23796
23720
  image.offset.offsetMeters.to = void 0;
23797
23721
  };
23798
23722
  const clearOpacityInterpolation = (image) => {
23799
- image.opacity.interpolation.state = null;
23723
+ image.finalOpacity.interpolation.state = null;
23724
+ image.finalOpacity.from = void 0;
23725
+ image.finalOpacity.to = void 0;
23800
23726
  };
23801
23727
  const applyOffsetDegUpdate = (image, nextOffset, interpolationOptions) => {
23802
23728
  const options = interpolationOptions;
@@ -23873,35 +23799,36 @@ const runOpacityTargetTransition = (image, targetOpacity, interpolationOptions)
23873
23799
  const clampedTarget = clampOpacity(targetOpacity);
23874
23800
  const options = interpolationOptions;
23875
23801
  if (!options || options.durationMs <= 0) {
23876
- image.opacity.current = clampedTarget;
23877
- image.opacity.from = void 0;
23878
- image.opacity.to = void 0;
23879
- image.opacity.interpolation.state = null;
23802
+ image.finalOpacity.current = clampedTarget;
23803
+ image.finalOpacity.from = void 0;
23804
+ image.finalOpacity.to = void 0;
23805
+ image.finalOpacity.interpolation.state = null;
23880
23806
  } else {
23881
23807
  const { state, requiresInterpolation } = createDistanceInterpolationState({
23882
- currentValue: clampOpacity(image.opacity.current),
23808
+ currentValue: clampOpacity(image.finalOpacity.current),
23883
23809
  targetValue: clampedTarget,
23884
- previousCommandValue: image.opacity.interpolation.lastCommandValue,
23810
+ previousCommandValue: image.finalOpacity.interpolation.lastCommandValue,
23885
23811
  options
23886
23812
  });
23887
23813
  if (requiresInterpolation) {
23888
- image.opacity.interpolation.state = state;
23889
- image.opacity.from = image.opacity.current;
23890
- image.opacity.to = clampedTarget;
23814
+ image.finalOpacity.interpolation.state = state;
23815
+ image.finalOpacity.from = image.finalOpacity.current;
23816
+ image.finalOpacity.to = clampedTarget;
23891
23817
  } else {
23892
- image.opacity.current = clampedTarget;
23893
- image.opacity.from = void 0;
23894
- image.opacity.to = void 0;
23895
- image.opacity.interpolation.state = null;
23818
+ image.finalOpacity.current = clampedTarget;
23819
+ image.finalOpacity.from = void 0;
23820
+ image.finalOpacity.to = void 0;
23821
+ image.finalOpacity.interpolation.state = null;
23896
23822
  }
23897
23823
  }
23898
- image.opacity.interpolation.lastCommandValue = clampedTarget;
23899
- image.opacity.interpolation.targetValue = clampedTarget;
23824
+ image.finalOpacity.interpolation.lastCommandValue = clampedTarget;
23825
+ image.finalOpacity.interpolation.targetValue = clampedTarget;
23900
23826
  };
23901
23827
  const applyOpacityUpdate = (image, nextOpacity, interpolationOptions, spriteOpacityMultiplier = 1) => {
23902
23828
  const clampedBase = clampOpacity(nextOpacity);
23903
23829
  const lodMultiplier = typeof image.lodOpacity === "number" ? image.lodOpacity : 1;
23904
- image.opacity.interpolation.baseValue = clampedBase;
23830
+ image.finalOpacity.interpolation.baseValue = clampedBase;
23831
+ image.opacity = clampedBase;
23905
23832
  runOpacityTargetTransition(
23906
23833
  image,
23907
23834
  clampedBase * spriteOpacityMultiplier * lodMultiplier,
@@ -23917,48 +23844,64 @@ const applyResolvedOpacityTarget = (image, resolvedTarget, interpolationOptions)
23917
23844
  };
23918
23845
  const stepOpacityInterpolation = (image, timestamp) => {
23919
23846
  const { state, active } = stepDistanceInterpolationState(
23920
- image.opacity.interpolation.state,
23847
+ image.finalOpacity.interpolation.state,
23921
23848
  timestamp,
23922
23849
  (value) => {
23923
- image.opacity.current = value;
23850
+ image.finalOpacity.current = value;
23924
23851
  },
23925
23852
  {
23926
23853
  normalize: clampOpacity
23927
23854
  }
23928
23855
  );
23929
- image.opacity.interpolation.state = state;
23856
+ image.finalOpacity.interpolation.state = state;
23930
23857
  if (!state) {
23931
- image.opacity.from = void 0;
23932
- image.opacity.to = void 0;
23858
+ image.finalOpacity.from = void 0;
23859
+ image.finalOpacity.to = void 0;
23933
23860
  }
23934
23861
  return active;
23935
23862
  };
23936
23863
  const IMAGE_INTERPOLATION_STEPPERS = [
23937
23864
  { id: "rotation", step: stepRotationInterpolation },
23938
- { id: "offsetDeg", step: stepOffsetDegInterpolation },
23939
- { id: "offsetMeters", step: stepOffsetMetersInterpolation },
23940
- { id: "opacity", step: stepOpacityInterpolation }
23865
+ {
23866
+ id: "offsetDeg",
23867
+ step: (image, timestamp, _autoRotationDeg) => stepOffsetDegInterpolation(image, timestamp)
23868
+ },
23869
+ {
23870
+ id: "offsetMeters",
23871
+ step: (image, timestamp, _autoRotationDeg) => stepOffsetMetersInterpolation(image, timestamp)
23872
+ },
23873
+ {
23874
+ id: "opacity",
23875
+ step: (image, timestamp, _autoRotationDeg) => stepOpacityInterpolation(image, timestamp)
23876
+ }
23941
23877
  ];
23942
23878
  const stepSpriteImageInterpolations = (image, timestamp, options) => {
23943
- var _a;
23879
+ var _a, _b;
23944
23880
  let active = false;
23945
23881
  const skipChannels = (_a = options == null ? void 0 : options.skipChannels) != null ? _a : null;
23882
+ const autoRotationDeg = (_b = options == null ? void 0 : options.autoRotationDeg) != null ? _b : 0;
23946
23883
  for (const { id, step } of IMAGE_INTERPOLATION_STEPPERS) {
23947
23884
  if (skipChannels && skipChannels[id]) {
23948
23885
  continue;
23949
23886
  }
23950
- if (step(image, timestamp)) {
23887
+ if (step(image, timestamp, autoRotationDeg)) {
23951
23888
  active = true;
23952
23889
  }
23953
23890
  }
23954
23891
  return active;
23955
23892
  };
23956
23893
  const hasActiveImageInterpolations = (image) => {
23957
- return image.rotateDeg.interpolation.state !== null || image.offset.offsetDeg.interpolation.state !== null || image.offset.offsetMeters.interpolation.state !== null || image.opacity.interpolation.state !== null;
23894
+ return image.finalRotateDeg.interpolation.state !== null || image.offset.offsetDeg.interpolation.state !== null || image.offset.offsetMeters.interpolation.state !== null || image.finalOpacity.interpolation.state !== null;
23958
23895
  };
23959
23896
  const applyOffsetUpdate = (image, nextOffset, options = {}) => {
23960
- applyOffsetDegUpdate(image, nextOffset, options.deg);
23961
- applyOffsetMetersUpdate(image, nextOffset, options.meters);
23897
+ const shouldUpdateMeters = options.meters !== void 0 || nextOffset.offsetMeters !== image.offset.offsetMeters.current;
23898
+ if (shouldUpdateMeters) {
23899
+ applyOffsetMetersUpdate(image, nextOffset, options.meters);
23900
+ }
23901
+ const shouldUpdateDeg = options.deg !== void 0 || nextOffset.offsetDeg !== image.offset.offsetDeg.current;
23902
+ if (shouldUpdateDeg) {
23903
+ applyOffsetDegUpdate(image, nextOffset, options.deg);
23904
+ }
23962
23905
  };
23963
23906
  const VERTEX_COMPONENT_COUNT = 6;
23964
23907
  const POSITION_COMPONENT_COUNT = 4;
@@ -26020,14 +25963,17 @@ const resolveImageOffset$2 = (image) => {
26020
25963
  offsetDeg: offset.offsetDeg.current
26021
25964
  };
26022
25965
  };
26023
- const calculateBorderWidthPixels = (widthMeters, imageScale, zoomScaleFactor, effectivePixelsPerMeter, sizeScaleAdjustment) => {
25966
+ const resolveAutoRotationDeg$1 = (sprite, image) => {
25967
+ return image.autoRotation ? sprite.currentAutoRotateDeg : 0;
25968
+ };
25969
+ const calculateBorderWidthPixels = (widthMeters, imageScale, distanceScaleFactor, effectivePixelsPerMeter, sizeScaleAdjustment) => {
26024
25970
  if (widthMeters === void 0 || !Number.isFinite(widthMeters) || widthMeters <= 0) {
26025
25971
  return 0;
26026
25972
  }
26027
25973
  if (!Number.isFinite(effectivePixelsPerMeter) || effectivePixelsPerMeter <= 0) {
26028
25974
  return 0;
26029
25975
  }
26030
- const scaledWidthMeters = widthMeters * imageScale * zoomScaleFactor * sizeScaleAdjustment;
25976
+ const scaledWidthMeters = widthMeters * imageScale * distanceScaleFactor * sizeScaleAdjustment;
26031
25977
  if (!Number.isFinite(scaledWidthMeters) || scaledWidthMeters <= 0) {
26032
25978
  return 0;
26033
25979
  }
@@ -26066,14 +26012,13 @@ const ensureHitTestCorners$1 = (imageEntry) => {
26066
26012
  }
26067
26013
  return imageEntry.hitTestCorners;
26068
26014
  };
26069
- const collectDepthSortedItemsInternal = (projectionHost, zoom, zoomScaleFactor, originCenterCache, {
26015
+ const collectDepthSortedItemsInternal = (projectionHost, zoom, originCenterCache, {
26070
26016
  bucket,
26071
26017
  bucketBuffers,
26072
26018
  imageResources,
26019
+ resolvedScaling,
26073
26020
  clipContext,
26074
26021
  baseMetersPerPixel,
26075
- spriteMinPixel,
26076
- spriteMaxPixel,
26077
26022
  drawingBufferWidth,
26078
26023
  drawingBufferHeight,
26079
26024
  pixelRatio
@@ -26088,6 +26033,7 @@ const collectDepthSortedItemsInternal = (projectionHost, zoom, zoomScaleFactor,
26088
26033
  throw new Error("bucketBuffers length mismatch");
26089
26034
  }
26090
26035
  const resolveOrigin = createBucketOriginResolver(bucket);
26036
+ const cameraLocation = projectionHost.getCameraLocation();
26091
26037
  for (const [spriteEntry, imageEntry] of bucket) {
26092
26038
  const imageResource = imageResources[imageEntry.imageHandle];
26093
26039
  if (!imageResource || !imageResource.texture) {
@@ -26116,23 +26062,35 @@ const collectDepthSortedItemsInternal = (projectionHost, zoom, zoomScaleFactor,
26116
26062
  if (effectivePixelsPerMeter <= 0) {
26117
26063
  continue;
26118
26064
  }
26065
+ const spriteBaseLocation = spriteEntry.location.current;
26066
+ const spriteDistanceLocation = {
26067
+ lng: spriteBaseLocation.lng,
26068
+ lat: spriteBaseLocation.lat,
26069
+ z: (_a = spriteBaseLocation.z) != null ? _a : 0
26070
+ };
26071
+ const cameraDistanceMeters = cameraLocation !== void 0 ? calculateCartesianDistanceMeters(
26072
+ cameraLocation,
26073
+ spriteDistanceLocation
26074
+ ) : Number.POSITIVE_INFINITY;
26075
+ const distanceScaleFactor = calculateDistanceScaleFactor(
26076
+ cameraDistanceMeters,
26077
+ resolvedScaling
26078
+ );
26119
26079
  const centerParams = {
26120
26080
  projectionHost,
26121
26081
  imageResources,
26122
26082
  originCenterCache,
26123
26083
  projected,
26124
26084
  baseMetersPerPixel,
26125
- spriteMinPixel,
26126
- spriteMaxPixel,
26127
26085
  effectivePixelsPerMeter,
26128
- zoomScaleFactor,
26086
+ distanceScaleFactor,
26129
26087
  drawingBufferWidth,
26130
26088
  drawingBufferHeight,
26131
26089
  pixelRatio,
26132
26090
  clipContext,
26133
26091
  resolveOrigin
26134
26092
  };
26135
- const anchorResolved = (_a = imageEntry.anchor) != null ? _a : DEFAULT_ANCHOR;
26093
+ const anchorResolved = (_b = imageEntry.anchor) != null ? _b : DEFAULT_ANCHOR;
26136
26094
  const offsetResolved = resolveImageOffset$2(imageEntry);
26137
26095
  const depthCenter = computeImageCenterXY(
26138
26096
  spriteEntry,
@@ -26142,26 +26100,22 @@ const collectDepthSortedItemsInternal = (projectionHost, zoom, zoomScaleFactor,
26142
26100
  );
26143
26101
  let depthKey;
26144
26102
  if (imageEntry.mode === "surface") {
26145
- const imageScale = (_b = imageEntry.scale) != null ? _b : 1;
26103
+ const imageScale = (_c = imageEntry.scale) != null ? _c : 1;
26146
26104
  const worldDims = calculateSurfaceWorldDimensions(
26147
26105
  imageResource.width,
26148
26106
  imageResource.height,
26149
26107
  baseMetersPerPixel,
26150
26108
  imageScale,
26151
- zoomScaleFactor,
26152
- {
26153
- effectivePixelsPerMeter,
26154
- spriteMinPixel,
26155
- spriteMaxPixel
26156
- }
26109
+ distanceScaleFactor
26157
26110
  );
26158
- const totalRotateDeg = Number.isFinite(imageEntry.displayedRotateDeg) ? imageEntry.displayedRotateDeg : normalizeAngleDeg(
26159
- ((_c = imageEntry.resolvedBaseRotateDeg) != null ? _c : 0) + imageEntry.rotationCommandDeg
26111
+ const autoRotationDeg = resolveAutoRotationDeg$1(spriteEntry, imageEntry);
26112
+ const totalRotateDeg = normalizeAngleDeg(
26113
+ Number.isFinite(imageEntry.finalRotateDeg.current) ? imageEntry.finalRotateDeg.current : autoRotationDeg + imageEntry.rotateDeg
26160
26114
  );
26161
26115
  const offsetMeters = calculateSurfaceOffsetMeters(
26162
26116
  offsetResolved,
26163
26117
  imageScale,
26164
- zoomScaleFactor,
26118
+ distanceScaleFactor,
26165
26119
  worldDims.scaleAdjustment
26166
26120
  );
26167
26121
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
@@ -26228,6 +26182,8 @@ const collectDepthSortedItemsInternal = (projectionHost, zoom, zoomScaleFactor,
26228
26182
  image: imageEntry,
26229
26183
  resource: imageResource,
26230
26184
  depthKey,
26185
+ cameraDistanceMeters,
26186
+ distanceScaleFactor,
26231
26187
  resolveOrigin
26232
26188
  });
26233
26189
  }
@@ -26265,15 +26221,13 @@ const projectLngLatToClipSpace = (projectionHost, location2, context) => {
26265
26221
  return [clipX, clipY, clipZ, clipW];
26266
26222
  };
26267
26223
  const computeImageCenterXY = (sprite, image, params, useResolvedAnchor) => {
26268
- var _a, _b, _c, _d, _e;
26224
+ var _a, _b, _c, _d;
26269
26225
  const {
26270
26226
  originCenterCache,
26271
26227
  projected,
26272
26228
  baseMetersPerPixel,
26273
- spriteMinPixel,
26274
- spriteMaxPixel,
26275
26229
  effectivePixelsPerMeter,
26276
- zoomScaleFactor,
26230
+ distanceScaleFactor,
26277
26231
  imageResources,
26278
26232
  projectionHost,
26279
26233
  drawingBufferWidth,
@@ -26308,10 +26262,11 @@ const computeImageCenterXY = (sprite, image, params, useResolvedAnchor) => {
26308
26262
  base = refCenter;
26309
26263
  }
26310
26264
  }
26311
- const totalRotDeg = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : normalizeAngleDeg(
26312
- ((_a = image.resolvedBaseRotateDeg) != null ? _a : 0) + image.rotationCommandDeg
26265
+ const autoRotationDeg = resolveAutoRotationDeg$1(sprite, image);
26266
+ const totalRotDeg = normalizeAngleDeg(
26267
+ Number.isFinite(image.finalRotateDeg.current) ? image.finalRotateDeg.current : autoRotationDeg + image.rotateDeg
26313
26268
  );
26314
- const imageScaleLocal = (_b = image.scale) != null ? _b : 1;
26269
+ const imageScaleLocal = (_a = image.scale) != null ? _a : 1;
26315
26270
  const imageResourceRef = imageResources[image.imageHandle];
26316
26271
  if (image.mode === "billboard") {
26317
26272
  const placement = calculateBillboardCenterPosition({
@@ -26320,10 +26275,8 @@ const computeImageCenterXY = (sprite, image, params, useResolvedAnchor) => {
26320
26275
  imageHeight: imageResourceRef == null ? void 0 : imageResourceRef.height,
26321
26276
  baseMetersPerPixel,
26322
26277
  imageScale: imageScaleLocal,
26323
- zoomScaleFactor,
26278
+ distanceScaleFactor,
26324
26279
  effectivePixelsPerMeter,
26325
- spriteMinPixel,
26326
- spriteMaxPixel,
26327
26280
  totalRotateDeg: totalRotDeg,
26328
26281
  anchor: image.anchor,
26329
26282
  offset: resolveImageOffset$2(image)
@@ -26339,7 +26292,7 @@ const computeImageCenterXY = (sprite, image, params, useResolvedAnchor) => {
26339
26292
  }
26340
26293
  const baseLngLat = image.originLocation !== void 0 ? (
26341
26294
  // When anchored to another image, reproject the 2D reference point back to geographic space.
26342
- (_c = projectionHost.unproject(base)) != null ? _c : sprite.location.current
26295
+ (_b = projectionHost.unproject(base)) != null ? _b : sprite.location.current
26343
26296
  ) : (
26344
26297
  // Otherwise use the sprite's own interpolated geographic location.
26345
26298
  sprite.location.current
@@ -26351,13 +26304,10 @@ const computeImageCenterXY = (sprite, image, params, useResolvedAnchor) => {
26351
26304
  imageHeight: imageResourceRef == null ? void 0 : imageResourceRef.height,
26352
26305
  baseMetersPerPixel,
26353
26306
  imageScale: imageScaleLocal,
26354
- zoomScaleFactor,
26307
+ distanceScaleFactor,
26355
26308
  totalRotateDeg: totalRotDeg,
26356
26309
  anchor: image.anchor,
26357
26310
  offset: resolveImageOffset$2(image),
26358
- effectivePixelsPerMeter,
26359
- spriteMinPixel,
26360
- spriteMaxPixel,
26361
26311
  projectToClipSpace,
26362
26312
  drawingBufferWidth,
26363
26313
  drawingBufferHeight,
@@ -26365,8 +26315,8 @@ const computeImageCenterXY = (sprite, image, params, useResolvedAnchor) => {
26365
26315
  resolveAnchorless: true,
26366
26316
  project: projectToClipSpace ? void 0 : projectionHost.project
26367
26317
  });
26368
- const anchorlessCenter = (_d = surfacePlacement.anchorlessCenter) != null ? _d : base;
26369
- const anchorAppliedCenter = (_e = surfacePlacement.center) != null ? _e : anchorlessCenter;
26318
+ const anchorlessCenter = (_c = surfacePlacement.anchorlessCenter) != null ? _c : base;
26319
+ const anchorAppliedCenter = (_d = surfacePlacement.center) != null ? _d : anchorlessCenter;
26370
26320
  const entry = cachedEntry != null ? cachedEntry : {
26371
26321
  anchorless: anchorlessCenter,
26372
26322
  anchorApplied: anchorAppliedCenter
@@ -26458,11 +26408,9 @@ const prepareSurfaceShaderInputs = (projectionHost, params) => {
26458
26408
  clipCorners: []
26459
26409
  };
26460
26410
  };
26461
- const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFactor, originCenterCache, {
26411
+ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, originCenterCache, {
26462
26412
  imageResources,
26463
26413
  baseMetersPerPixel,
26464
- spriteMinPixel,
26465
- spriteMaxPixel,
26466
26414
  drawingBufferWidth,
26467
26415
  drawingBufferHeight,
26468
26416
  pixelRatio,
@@ -26476,7 +26424,7 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26476
26424
  screenToClipOffsetX,
26477
26425
  screenToClipOffsetY
26478
26426
  }) => {
26479
- var _a, _b, _c, _d, _e, _f, _g, _h;
26427
+ var _a, _b, _c, _d, _e, _f;
26480
26428
  const spriteEntry = item.sprite;
26481
26429
  const imageEntry = item.image;
26482
26430
  const imageResource = item.resource;
@@ -26488,6 +26436,8 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26488
26436
  const atlasUSpan = atlasU1 - atlasU0;
26489
26437
  const atlasVSpan = atlasV1 - atlasV0;
26490
26438
  const spriteMercator = resolveSpriteMercator(projectionHost, item.sprite);
26439
+ const distanceScaleFactor = item.distanceScaleFactor;
26440
+ const cameraDistanceMeters = item.cameraDistanceMeters;
26491
26441
  imageEntry.surfaceShaderInputs = void 0;
26492
26442
  imageEntry.borderPixelWidth = 0;
26493
26443
  let screenCornerBuffer = null;
@@ -26505,8 +26455,9 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26505
26455
  let borderSizeScaleAdjustment = 1;
26506
26456
  const anchor = (_a = imageEntry.anchor) != null ? _a : DEFAULT_ANCHOR;
26507
26457
  const offsetDef = resolveImageOffset$2(imageEntry);
26508
- const totalRotateDeg = Number.isFinite(imageEntry.displayedRotateDeg) ? imageEntry.displayedRotateDeg : normalizeAngleDeg(
26509
- ((_b = imageEntry.resolvedBaseRotateDeg) != null ? _b : 0) + imageEntry.rotationCommandDeg
26458
+ const autoRotationDeg = resolveAutoRotationDeg$1(spriteEntry, imageEntry);
26459
+ const totalRotateDeg = normalizeAngleDeg(
26460
+ Number.isFinite(imageEntry.finalRotateDeg.current) ? imageEntry.finalRotateDeg.current : autoRotationDeg + imageEntry.rotateDeg
26510
26461
  );
26511
26462
  const projected = projectionHost.project(spriteEntry.location.current);
26512
26463
  if (!projected) {
@@ -26530,17 +26481,15 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26530
26481
  if (effectivePixelsPerMeter <= 0) {
26531
26482
  return null;
26532
26483
  }
26533
- const imageScale = (_c = imageEntry.scale) != null ? _c : 1;
26484
+ const imageScale = (_b = imageEntry.scale) != null ? _b : 1;
26534
26485
  const centerParams = {
26535
26486
  projectionHost,
26536
26487
  imageResources,
26537
26488
  originCenterCache,
26538
26489
  projected,
26539
26490
  baseMetersPerPixel,
26540
- spriteMinPixel,
26541
- spriteMaxPixel,
26542
26491
  effectivePixelsPerMeter,
26543
- zoomScaleFactor,
26492
+ distanceScaleFactor,
26544
26493
  drawingBufferWidth,
26545
26494
  drawingBufferHeight,
26546
26495
  pixelRatio,
@@ -26555,7 +26504,7 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26555
26504
  spriteEntry,
26556
26505
  refImg,
26557
26506
  centerParams,
26558
- (_d = imageEntry.originLocation.useResolvedAnchor) != null ? _d : false
26507
+ (_c = imageEntry.originLocation.useResolvedAnchor) != null ? _c : false
26559
26508
  );
26560
26509
  }
26561
26510
  }
@@ -26579,14 +26528,6 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26579
26528
  };
26580
26529
  };
26581
26530
  const baseLocation = resolveBaseLocation();
26582
- const cameraLocation = projectionHost.getCameraLocation();
26583
- const spriteBaseLocation = spriteEntry.location.current;
26584
- const spriteDistanceLocation = {
26585
- lng: spriteBaseLocation.lng,
26586
- lat: spriteBaseLocation.lat,
26587
- z: (_e = spriteBaseLocation.z) != null ? _e : 0
26588
- };
26589
- const cameraDistanceMeters = cameraLocation !== void 0 ? calculateCartesianDistanceMeters(cameraLocation, spriteDistanceLocation) : Number.POSITIVE_INFINITY;
26590
26531
  if (imageEntry.mode === "surface") {
26591
26532
  screenToClipUniforms = {
26592
26533
  scaleX: identityScaleX,
@@ -26601,13 +26542,10 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26601
26542
  imageHeight: imageResource.height,
26602
26543
  baseMetersPerPixel,
26603
26544
  imageScale,
26604
- zoomScaleFactor,
26545
+ distanceScaleFactor,
26605
26546
  totalRotateDeg,
26606
26547
  anchor,
26607
26548
  offset: offsetDef,
26608
- effectivePixelsPerMeter,
26609
- spriteMinPixel,
26610
- spriteMaxPixel,
26611
26549
  projectToClipSpace: (location2) => projectLngLatToClipSpace(projectionHost, location2, clipContext),
26612
26550
  drawingBufferWidth,
26613
26551
  drawingBufferHeight,
@@ -26621,7 +26559,7 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26621
26559
  const offsetMeters = calculateSurfaceOffsetMeters(
26622
26560
  offsetDef,
26623
26561
  imageScale,
26624
- zoomScaleFactor,
26562
+ distanceScaleFactor,
26625
26563
  surfaceCenter.worldDimensions.scaleAdjustment
26626
26564
  );
26627
26565
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
@@ -26633,7 +26571,7 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26633
26571
  });
26634
26572
  const orderIndex = Math.min(imageEntry.order, ORDER_MAX - 1);
26635
26573
  const depthBiasNdc = -((imageEntry.subLayer * ORDER_BUCKET + orderIndex) * EPS_NDC);
26636
- const displacedCenter = (_f = surfaceCenter.displacedLngLat) != null ? _f : baseLngLat;
26574
+ const displacedCenter = (_d = surfaceCenter.displacedLngLat) != null ? _d : baseLngLat;
26637
26575
  const surfaceShaderInputs = prepareSurfaceShaderInputs(projectionHost, {
26638
26576
  baseLngLat,
26639
26577
  worldWidthMeters: surfaceCenter.worldDimensions.width,
@@ -26819,10 +26757,8 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26819
26757
  imageHeight: imageResource.height,
26820
26758
  baseMetersPerPixel,
26821
26759
  imageScale,
26822
- zoomScaleFactor,
26760
+ distanceScaleFactor,
26823
26761
  effectivePixelsPerMeter,
26824
- spriteMinPixel,
26825
- spriteMaxPixel,
26826
26762
  totalRotateDeg,
26827
26763
  anchor,
26828
26764
  offset: offsetDef
@@ -26890,19 +26826,19 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26890
26826
  }
26891
26827
  writeBillboardCorners(resolvedCorners, useShaderBillboard);
26892
26828
  }
26893
- const borderWidthMeters = (_g = imageEntry.border) == null ? void 0 : _g.widthMeters;
26829
+ const borderWidthMeters = (_e = imageEntry.border) == null ? void 0 : _e.widthMeters;
26894
26830
  imageEntry.borderPixelWidth = calculateBorderWidthPixels(
26895
26831
  borderWidthMeters,
26896
26832
  imageScale,
26897
- zoomScaleFactor,
26833
+ distanceScaleFactor,
26898
26834
  effectivePixelsPerMeter,
26899
26835
  borderSizeScaleAdjustment
26900
26836
  );
26901
- const leaderLineWidthMeters = (_h = imageEntry.leaderLine) == null ? void 0 : _h.widthMeters;
26837
+ const leaderLineWidthMeters = (_f = imageEntry.leaderLine) == null ? void 0 : _f.widthMeters;
26902
26838
  imageEntry.leaderLinePixelWidth = calculateBorderWidthPixels(
26903
26839
  leaderLineWidthMeters,
26904
26840
  imageScale,
26905
- zoomScaleFactor,
26841
+ distanceScaleFactor,
26906
26842
  effectivePixelsPerMeter,
26907
26843
  borderSizeScaleAdjustment
26908
26844
  );
@@ -26912,7 +26848,7 @@ const prepareDrawSpriteImageInternal = (projectionHost, item, zoom, zoomScaleFac
26912
26848
  imageEntry,
26913
26849
  imageResource,
26914
26850
  vertexData: new Float32Array(QUAD_VERTEX_SCRATCH),
26915
- opacity: imageEntry.opacity.current,
26851
+ opacity: imageEntry.finalOpacity.current,
26916
26852
  hitTestCorners,
26917
26853
  screenToClip: screenToClipUniforms,
26918
26854
  useShaderSurface,
@@ -26928,19 +26864,17 @@ const prepareDrawSpriteImages = (projectionHost, params) => {
26928
26864
  const originCenterCache = /* @__PURE__ */ new Map();
26929
26865
  const zoom = projectionHost.getZoom();
26930
26866
  const resolvedScaling = (_a = params.resolvedScaling) != null ? _a : resolveScalingOptions({
26931
- metersPerPixel: params.baseMetersPerPixel,
26932
- spriteMinPixel: params.spriteMinPixel,
26933
- spriteMaxPixel: params.spriteMaxPixel,
26934
- zoomMin: zoom,
26935
- zoomMax: zoom
26867
+ metersPerPixel: params.baseMetersPerPixel
26936
26868
  });
26937
- const zoomScaleFactor = calculateZoomScaleFactor(zoom, resolvedScaling);
26869
+ const preparedParams = {
26870
+ ...params,
26871
+ resolvedScaling
26872
+ };
26938
26873
  const itemsWithDepth = collectDepthSortedItemsInternal(
26939
26874
  projectionHost,
26940
26875
  zoom,
26941
- zoomScaleFactor,
26942
26876
  originCenterCache,
26943
- params
26877
+ preparedParams
26944
26878
  );
26945
26879
  const preparedItems = [];
26946
26880
  for (const item of itemsWithDepth) {
@@ -26948,9 +26882,8 @@ const prepareDrawSpriteImages = (projectionHost, params) => {
26948
26882
  projectionHost,
26949
26883
  item,
26950
26884
  zoom,
26951
- zoomScaleFactor,
26952
26885
  originCenterCache,
26953
- params
26886
+ preparedParams
26954
26887
  );
26955
26888
  if (prepared) {
26956
26889
  preparedItems.push(prepared);
@@ -26984,14 +26917,14 @@ const applyVisibilityDistanceLod = (preparedItems) => {
26984
26917
  continue;
26985
26918
  }
26986
26919
  image.lodOpacity = lodMultiplier;
26987
- const baseOpacity = (_b = image.opacity.interpolation.baseValue) != null ? _b : image.opacity.current;
26920
+ const baseOpacity = (_b = image.finalOpacity.interpolation.baseValue) != null ? _b : image.finalOpacity.current;
26988
26921
  const combinedTarget = clampOpacity(
26989
26922
  baseOpacity * ((_c = sprite.opacityMultiplier) != null ? _c : 1) * lodMultiplier
26990
26923
  );
26991
26924
  applyResolvedOpacityTarget(
26992
26925
  image,
26993
26926
  combinedTarget,
26994
- (_d = image.opacity.interpolation.options) != null ? _d : null
26927
+ (_d = image.finalOpacity.interpolation.options) != null ? _d : null
26995
26928
  );
26996
26929
  }
26997
26930
  };
@@ -27000,7 +26933,7 @@ const syncPreparedOpacities = (preparedItems) => {
27000
26933
  return;
27001
26934
  }
27002
26935
  for (const prepared of preparedItems) {
27003
- prepared.opacity = prepared.imageEntry.opacity.current;
26936
+ prepared.opacity = prepared.imageEntry.finalOpacity.current;
27004
26937
  }
27005
26938
  };
27006
26939
  const filterVisiblePreparedItems = (preparedItems) => {
@@ -27015,93 +26948,61 @@ const filterVisiblePreparedItems = (preparedItems) => {
27015
26948
  }
27016
26949
  return visibleItems;
27017
26950
  };
27018
- const evaluateDistanceInterpolationsBatch = (requests) => {
27019
- if (!requests.length) {
27020
- return [];
27021
- }
27022
- return requests.map((request) => evaluateDistanceInterpolation(request));
27023
- };
27024
- const evaluateDegreeInterpolationsBatch = (requests) => {
27025
- if (!requests.length) {
26951
+ const evaluateDistanceInterpolationsBatch = (states, timestamp) => {
26952
+ if (!states.length) {
27026
26953
  return [];
27027
26954
  }
27028
- return requests.map((request) => evaluateDegreeInterpolation(request));
26955
+ return states.map((state) => evaluateDistanceInterpolation(state, timestamp));
27029
26956
  };
27030
- const evaluateSpriteInterpolationsBatch = (requests) => {
27031
- if (!requests.length) {
26957
+ const evaluateDegreeInterpolationsBatch = (states, timestamp) => {
26958
+ if (!states.length) {
27032
26959
  return [];
27033
26960
  }
27034
- return requests.map((request) => evaluateInterpolation(request));
27035
- };
27036
- const defaultInterpolationEvaluationHandlers = {
27037
- evaluateDistance: (requests) => evaluateDistanceInterpolationsBatch(requests),
27038
- evaluateDegree: (requests) => evaluateDegreeInterpolationsBatch(requests),
27039
- evaluateSprite: (requests) => evaluateSpriteInterpolationsBatch(requests)
27040
- };
27041
- const applySpriteInterpolationEvaluations$1 = (workItems, evaluations, timestamp) => {
27042
- var _a;
27043
- let active = false;
27044
- for (let index = 0; index < workItems.length; index += 1) {
27045
- const item = workItems[index];
27046
- const { sprite, state } = item;
27047
- const evaluation = (_a = evaluations[index]) != null ? _a : evaluateInterpolation({
27048
- state,
27049
- timestamp
27050
- });
27051
- if (state.startTimestamp < 0) {
27052
- state.startTimestamp = evaluation.effectiveStartTimestamp;
27053
- }
27054
- sprite.location.current = evaluation.location;
27055
- if (evaluation.completed) {
27056
- sprite.location.current = cloneSpriteLocation(state.to);
27057
- sprite.location.from = void 0;
27058
- sprite.location.to = void 0;
27059
- sprite.location.interpolation.state = null;
27060
- } else {
27061
- active = true;
27062
- }
27063
- }
27064
- return active;
26961
+ return states.map((state) => evaluateDegreeInterpolation(state, timestamp));
27065
26962
  };
27066
26963
  const ensureOpacityInterpolationTarget = (sprite, image) => {
27067
26964
  var _a, _b, _c, _d;
27068
26965
  const target = clampOpacity(
27069
- ((_a = image.opacity.interpolation.baseValue) != null ? _a : image.opacity.current) * ((_b = sprite.opacityMultiplier) != null ? _b : 1) * ((_c = image.lodOpacity) != null ? _c : 1)
26966
+ ((_a = image.finalOpacity.interpolation.baseValue) != null ? _a : image.finalOpacity.current) * ((_b = sprite.opacityMultiplier) != null ? _b : 1) * ((_c = image.lodOpacity) != null ? _c : 1)
27070
26967
  );
27071
- const interpolationState = image.opacity.interpolation.state;
27072
- const currentStateTarget = interpolationState ? clampOpacity((_d = interpolationState.pathTarget) != null ? _d : interpolationState.to) : image.opacity.current;
26968
+ const interpolationState = image.finalOpacity.interpolation.state;
26969
+ const currentStateTarget = interpolationState ? clampOpacity((_d = interpolationState.pathTarget) != null ? _d : interpolationState.to) : image.finalOpacity.current;
27073
26970
  if (interpolationState) {
27074
26971
  if (Math.abs(currentStateTarget - target) <= OPACITY_TARGET_EPSILON) {
27075
26972
  return;
27076
26973
  }
27077
- } else if (Math.abs(image.opacity.current - target) <= OPACITY_TARGET_EPSILON) {
26974
+ } else if (Math.abs(image.finalOpacity.current - target) <= OPACITY_TARGET_EPSILON) {
27078
26975
  return;
27079
26976
  }
27080
- const options = image.opacity.interpolation.options;
26977
+ const options = image.finalOpacity.interpolation.options;
27081
26978
  if (options && options.durationMs > 0) {
27082
26979
  const { state, requiresInterpolation } = createDistanceInterpolationState({
27083
- currentValue: clampOpacity(image.opacity.current),
26980
+ currentValue: clampOpacity(image.finalOpacity.current),
27084
26981
  targetValue: target,
27085
- previousCommandValue: image.opacity.interpolation.lastCommandValue,
26982
+ previousCommandValue: image.finalOpacity.interpolation.lastCommandValue,
27086
26983
  options
27087
26984
  });
27088
26985
  if (requiresInterpolation) {
27089
- image.opacity.interpolation.state = state;
27090
- image.opacity.from = image.opacity.current;
27091
- image.opacity.to = target;
26986
+ image.finalOpacity.interpolation.state = state;
26987
+ image.finalOpacity.from = image.finalOpacity.current;
26988
+ image.finalOpacity.to = target;
27092
26989
  return;
27093
26990
  }
27094
26991
  }
27095
- image.opacity.current = target;
27096
- image.opacity.from = void 0;
27097
- image.opacity.to = void 0;
27098
- image.opacity.interpolation.state = null;
27099
- image.opacity.interpolation.lastCommandValue = target;
27100
- image.opacity.interpolation.targetValue = target;
26992
+ image.finalOpacity.current = target;
26993
+ image.finalOpacity.from = void 0;
26994
+ image.finalOpacity.to = void 0;
26995
+ image.finalOpacity.interpolation.state = null;
26996
+ image.finalOpacity.interpolation.lastCommandValue = target;
26997
+ image.finalOpacity.interpolation.targetValue = target;
26998
+ };
26999
+ const DEFAULT_INTERPOLATION_EVALUATION_HANDLERS = {
27000
+ evaluateDistance: evaluateDistanceInterpolationsBatch,
27001
+ evaluateDegree: evaluateDegreeInterpolationsBatch,
27002
+ evaluateSprite: evaluateLocationInterpolationsBatch
27101
27003
  };
27102
- const processInterpolationsInternal = (params, handlers = defaultInterpolationEvaluationHandlers) => {
27004
+ const processInterpolationsInternal = (params, handlers = DEFAULT_INTERPOLATION_EVALUATION_HANDLERS) => {
27103
27005
  var _a;
27104
- const evaluationHandlers = handlers != null ? handlers : defaultInterpolationEvaluationHandlers;
27105
27006
  const { sprites, timestamp } = params;
27106
27007
  if (!sprites.length) {
27107
27008
  return {
@@ -27111,14 +27012,13 @@ const processInterpolationsInternal = (params, handlers = defaultInterpolationEv
27111
27012
  }
27112
27013
  const distanceInterpolationWorkItems = [];
27113
27014
  const degreeInterpolationWorkItems = [];
27114
- const spriteInterpolationWorkItems = [];
27015
+ const locationInterpolationWorkItems = [];
27115
27016
  let hasActiveInterpolation = false;
27116
27017
  for (const sprite of sprites) {
27117
- const locationInterpolation = sprite.location.interpolation;
27118
- const state = locationInterpolation.state;
27119
- if (state) {
27120
- spriteInterpolationWorkItems.push({ sprite, state });
27121
- }
27018
+ collectLocationInterpolationWorkItems(
27019
+ sprite,
27020
+ locationInterpolationWorkItems
27021
+ );
27122
27022
  sprite.images.forEach((orderMap) => {
27123
27023
  orderMap.forEach((image) => {
27124
27024
  const hasOffsetMetersInterpolation = image.offset.offsetMeters.interpolation.state !== null;
@@ -27126,14 +27026,14 @@ const processInterpolationsInternal = (params, handlers = defaultInterpolationEv
27126
27026
  collectDistanceInterpolationWorkItems(
27127
27027
  image,
27128
27028
  distanceInterpolationWorkItems,
27129
- {
27130
- includeOpacity: false
27131
- }
27029
+ true,
27030
+ // includeOffsetMeters
27031
+ false
27132
27032
  );
27133
27033
  }
27134
27034
  ensureOpacityInterpolationTarget(sprite, image);
27135
- const hasOpacityInterpolation = image.opacity.interpolation.state !== null;
27136
- const hasDegreeInterpolation = image.rotateDeg.interpolation.state !== null || image.offset.offsetDeg.interpolation.state !== null;
27035
+ const hasOpacityInterpolation = image.finalOpacity.interpolation.state !== null;
27036
+ const hasDegreeInterpolation = image.finalRotateDeg.interpolation.state !== null || image.offset.offsetDeg.interpolation.state !== null;
27137
27037
  if (hasDegreeInterpolation) {
27138
27038
  collectDegreeInterpolationWorkItems(
27139
27039
  image,
@@ -27155,38 +27055,33 @@ const processInterpolationsInternal = (params, handlers = defaultInterpolationEv
27155
27055
  skipChannels.offsetDeg = true;
27156
27056
  shouldSkipChannels = true;
27157
27057
  }
27158
- if (stepSpriteImageInterpolations(
27159
- image,
27160
- timestamp,
27161
- shouldSkipChannels ? { skipChannels } : void 0
27162
- )) {
27058
+ const interpolationOptions = shouldSkipChannels ? {
27059
+ skipChannels,
27060
+ autoRotationDeg: resolveAutoRotationDeg$1(sprite, image)
27061
+ } : { autoRotationDeg: resolveAutoRotationDeg$1(sprite, image) };
27062
+ if (stepSpriteImageInterpolations(image, timestamp, interpolationOptions)) {
27163
27063
  hasActiveInterpolation = true;
27164
27064
  }
27165
27065
  });
27166
27066
  });
27167
27067
  }
27168
- const distanceRequests = distanceInterpolationWorkItems.length > 0 ? distanceInterpolationWorkItems.map(({ state }) => ({
27169
- state,
27170
- timestamp
27171
- })) : [];
27172
- const degreeRequests = degreeInterpolationWorkItems.length > 0 ? degreeInterpolationWorkItems.map(({ state }) => ({
27173
- state,
27174
- timestamp
27175
- })) : [];
27176
- const spriteRequests = spriteInterpolationWorkItems.length > 0 ? spriteInterpolationWorkItems.map(({ state }) => ({
27177
- state,
27178
- timestamp
27179
- })) : [];
27180
- const hasRequests = distanceRequests.length > 0 || degreeRequests.length > 0 || spriteRequests.length > 0;
27068
+ const hasRequests = distanceInterpolationWorkItems.length > 0 || degreeInterpolationWorkItems.length > 0 || locationInterpolationWorkItems.length > 0;
27181
27069
  if (hasRequests) {
27182
- (_a = evaluationHandlers.prepare) == null ? void 0 : _a.call(evaluationHandlers, {
27183
- distance: distanceRequests,
27184
- degree: degreeRequests,
27185
- sprite: spriteRequests
27186
- });
27070
+ (_a = handlers.prepare) == null ? void 0 : _a.call(
27071
+ handlers,
27072
+ {
27073
+ distance: distanceInterpolationWorkItems,
27074
+ degree: degreeInterpolationWorkItems,
27075
+ sprite: locationInterpolationWorkItems
27076
+ },
27077
+ timestamp
27078
+ );
27187
27079
  }
27188
- if (distanceRequests.length > 0) {
27189
- const evaluations = evaluationHandlers.evaluateDistance(distanceRequests);
27080
+ if (distanceInterpolationWorkItems.length > 0) {
27081
+ const evaluations = handlers.evaluateDistance(
27082
+ distanceInterpolationWorkItems,
27083
+ timestamp
27084
+ );
27190
27085
  if (applyDistanceInterpolationEvaluations(
27191
27086
  distanceInterpolationWorkItems,
27192
27087
  evaluations,
@@ -27195,8 +27090,11 @@ const processInterpolationsInternal = (params, handlers = defaultInterpolationEv
27195
27090
  hasActiveInterpolation = true;
27196
27091
  }
27197
27092
  }
27198
- if (degreeRequests.length > 0) {
27199
- const evaluations = evaluationHandlers.evaluateDegree(degreeRequests);
27093
+ if (degreeInterpolationWorkItems.length > 0) {
27094
+ const evaluations = handlers.evaluateDegree(
27095
+ degreeInterpolationWorkItems,
27096
+ timestamp
27097
+ );
27200
27098
  if (applyDegreeInterpolationEvaluations(
27201
27099
  degreeInterpolationWorkItems,
27202
27100
  evaluations,
@@ -27205,10 +27103,13 @@ const processInterpolationsInternal = (params, handlers = defaultInterpolationEv
27205
27103
  hasActiveInterpolation = true;
27206
27104
  }
27207
27105
  }
27208
- if (spriteRequests.length > 0) {
27209
- const evaluations = evaluationHandlers.evaluateSprite(spriteRequests);
27210
- if (applySpriteInterpolationEvaluations$1(
27211
- spriteInterpolationWorkItems,
27106
+ if (locationInterpolationWorkItems.length > 0) {
27107
+ const evaluations = handlers.evaluateSprite(
27108
+ locationInterpolationWorkItems,
27109
+ timestamp
27110
+ );
27111
+ if (applyLocationInterpolationEvaluations(
27112
+ locationInterpolationWorkItems,
27212
27113
  evaluations,
27213
27114
  timestamp
27214
27115
  )) {
@@ -27220,9 +27121,8 @@ const processInterpolationsInternal = (params, handlers = defaultInterpolationEv
27220
27121
  hasActiveInterpolation
27221
27122
  };
27222
27123
  };
27223
- const processOpacityInterpolationsAfterPreparation = (params, preparedItems, handlers = defaultInterpolationEvaluationHandlers) => {
27124
+ const processOpacityInterpolationsAfterPreparation = (params, preparedItems, handlers = DEFAULT_INTERPOLATION_EVALUATION_HANDLERS) => {
27224
27125
  var _a;
27225
- const evaluationHandlers = handlers != null ? handlers : defaultInterpolationEvaluationHandlers;
27226
27126
  const { sprites, timestamp } = params;
27227
27127
  if (!sprites.length) {
27228
27128
  return {
@@ -27235,10 +27135,14 @@ const processOpacityInterpolationsAfterPreparation = (params, preparedItems, han
27235
27135
  sprite.images.forEach((orderMap) => {
27236
27136
  orderMap.forEach((image) => {
27237
27137
  ensureOpacityInterpolationTarget(sprite, image);
27238
- if (image.opacity.interpolation.state !== null) {
27239
- collectDistanceInterpolationWorkItems(image, opacityWorkItems, {
27240
- includeOffsetMeters: false
27241
- });
27138
+ if (image.finalOpacity.interpolation.state !== null) {
27139
+ collectDistanceInterpolationWorkItems(
27140
+ image,
27141
+ opacityWorkItems,
27142
+ false,
27143
+ true
27144
+ // includeOpacity
27145
+ );
27242
27146
  }
27243
27147
  });
27244
27148
  });
@@ -27249,20 +27153,20 @@ const processOpacityInterpolationsAfterPreparation = (params, preparedItems, han
27249
27153
  hasActiveInterpolation: false
27250
27154
  };
27251
27155
  }
27252
- const opacityRequests = opacityWorkItems.length > 0 ? opacityWorkItems.map(({ state }) => ({
27253
- state,
27254
- timestamp
27255
- })) : [];
27256
- if (opacityRequests.length > 0) {
27257
- (_a = evaluationHandlers.prepare) == null ? void 0 : _a.call(evaluationHandlers, {
27258
- distance: opacityRequests,
27259
- degree: [],
27260
- sprite: []
27261
- });
27156
+ if (opacityWorkItems.length > 0) {
27157
+ (_a = handlers.prepare) == null ? void 0 : _a.call(
27158
+ handlers,
27159
+ {
27160
+ distance: opacityWorkItems,
27161
+ degree: [],
27162
+ sprite: []
27163
+ },
27164
+ timestamp
27165
+ );
27262
27166
  }
27263
27167
  let hasActiveInterpolation = false;
27264
- if (opacityRequests.length > 0) {
27265
- const evaluations = evaluationHandlers.evaluateDistance(opacityRequests);
27168
+ if (opacityWorkItems.length > 0) {
27169
+ const evaluations = handlers.evaluateDistance(opacityWorkItems, timestamp);
27266
27170
  if (applyDistanceInterpolationEvaluations(
27267
27171
  opacityWorkItems,
27268
27172
  evaluations,
@@ -27399,9 +27303,11 @@ const resolveImageOffset$1 = (image) => {
27399
27303
  offsetDeg: offset.offsetDeg.current
27400
27304
  };
27401
27305
  };
27402
- const encodeDistanceInterpolationRequest = (buffer, cursor, request) => {
27306
+ const resolveAutoRotationDeg = (sprite, image) => {
27307
+ return image.autoRotation ? sprite.currentAutoRotateDeg : 0;
27308
+ };
27309
+ const encodeDistanceInterpolationRequest = (buffer, cursor, state, timestamp) => {
27403
27310
  var _a;
27404
- const { state, timestamp } = request;
27405
27311
  const preset = encodeEasingPreset(state.easingParam);
27406
27312
  if (preset.id < 0) {
27407
27313
  throw new Error(
@@ -27420,9 +27326,8 @@ const encodeDistanceInterpolationRequest = (buffer, cursor, request) => {
27420
27326
  buffer[cursor++] = preset.param2;
27421
27327
  return cursor;
27422
27328
  };
27423
- const encodeDegreeInterpolationRequest = (buffer, cursor, request) => {
27329
+ const encodeDegreeInterpolationRequest = (buffer, cursor, state, timestamp) => {
27424
27330
  var _a;
27425
- const { state, timestamp } = request;
27426
27331
  const preset = encodeEasingPreset(state.easingParam);
27427
27332
  if (preset.id < 0) {
27428
27333
  throw new Error(
@@ -27441,9 +27346,8 @@ const encodeDegreeInterpolationRequest = (buffer, cursor, request) => {
27441
27346
  buffer[cursor++] = preset.param2;
27442
27347
  return cursor;
27443
27348
  };
27444
- const encodeSpriteInterpolationRequest = (buffer, cursor, request) => {
27349
+ const encodeSpriteInterpolationRequest = (buffer, cursor, state, timestamp) => {
27445
27350
  var _a, _b;
27446
- const { state, timestamp } = request;
27447
27351
  const preset = encodeEasingPreset(state.easingParam);
27448
27352
  if (preset.id < 0) {
27449
27353
  throw new Error(
@@ -27474,17 +27378,17 @@ const decodeSpriteInterpolationResult = (buffer, cursor) => {
27474
27378
  const hasZ = buffer[cursor++] !== 0;
27475
27379
  const completed = buffer[cursor++] !== 0;
27476
27380
  const effectiveStartTimestamp = buffer[cursor++];
27477
- const location2 = hasZ ? { lng, lat, z } : { lng, lat };
27381
+ const value = hasZ ? { lng, lat, z } : { lng, lat };
27478
27382
  return {
27479
27383
  nextCursor: cursor,
27480
27384
  result: {
27481
- location: location2,
27385
+ value,
27482
27386
  completed,
27483
27387
  effectiveStartTimestamp
27484
27388
  }
27485
27389
  };
27486
27390
  };
27487
- const processInterpolationsViaWasm = (wasm, requests) => {
27391
+ const processInterpolationsViaWasm = (wasm, requests, timestamp) => {
27488
27392
  const distanceCount = requests.distance.length;
27489
27393
  const degreeCount = requests.degree.length;
27490
27394
  const spriteCount = requests.sprite.length;
@@ -27513,14 +27417,25 @@ const processInterpolationsViaWasm = (wasm, requests) => {
27513
27417
  cursor = encodeDistanceInterpolationRequest(
27514
27418
  paramsBuffer,
27515
27419
  cursor,
27516
- request
27420
+ request,
27421
+ timestamp
27517
27422
  );
27518
27423
  }
27519
27424
  for (const request of requests.degree) {
27520
- cursor = encodeDegreeInterpolationRequest(paramsBuffer, cursor, request);
27425
+ cursor = encodeDegreeInterpolationRequest(
27426
+ paramsBuffer,
27427
+ cursor,
27428
+ request,
27429
+ timestamp
27430
+ );
27521
27431
  }
27522
27432
  for (const request of requests.sprite) {
27523
- cursor = encodeSpriteInterpolationRequest(paramsBuffer, cursor, request);
27433
+ cursor = encodeSpriteInterpolationRequest(
27434
+ paramsBuffer,
27435
+ cursor,
27436
+ request,
27437
+ timestamp
27438
+ );
27524
27439
  }
27525
27440
  const resultPrepared = resultHolder.prepare();
27526
27441
  const success = wasm.processInterpolations(
@@ -27532,9 +27447,7 @@ const processInterpolationsViaWasm = (wasm, requests) => {
27532
27447
  }
27533
27448
  const resultBuffer = resultPrepared.buffer;
27534
27449
  let read = WASM_PROCESS_INTERPOLATIONS_HEADER_LENGTH;
27535
- const distanceResults = new Array(
27536
- distanceCount
27537
- );
27450
+ const distanceResults = new Array(distanceCount);
27538
27451
  for (let i = 0; i < distanceCount; i += 1) {
27539
27452
  const value = resultBuffer[read++];
27540
27453
  const completed = resultBuffer[read++] !== 0;
@@ -27545,9 +27458,7 @@ const processInterpolationsViaWasm = (wasm, requests) => {
27545
27458
  effectiveStartTimestamp
27546
27459
  };
27547
27460
  }
27548
- const degreeResults = new Array(
27549
- degreeCount
27550
- );
27461
+ const degreeResults = new Array(degreeCount);
27551
27462
  for (let i = 0; i < degreeCount; i += 1) {
27552
27463
  const value = resultBuffer[read++];
27553
27464
  const completed = resultBuffer[read++] !== 0;
@@ -27558,9 +27469,7 @@ const processInterpolationsViaWasm = (wasm, requests) => {
27558
27469
  effectiveStartTimestamp
27559
27470
  };
27560
27471
  }
27561
- const spriteResults = new Array(
27562
- spriteCount
27563
- );
27472
+ const spriteResults = new Array(spriteCount);
27564
27473
  for (let i = 0; i < spriteCount; i += 1) {
27565
27474
  const decoded = decodeSpriteInterpolationResult(resultBuffer, read);
27566
27475
  spriteResults[i] = decoded.result;
@@ -27576,31 +27485,6 @@ const processInterpolationsViaWasm = (wasm, requests) => {
27576
27485
  paramsHolder.release();
27577
27486
  }
27578
27487
  };
27579
- const applySpriteInterpolationEvaluations = (workItems, evaluations, timestamp) => {
27580
- var _a;
27581
- let active = false;
27582
- for (let index = 0; index < workItems.length; index += 1) {
27583
- const item = workItems[index];
27584
- const { sprite, state } = item;
27585
- const evaluation = (_a = evaluations[index]) != null ? _a : evaluateInterpolation({
27586
- state,
27587
- timestamp
27588
- });
27589
- if (state.startTimestamp < 0) {
27590
- state.startTimestamp = evaluation.effectiveStartTimestamp;
27591
- }
27592
- sprite.location.current = evaluation.location;
27593
- if (evaluation.completed) {
27594
- sprite.location.current = cloneSpriteLocation(state.to);
27595
- sprite.location.from = void 0;
27596
- sprite.location.to = void 0;
27597
- sprite.location.interpolation.state = null;
27598
- } else {
27599
- active = true;
27600
- }
27601
- }
27602
- return active;
27603
- };
27604
27488
  const processInterpolationsWithWasm = (wasm, params) => {
27605
27489
  const { sprites, timestamp } = params;
27606
27490
  if (!sprites.length) {
@@ -27611,7 +27495,7 @@ const processInterpolationsWithWasm = (wasm, params) => {
27611
27495
  }
27612
27496
  const distanceInterpolationWorkItems = [];
27613
27497
  const degreeInterpolationWorkItems = [];
27614
- const spriteInterpolationWorkItems = [];
27498
+ const locationInterpolationWorkItems = [];
27615
27499
  const processedSprites = [];
27616
27500
  let hasActiveInterpolation = false;
27617
27501
  for (const sprite of sprites) {
@@ -27621,9 +27505,10 @@ const processInterpolationsWithWasm = (wasm, params) => {
27621
27505
  if (!hasSpriteInterpolation && !sprite.interpolationDirty) {
27622
27506
  continue;
27623
27507
  }
27624
- if (state) {
27625
- spriteInterpolationWorkItems.push({ sprite, state });
27626
- }
27508
+ collectLocationInterpolationWorkItems(
27509
+ sprite,
27510
+ locationInterpolationWorkItems
27511
+ );
27627
27512
  const touchedImages = [];
27628
27513
  sprite.images.forEach((orderMap) => {
27629
27514
  orderMap.forEach((image) => {
@@ -27640,13 +27525,13 @@ const processInterpolationsWithWasm = (wasm, params) => {
27640
27525
  collectDistanceInterpolationWorkItems(
27641
27526
  image,
27642
27527
  distanceInterpolationWorkItems,
27643
- {
27644
- includeOpacity: false
27645
- }
27528
+ true,
27529
+ // includeOffsetMeters
27530
+ false
27646
27531
  );
27647
27532
  }
27648
- const hasOpacityInterpolation = image.opacity.interpolation.state !== null;
27649
- const hasDegreeInterpolation = image.rotateDeg.interpolation.state !== null || image.offset.offsetDeg.interpolation.state !== null;
27533
+ const hasOpacityInterpolation = image.finalOpacity.interpolation.state !== null;
27534
+ const hasDegreeInterpolation = image.finalRotateDeg.interpolation.state !== null || image.offset.offsetDeg.interpolation.state !== null;
27650
27535
  if (hasDegreeInterpolation) {
27651
27536
  collectDegreeInterpolationWorkItems(
27652
27537
  image,
@@ -27668,11 +27553,11 @@ const processInterpolationsWithWasm = (wasm, params) => {
27668
27553
  skipChannels.offsetDeg = true;
27669
27554
  shouldSkipChannels = true;
27670
27555
  }
27671
- if (stepSpriteImageInterpolations(
27672
- image,
27673
- timestamp,
27674
- shouldSkipChannels ? { skipChannels } : void 0
27675
- )) {
27556
+ const interpolationOptions = shouldSkipChannels ? {
27557
+ skipChannels,
27558
+ autoRotationDeg: resolveAutoRotationDeg(sprite, image)
27559
+ } : { autoRotationDeg: resolveAutoRotationDeg(sprite, image) };
27560
+ if (stepSpriteImageInterpolations(image, timestamp, interpolationOptions)) {
27676
27561
  hasActiveInterpolation = true;
27677
27562
  }
27678
27563
  });
@@ -27683,29 +27568,21 @@ const processInterpolationsWithWasm = (wasm, params) => {
27683
27568
  }
27684
27569
  processedSprites.push({ sprite, touchedImages });
27685
27570
  }
27686
- const distanceRequests = distanceInterpolationWorkItems.length > 0 ? distanceInterpolationWorkItems.map(({ state }) => ({
27687
- state,
27688
- timestamp
27689
- })) : [];
27690
- const degreeRequests = degreeInterpolationWorkItems.length > 0 ? degreeInterpolationWorkItems.map(({ state }) => ({
27691
- state,
27692
- timestamp
27693
- })) : [];
27694
- const spriteRequests = spriteInterpolationWorkItems.length > 0 ? spriteInterpolationWorkItems.map(({ state }) => ({
27695
- state,
27571
+ const hasPresetRequests = distanceInterpolationWorkItems.length > 0 || degreeInterpolationWorkItems.length > 0 || locationInterpolationWorkItems.length > 0;
27572
+ const wasmResults = hasPresetRequests ? processInterpolationsViaWasm(
27573
+ wasm,
27574
+ {
27575
+ distance: distanceInterpolationWorkItems,
27576
+ degree: degreeInterpolationWorkItems,
27577
+ sprite: locationInterpolationWorkItems
27578
+ },
27696
27579
  timestamp
27697
- })) : [];
27698
- const hasPresetRequests = distanceRequests.length > 0 || degreeRequests.length > 0 || spriteRequests.length > 0;
27699
- const wasmResults = hasPresetRequests ? processInterpolationsViaWasm(wasm, {
27700
- distance: distanceRequests,
27701
- degree: degreeRequests,
27702
- sprite: spriteRequests
27703
- }) : {
27580
+ ) : {
27704
27581
  distance: [],
27705
27582
  degree: [],
27706
27583
  sprite: []
27707
27584
  };
27708
- if (distanceRequests.length > 0) {
27585
+ if (distanceInterpolationWorkItems.length > 0) {
27709
27586
  if (applyDistanceInterpolationEvaluations(
27710
27587
  distanceInterpolationWorkItems,
27711
27588
  wasmResults.distance,
@@ -27714,7 +27591,7 @@ const processInterpolationsWithWasm = (wasm, params) => {
27714
27591
  hasActiveInterpolation = true;
27715
27592
  }
27716
27593
  }
27717
- if (degreeRequests.length > 0) {
27594
+ if (degreeInterpolationWorkItems.length > 0) {
27718
27595
  if (applyDegreeInterpolationEvaluations(
27719
27596
  degreeInterpolationWorkItems,
27720
27597
  wasmResults.degree,
@@ -27723,9 +27600,9 @@ const processInterpolationsWithWasm = (wasm, params) => {
27723
27600
  hasActiveInterpolation = true;
27724
27601
  }
27725
27602
  }
27726
- if (spriteRequests.length > 0) {
27727
- if (applySpriteInterpolationEvaluations(
27728
- spriteInterpolationWorkItems,
27603
+ if (locationInterpolationWorkItems.length > 0) {
27604
+ if (applyLocationInterpolationEvaluations(
27605
+ locationInterpolationWorkItems,
27729
27606
  wasmResults.sprite,
27730
27607
  timestamp
27731
27608
  )) {
@@ -28248,6 +28125,9 @@ const convertToWasmProjectionState = (wasm, params, deps) => {
28248
28125
  9
28249
28126
  /* FLAGS */
28250
28127
  ] = inputFlags;
28128
+ const zoomScaleFactor = 1;
28129
+ const spriteMinPixel = 0;
28130
+ const spriteMaxPixel = 0;
28251
28131
  const frameConstView = parameterBuffer.subarray(
28252
28132
  frameConstOffset,
28253
28133
  frameConstOffset + INPUT_FRAME_CONSTANT_LENGTH
@@ -28264,12 +28144,12 @@ const convertToWasmProjectionState = (wasm, params, deps) => {
28264
28144
  0
28265
28145
  );
28266
28146
  frameConstView[fcCursor++] = callParams.baseMetersPerPixel;
28267
- frameConstView[fcCursor++] = callParams.spriteMinPixel;
28268
- frameConstView[fcCursor++] = callParams.spriteMaxPixel;
28147
+ frameConstView[fcCursor++] = spriteMinPixel;
28148
+ frameConstView[fcCursor++] = spriteMaxPixel;
28269
28149
  frameConstView[fcCursor++] = callParams.drawingBufferWidth;
28270
28150
  frameConstView[fcCursor++] = callParams.drawingBufferHeight;
28271
28151
  frameConstView[fcCursor++] = callParams.pixelRatio;
28272
- frameConstView[fcCursor++] = toFiniteOr(callParams.zoomScaleFactor, 1);
28152
+ frameConstView[fcCursor++] = zoomScaleFactor;
28273
28153
  frameConstView[fcCursor++] = callParams.identityScaleX;
28274
28154
  frameConstView[fcCursor++] = callParams.identityScaleY;
28275
28155
  frameConstView[fcCursor++] = callParams.identityOffsetX;
@@ -28289,7 +28169,7 @@ const convertToWasmProjectionState = (wasm, params, deps) => {
28289
28169
  frameConstView[fcCursor++] = (_c = cameraLocation == null ? void 0 : cameraLocation.z) != null ? _c : 0;
28290
28170
  state.lastFrameParams = {
28291
28171
  baseMetersPerPixel: callParams.baseMetersPerPixel,
28292
- zoomScaleFactor: toFiniteOr(callParams.zoomScaleFactor, 1)
28172
+ zoomScaleFactor
28293
28173
  };
28294
28174
  writeMatrix(
28295
28175
  parameterBuffer,
@@ -28350,7 +28230,7 @@ const convertToWasmProjectionState = (wasm, params, deps) => {
28350
28230
  const originTargetIndices = (_g = (_f = callParams.bucketBuffers) == null ? void 0 : _f.originTargetIndices) != null ? _g : null;
28351
28231
  cursor = itemOffset;
28352
28232
  bucket.forEach(([sprite, image], index) => {
28353
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k;
28233
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h, _i, _j, _k, _l;
28354
28234
  const imageHandle = image.imageHandle;
28355
28235
  const spriteHandle = sprite.handle;
28356
28236
  const originKeyCandidate = (_a2 = originReferenceKeys == null ? void 0 : originReferenceKeys[index]) != null ? _a2 : image.originReferenceKey;
@@ -28358,37 +28238,52 @@ const convertToWasmProjectionState = (wasm, params, deps) => {
28358
28238
  const originIndex = (_b2 = originTargetIndices == null ? void 0 : originTargetIndices[index]) != null ? _b2 : image.originRenderTargetIndex;
28359
28239
  const originLocation = image.originLocation;
28360
28240
  const currentLocation = sprite.location.current;
28241
+ const cameraLocation2 = preparedProjection.cameraLocation;
28242
+ const cameraDistanceMeters = cameraLocation2 !== void 0 ? calculateCartesianDistanceMeters(cameraLocation2, {
28243
+ lng: currentLocation.lng,
28244
+ lat: currentLocation.lat,
28245
+ z: (_c2 = currentLocation.z) != null ? _c2 : 0
28246
+ }) : Number.POSITIVE_INFINITY;
28247
+ const distanceScaleFactor = calculateDistanceScaleFactor(
28248
+ cameraDistanceMeters,
28249
+ callParams.resolvedScaling
28250
+ );
28251
+ const scaledImageScale = ((_d2 = image.scale) != null ? _d2 : 1) * distanceScaleFactor;
28361
28252
  parameterBuffer[cursor++] = spriteHandle;
28362
28253
  parameterBuffer[cursor++] = imageHandle;
28363
28254
  parameterBuffer[cursor++] = originIndex != null ? originIndex : SPRITE_ORIGIN_REFERENCE_INDEX_NONE;
28364
28255
  parameterBuffer[cursor++] = boolToNumber(
28365
- (_c2 = originLocation == null ? void 0 : originLocation.useResolvedAnchor) != null ? _c2 : false
28256
+ (_e2 = originLocation == null ? void 0 : originLocation.useResolvedAnchor) != null ? _e2 : false
28366
28257
  );
28367
28258
  parameterBuffer[cursor++] = modeToNumber(image.mode);
28368
- parameterBuffer[cursor++] = (_d2 = image.scale) != null ? _d2 : 1;
28369
- parameterBuffer[cursor++] = image.opacity.current;
28370
- const anchor = (_e2 = image.anchor) != null ? _e2 : { x: 0, y: 0 };
28259
+ parameterBuffer[cursor++] = scaledImageScale;
28260
+ parameterBuffer[cursor++] = image.finalOpacity.current;
28261
+ const anchor = (_f2 = image.anchor) != null ? _f2 : { x: 0, y: 0 };
28371
28262
  parameterBuffer[cursor++] = anchor.x;
28372
28263
  parameterBuffer[cursor++] = anchor.y;
28373
28264
  const offset = resolveImageOffset$1(image);
28374
28265
  parameterBuffer[cursor++] = offset.offsetMeters;
28375
28266
  parameterBuffer[cursor++] = offset.offsetDeg;
28376
- parameterBuffer[cursor++] = toFiniteOr(image.displayedRotateDeg, 0);
28377
- parameterBuffer[cursor++] = toFiniteOr(image.resolvedBaseRotateDeg, 0);
28378
- parameterBuffer[cursor++] = toFiniteOr(image.rotationCommandDeg, 0);
28267
+ const autoRotationDeg = resolveAutoRotationDeg(sprite, image);
28268
+ const resolvedRotation = normalizeAngleDeg(
28269
+ toFiniteOr(image.finalRotateDeg.current, 0)
28270
+ );
28271
+ parameterBuffer[cursor++] = resolvedRotation;
28272
+ parameterBuffer[cursor++] = toFiniteOr(autoRotationDeg, 0);
28273
+ parameterBuffer[cursor++] = toFiniteOr(image.rotateDeg, 0);
28379
28274
  parameterBuffer[cursor++] = image.order;
28380
28275
  parameterBuffer[cursor++] = image.subLayer;
28381
28276
  parameterBuffer[cursor++] = originKey != null ? originKey : SPRITE_ORIGIN_REFERENCE_KEY_NONE;
28382
- parameterBuffer[cursor++] = (_f2 = originReferenceKeys == null ? void 0 : originReferenceKeys[index]) != null ? _f2 : SPRITE_ORIGIN_REFERENCE_KEY_NONE;
28383
- parameterBuffer[cursor++] = (_g2 = originTargetIndices == null ? void 0 : originTargetIndices[index]) != null ? _g2 : SPRITE_ORIGIN_REFERENCE_INDEX_NONE;
28277
+ parameterBuffer[cursor++] = (_g2 = originReferenceKeys == null ? void 0 : originReferenceKeys[index]) != null ? _g2 : SPRITE_ORIGIN_REFERENCE_KEY_NONE;
28278
+ parameterBuffer[cursor++] = (_h = originTargetIndices == null ? void 0 : originTargetIndices[index]) != null ? _h : SPRITE_ORIGIN_REFERENCE_INDEX_NONE;
28384
28279
  parameterBuffer[cursor++] = image.imageHandle;
28385
28280
  parameterBuffer[cursor++] = currentLocation.lng;
28386
28281
  parameterBuffer[cursor++] = currentLocation.lat;
28387
- parameterBuffer[cursor++] = (_h = currentLocation.z) != null ? _h : 0;
28388
- parameterBuffer[cursor++] = (_i = originLocation == null ? void 0 : originLocation.subLayer) != null ? _i : -1;
28389
- parameterBuffer[cursor++] = (_j = originLocation == null ? void 0 : originLocation.order) != null ? _j : -1;
28282
+ parameterBuffer[cursor++] = (_i = currentLocation.z) != null ? _i : 0;
28283
+ parameterBuffer[cursor++] = (_j = originLocation == null ? void 0 : originLocation.subLayer) != null ? _j : -1;
28284
+ parameterBuffer[cursor++] = (_k = originLocation == null ? void 0 : originLocation.order) != null ? _k : -1;
28390
28285
  parameterBuffer[cursor++] = boolToNumber(
28391
- (_k = originLocation == null ? void 0 : originLocation.useResolvedAnchor) != null ? _k : false
28286
+ (_l = originLocation == null ? void 0 : originLocation.useResolvedAnchor) != null ? _l : false
28392
28287
  );
28393
28288
  parameterBuffer[cursor++] = index;
28394
28289
  });
@@ -28438,39 +28333,306 @@ const createWasmCalculationHost = (params, deps) => {
28438
28333
  }
28439
28334
  };
28440
28335
  return {
28441
- processDrawSpriteImages: (params2) => runWithFallback(
28442
- () => {
28443
- let interpolationResult = params2.interpolationParams ? processInterpolationsWithWasm(wasm, params2.interpolationParams) : DEFAULT_RENDER_INTERPOLATION_RESULT;
28444
- const preparedItems = params2.prepareParams ? prepareDrawSpriteImagesInternal(
28445
- wasm,
28446
- wasmState,
28447
- deps,
28448
- params2.prepareParams
28449
- ) : [];
28450
- if (preparedItems.length > 0) {
28451
- applyVisibilityDistanceLod(preparedItems);
28452
- }
28453
- if (params2.interpolationParams) {
28454
- const opacityResult = processOpacityInterpolationsAfterPreparation(
28455
- params2.interpolationParams,
28456
- preparedItems
28457
- );
28458
- interpolationResult = {
28459
- handled: interpolationResult.handled || opacityResult.handled,
28460
- hasActiveInterpolation: interpolationResult.hasActiveInterpolation || opacityResult.hasActiveInterpolation
28461
- };
28462
- }
28463
- syncPreparedOpacities(preparedItems);
28464
- const visiblePreparedItems = filterVisiblePreparedItems(preparedItems);
28465
- return {
28466
- interpolationResult,
28467
- preparedItems: visiblePreparedItems
28468
- };
28469
- },
28470
- () => ensureFallbackHost().processDrawSpriteImages(params2)
28471
- ),
28336
+ processDrawSpriteImages: (params2) => runWithFallback(
28337
+ () => {
28338
+ let interpolationResult = params2.interpolationParams ? processInterpolationsWithWasm(wasm, params2.interpolationParams) : DEFAULT_RENDER_INTERPOLATION_RESULT;
28339
+ const preparedItems = params2.prepareParams ? prepareDrawSpriteImagesInternal(
28340
+ wasm,
28341
+ wasmState,
28342
+ deps,
28343
+ params2.prepareParams
28344
+ ) : [];
28345
+ if (preparedItems.length > 0) {
28346
+ applyVisibilityDistanceLod(preparedItems);
28347
+ }
28348
+ if (params2.interpolationParams) {
28349
+ const opacityResult = processOpacityInterpolationsAfterPreparation(
28350
+ params2.interpolationParams,
28351
+ preparedItems
28352
+ );
28353
+ interpolationResult = {
28354
+ handled: interpolationResult.handled || opacityResult.handled,
28355
+ hasActiveInterpolation: interpolationResult.hasActiveInterpolation || opacityResult.hasActiveInterpolation
28356
+ };
28357
+ }
28358
+ syncPreparedOpacities(preparedItems);
28359
+ const visiblePreparedItems = filterVisiblePreparedItems(preparedItems);
28360
+ return {
28361
+ interpolationResult,
28362
+ preparedItems: visiblePreparedItems
28363
+ };
28364
+ },
28365
+ () => ensureFallbackHost().processDrawSpriteImages(params2)
28366
+ ),
28367
+ release: () => {
28368
+ releaseFallbackHost();
28369
+ }
28370
+ };
28371
+ };
28372
+ const createSpriteTrackingController = (mapInstance) => {
28373
+ let trackedSpriteTrackRotation = true;
28374
+ let trackedSprite;
28375
+ let trackedSpriteFrameId = null;
28376
+ const cancelTrackedSpriteFrame = () => {
28377
+ if (trackedSpriteFrameId === null) {
28378
+ return;
28379
+ }
28380
+ if (typeof window !== "undefined") {
28381
+ window.cancelAnimationFrame(trackedSpriteFrameId);
28382
+ }
28383
+ trackedSpriteFrameId = null;
28384
+ };
28385
+ const untrackSpriteInternal = () => {
28386
+ cancelTrackedSpriteFrame();
28387
+ };
28388
+ const applyTrackedSpriteRotation = (sprite) => {
28389
+ let targetBearing = null;
28390
+ for (const orderMap of sprite.images.values()) {
28391
+ const iterator = orderMap.values().next();
28392
+ if (!iterator.done) {
28393
+ targetBearing = normalizeAngleDeg(
28394
+ iterator.value.finalRotateDeg.current
28395
+ );
28396
+ break;
28397
+ }
28398
+ }
28399
+ if (targetBearing === null) {
28400
+ return false;
28401
+ }
28402
+ const currentBearing = normalizeAngleDeg(mapInstance.getBearing());
28403
+ if (currentBearing === targetBearing) {
28404
+ return false;
28405
+ }
28406
+ mapInstance.setBearing(targetBearing);
28407
+ return true;
28408
+ };
28409
+ const stepTrackedSprite = () => {
28410
+ trackedSpriteFrameId = null;
28411
+ if (!mapInstance || !trackedSprite || typeof window === "undefined") {
28412
+ return;
28413
+ }
28414
+ mapInstance.setCenter(trackedSprite.location.current);
28415
+ if (trackedSpriteTrackRotation) {
28416
+ applyTrackedSpriteRotation(trackedSprite);
28417
+ }
28418
+ trackedSpriteFrameId = window.requestAnimationFrame(stepTrackedSprite);
28419
+ };
28420
+ const trackSprite = (sprite, trackRotation) => {
28421
+ if (typeof window === "undefined") {
28422
+ return;
28423
+ }
28424
+ trackedSpriteTrackRotation = trackRotation !== false;
28425
+ trackedSprite = sprite;
28426
+ cancelTrackedSpriteFrame();
28427
+ trackedSpriteFrameId = window.requestAnimationFrame(stepTrackedSprite);
28428
+ };
28429
+ const untrackSprite = () => {
28430
+ trackedSpriteTrackRotation = true;
28431
+ trackedSprite = void 0;
28432
+ untrackSpriteInternal();
28433
+ };
28434
+ return {
28435
+ trackSprite,
28436
+ untrackSprite,
28437
+ release: () => {
28438
+ untrackSpriteInternal();
28439
+ trackedSprite = void 0;
28440
+ }
28441
+ };
28442
+ };
28443
+ const createSpriteMouseEventsController = ({
28444
+ resolveHitTestResult,
28445
+ resolveSpriteEventPayload,
28446
+ updateVisibilityState
28447
+ }) => {
28448
+ const eventListeners = /* @__PURE__ */ new Map();
28449
+ const inputListenerDisposers = [];
28450
+ let boundCanvasElement;
28451
+ const registerDisposer = (disposer) => {
28452
+ inputListenerDisposers.push(disposer);
28453
+ };
28454
+ const clearDomListeners = () => {
28455
+ inputListenerDisposers.forEach((dispose) => dispose());
28456
+ inputListenerDisposers.length = 0;
28457
+ };
28458
+ const getListenerSet = (type) => {
28459
+ let set = eventListeners.get(type);
28460
+ if (!set) {
28461
+ set = /* @__PURE__ */ new Set();
28462
+ eventListeners.set(type, set);
28463
+ }
28464
+ return set;
28465
+ };
28466
+ const addEventListener2 = (type, listener) => {
28467
+ getListenerSet(type).add(listener);
28468
+ };
28469
+ const removeEventListener2 = (type, listener) => {
28470
+ const listeners = eventListeners.get(type);
28471
+ if (!listeners) {
28472
+ return;
28473
+ }
28474
+ listeners.delete(listener);
28475
+ if (listeners.size === 0) {
28476
+ eventListeners.delete(type);
28477
+ }
28478
+ };
28479
+ const hasSpriteListeners = (type) => {
28480
+ var _a, _b;
28481
+ return ((_b = (_a = eventListeners.get(type)) == null ? void 0 : _a.size) != null ? _b : 0) > 0;
28482
+ };
28483
+ const hasSpriteClickListeners = () => hasSpriteListeners("spriteclick");
28484
+ const hasSpriteHoverListeners = () => hasSpriteListeners("spritehover");
28485
+ const dispatchSpriteClick = (hitEntry, screenPoint, originalEvent) => {
28486
+ const listeners = eventListeners.get("spriteclick");
28487
+ if (!listeners || listeners.size === 0) {
28488
+ return;
28489
+ }
28490
+ const payload = resolveSpriteEventPayload(hitEntry);
28491
+ const clickEvent = {
28492
+ type: "spriteclick",
28493
+ sprite: payload.sprite,
28494
+ image: payload.image,
28495
+ screenPoint,
28496
+ originalEvent
28497
+ };
28498
+ listeners.forEach((listener) => {
28499
+ listener(clickEvent);
28500
+ });
28501
+ };
28502
+ const dispatchSpriteHover = (hitEntry, screenPoint, originalEvent) => {
28503
+ const listeners = eventListeners.get("spritehover");
28504
+ if (!listeners || listeners.size === 0) {
28505
+ return;
28506
+ }
28507
+ const payload = resolveSpriteEventPayload(hitEntry);
28508
+ const hoverEvent = {
28509
+ type: "spritehover",
28510
+ sprite: payload.sprite,
28511
+ image: payload.image,
28512
+ screenPoint,
28513
+ originalEvent
28514
+ };
28515
+ listeners.forEach((listener) => {
28516
+ listener(hoverEvent);
28517
+ });
28518
+ };
28519
+ const processClickEvent = (nativeEvent) => {
28520
+ if (!hasSpriteClickListeners()) {
28521
+ return;
28522
+ }
28523
+ const hitResult = resolveHitTestResult(nativeEvent);
28524
+ if (!hitResult || !hitResult.hitEntry) {
28525
+ return;
28526
+ }
28527
+ dispatchSpriteClick(hitResult.hitEntry, hitResult.screenPoint, nativeEvent);
28528
+ };
28529
+ const processHoverEvent = (nativeEvent) => {
28530
+ if (!hasSpriteHoverListeners()) {
28531
+ return;
28532
+ }
28533
+ const hitResult = resolveHitTestResult(nativeEvent);
28534
+ if (!hitResult) {
28535
+ return;
28536
+ }
28537
+ dispatchSpriteHover(hitResult.hitEntry, hitResult.screenPoint, nativeEvent);
28538
+ };
28539
+ const bindCanvas = (canvasElement) => {
28540
+ var _a;
28541
+ clearDomListeners();
28542
+ boundCanvasElement = canvasElement;
28543
+ const supportsPointerEvents = typeof window !== "undefined" && "PointerEvent" in window;
28544
+ if (canvasElement) {
28545
+ if (supportsPointerEvents) {
28546
+ const pointerUpListener = (event) => {
28547
+ if (event.pointerType === "mouse" && event.button !== 0) {
28548
+ return;
28549
+ }
28550
+ processClickEvent(event);
28551
+ };
28552
+ canvasElement.addEventListener("pointerup", pointerUpListener, {
28553
+ passive: true
28554
+ });
28555
+ registerDisposer(() => {
28556
+ canvasElement.removeEventListener("pointerup", pointerUpListener);
28557
+ });
28558
+ const pointerMoveListener = (event) => {
28559
+ if (!event.isPrimary) {
28560
+ return;
28561
+ }
28562
+ if (event.pointerType === "touch") {
28563
+ return;
28564
+ }
28565
+ processHoverEvent(event);
28566
+ };
28567
+ canvasElement.addEventListener("pointermove", pointerMoveListener, {
28568
+ passive: true
28569
+ });
28570
+ registerDisposer(() => {
28571
+ canvasElement.removeEventListener("pointermove", pointerMoveListener);
28572
+ });
28573
+ } else {
28574
+ const clickListener = (event) => {
28575
+ if (event.button !== 0) {
28576
+ return;
28577
+ }
28578
+ processClickEvent(event);
28579
+ };
28580
+ canvasElement.addEventListener("click", clickListener, {
28581
+ passive: true
28582
+ });
28583
+ registerDisposer(() => {
28584
+ canvasElement.removeEventListener("click", clickListener);
28585
+ });
28586
+ const touchListener = (event) => {
28587
+ processClickEvent(event);
28588
+ };
28589
+ canvasElement.addEventListener("touchend", touchListener, {
28590
+ passive: true
28591
+ });
28592
+ registerDisposer(() => {
28593
+ canvasElement.removeEventListener("touchend", touchListener);
28594
+ });
28595
+ const mouseMoveListener = (event) => {
28596
+ processHoverEvent(event);
28597
+ };
28598
+ canvasElement.addEventListener("mousemove", mouseMoveListener, {
28599
+ passive: true
28600
+ });
28601
+ registerDisposer(() => {
28602
+ canvasElement.removeEventListener("mousemove", mouseMoveListener);
28603
+ });
28604
+ }
28605
+ const visibilityTarget = (_a = canvasElement.ownerDocument) != null ? _a : typeof document !== "undefined" ? document : void 0;
28606
+ if (visibilityTarget) {
28607
+ const visibilityListener = () => updateVisibilityState();
28608
+ visibilityTarget.addEventListener(
28609
+ "visibilitychange",
28610
+ visibilityListener
28611
+ );
28612
+ registerDisposer(() => {
28613
+ visibilityTarget.removeEventListener(
28614
+ "visibilitychange",
28615
+ visibilityListener
28616
+ );
28617
+ });
28618
+ updateVisibilityState();
28619
+ }
28620
+ }
28621
+ };
28622
+ return {
28623
+ get canvasElement() {
28624
+ return boundCanvasElement;
28625
+ },
28626
+ addEventListener: addEventListener2,
28627
+ removeEventListener: removeEventListener2,
28628
+ hasSpriteClickListeners,
28629
+ hasSpriteHoverListeners,
28630
+ bindCanvas,
28472
28631
  release: () => {
28473
- releaseFallbackHost();
28632
+ clearDomListeners();
28633
+ eventListeners.forEach((set) => set.clear());
28634
+ eventListeners.clear();
28635
+ boundCanvasElement = void 0;
28474
28636
  }
28475
28637
  };
28476
28638
  };
@@ -29271,6 +29433,9 @@ const resolveImageOffset = (image) => {
29271
29433
  offsetDeg: offset.offsetDeg.current
29272
29434
  };
29273
29435
  };
29436
+ const resolveImageAutoRotationDeg$1 = (sprite, image) => {
29437
+ return image.autoRotation ? sprite.currentAutoRotateDeg : 0;
29438
+ };
29274
29439
  const createHitTestController = ({
29275
29440
  images,
29276
29441
  getResolvedScaling
@@ -29341,7 +29506,6 @@ const createHitTestController = ({
29341
29506
  const scaling = getResolvedScaling();
29342
29507
  const baseLocation = sprite.location.current;
29343
29508
  const zoom = projectionHost.getZoom();
29344
- const zoomScaleFactor = calculateZoomScaleFactor(zoom, scaling);
29345
29509
  const metersPerPixelAtLat = calculateMetersPerPixelAtLatitude(
29346
29510
  zoom,
29347
29511
  baseLocation.lat
@@ -29361,35 +29525,39 @@ const createHitTestController = ({
29361
29525
  if (!Number.isFinite(effectivePixelsPerMeter) || effectivePixelsPerMeter <= 0) {
29362
29526
  return null;
29363
29527
  }
29364
- const imageScale = (_a = image.scale) != null ? _a : 1;
29528
+ const cameraLocation = projectionHost.getCameraLocation();
29529
+ const cameraDistanceMeters = cameraLocation !== void 0 ? calculateCartesianDistanceMeters(cameraLocation, {
29530
+ lng: baseLocation.lng,
29531
+ lat: baseLocation.lat,
29532
+ z: (_a = baseLocation.z) != null ? _a : 0
29533
+ }) : Number.POSITIVE_INFINITY;
29534
+ const distanceScaleFactor = calculateDistanceScaleFactor(
29535
+ cameraDistanceMeters,
29536
+ scaling
29537
+ );
29538
+ const imageScale = (_b = image.scale) != null ? _b : 1;
29365
29539
  const baseMetersPerPixel = scaling.metersPerPixel;
29366
- const spriteMinPixel = scaling.spriteMinPixel;
29367
- const spriteMaxPixel = scaling.spriteMaxPixel;
29368
29540
  const worldDims = calculateSurfaceWorldDimensions(
29369
29541
  imageResource.width,
29370
29542
  imageResource.height,
29371
29543
  baseMetersPerPixel,
29372
29544
  imageScale,
29373
- zoomScaleFactor,
29374
- {
29375
- effectivePixelsPerMeter,
29376
- spriteMinPixel,
29377
- spriteMaxPixel
29378
- }
29545
+ distanceScaleFactor
29379
29546
  );
29380
29547
  if (worldDims.width <= 0 || worldDims.height <= 0) {
29381
29548
  return null;
29382
29549
  }
29383
- const anchor = (_b = image.anchor) != null ? _b : DEFAULT_ANCHOR;
29550
+ const anchor = (_c = image.anchor) != null ? _c : DEFAULT_ANCHOR;
29384
29551
  const offsetDef = resolveImageOffset(image);
29385
29552
  const offsetMetersVec = calculateSurfaceOffsetMeters(
29386
29553
  offsetDef,
29387
29554
  imageScale,
29388
- zoomScaleFactor,
29555
+ distanceScaleFactor,
29389
29556
  worldDims.scaleAdjustment
29390
29557
  );
29391
- const totalRotateDeg = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : normalizeAngleDeg(
29392
- ((_c = image.resolvedBaseRotateDeg) != null ? _c : 0) + image.rotationCommandDeg
29558
+ const autoRotationDeg = resolveImageAutoRotationDeg$1(sprite, image);
29559
+ const totalRotateDeg = normalizeAngleDeg(
29560
+ Number.isFinite(image.finalRotateDeg.current) ? image.finalRotateDeg.current : autoRotationDeg + image.rotateDeg
29393
29561
  );
29394
29562
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
29395
29563
  worldWidthMeters: worldDims.width,
@@ -29412,7 +29580,6 @@ const createHitTestController = ({
29412
29580
  const scaling = getResolvedScaling();
29413
29581
  const baseLocation = sprite.location.current;
29414
29582
  const zoom = projectionHost.getZoom();
29415
- const zoomScaleFactor = calculateZoomScaleFactor(zoom, scaling);
29416
29583
  const metersPerPixelAtLat = calculateMetersPerPixelAtLatitude(
29417
29584
  zoom,
29418
29585
  baseLocation.lat
@@ -29432,22 +29599,29 @@ const createHitTestController = ({
29432
29599
  if (!Number.isFinite(effectivePixelsPerMeter) || effectivePixelsPerMeter <= 0) {
29433
29600
  return null;
29434
29601
  }
29602
+ const cameraLocation = projectionHost.getCameraLocation();
29603
+ const cameraDistanceMeters = cameraLocation !== void 0 ? calculateCartesianDistanceMeters(cameraLocation, {
29604
+ lng: baseLocation.lng,
29605
+ lat: baseLocation.lat,
29606
+ z: (_a = baseLocation.z) != null ? _a : 0
29607
+ }) : Number.POSITIVE_INFINITY;
29608
+ const distanceScaleFactor = calculateDistanceScaleFactor(
29609
+ cameraDistanceMeters,
29610
+ scaling
29611
+ );
29435
29612
  const baseMetersPerPixel = scaling.metersPerPixel;
29436
- const spriteMinPixel = scaling.spriteMinPixel;
29437
- const spriteMaxPixel = scaling.spriteMaxPixel;
29438
- const imageScale = (_a = image.scale) != null ? _a : 1;
29439
- const totalRotateDeg = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : normalizeAngleDeg(
29440
- ((_b = image.resolvedBaseRotateDeg) != null ? _b : 0) + image.rotationCommandDeg
29613
+ const imageScale = (_b = image.scale) != null ? _b : 1;
29614
+ const autoRotationDeg = resolveImageAutoRotationDeg$1(sprite, image);
29615
+ const totalRotateDeg = normalizeAngleDeg(
29616
+ Number.isFinite(image.finalRotateDeg.current) ? image.finalRotateDeg.current : autoRotationDeg + image.rotateDeg
29441
29617
  );
29442
29618
  const pixelDims = calculateBillboardPixelDimensions(
29443
29619
  imageResource.width,
29444
29620
  imageResource.height,
29445
29621
  baseMetersPerPixel,
29446
29622
  imageScale,
29447
- zoomScaleFactor,
29448
- effectivePixelsPerMeter,
29449
- spriteMinPixel,
29450
- spriteMaxPixel
29623
+ distanceScaleFactor,
29624
+ effectivePixelsPerMeter
29451
29625
  );
29452
29626
  const halfWidthMeters = pixelDims.width / 2 / effectivePixelsPerMeter;
29453
29627
  const halfHeightMeters = pixelDims.height / 2 / effectivePixelsPerMeter;
@@ -29460,7 +29634,7 @@ const createHitTestController = ({
29460
29634
  const offsetShift = calculateBillboardOffsetPixels(
29461
29635
  resolveImageOffset(image),
29462
29636
  imageScale,
29463
- zoomScaleFactor,
29637
+ distanceScaleFactor,
29464
29638
  effectivePixelsPerMeter
29465
29639
  );
29466
29640
  const anchorShiftMeters = Math.hypot(anchorShift.x, anchorShift.y) / effectivePixelsPerMeter;
@@ -29469,7 +29643,7 @@ const createHitTestController = ({
29469
29643
  return rectFromRadiusMeters(baseLocation, safetyRadius);
29470
29644
  };
29471
29645
  const estimateImageBounds = (projectionHost, sprite, image) => {
29472
- if (image.opacity.current <= 0 || !sprite.isEnabled) {
29646
+ if (image.finalOpacity.current <= 0 || !sprite.isEnabled) {
29473
29647
  return null;
29474
29648
  }
29475
29649
  if (image.mode === "surface") {
@@ -29749,7 +29923,7 @@ const createHitTestController = ({
29749
29923
  hitTestTree.clear();
29750
29924
  hitTestTreeItems = /* @__PURE__ */ new WeakMap();
29751
29925
  };
29752
- const setHitTestEnabled = (enabled) => {
29926
+ const setHitTestDetection = (enabled) => {
29753
29927
  if (isHitTestEnabled === enabled) {
29754
29928
  return false;
29755
29929
  }
@@ -29768,7 +29942,7 @@ const createHitTestController = ({
29768
29942
  refreshSpriteHitTestBounds,
29769
29943
  findTopmostHitEntry,
29770
29944
  resolveHitTestResult,
29771
- setHitTestEnabled,
29945
+ setHitTestDetection,
29772
29946
  isHitTestEnabled: isHitTestEnabledFn
29773
29947
  };
29774
29948
  };
@@ -30270,12 +30444,15 @@ const reapplySpriteOpacityMultiplier = (sprite) => {
30270
30444
  sprite.images.forEach((orderMap) => {
30271
30445
  orderMap.forEach((image) => {
30272
30446
  var _a2, _b;
30273
- const baseOpacity = (_a2 = image.opacity.interpolation.baseValue) != null ? _a2 : image.opacity.current;
30274
- const interpolationOption = (_b = image.opacity.interpolation.options) != null ? _b : null;
30447
+ const baseOpacity = (_a2 = image.finalOpacity.interpolation.baseValue) != null ? _a2 : image.finalOpacity.current;
30448
+ const interpolationOption = (_b = image.finalOpacity.interpolation.options) != null ? _b : null;
30275
30449
  applyOpacityUpdate(image, baseOpacity, interpolationOption, multiplier);
30276
30450
  });
30277
30451
  });
30278
30452
  };
30453
+ const resolveImageAutoRotationDeg = (sprite, image) => {
30454
+ return image.autoRotation ? sprite.currentAutoRotateDeg : 0;
30455
+ };
30279
30456
  const applyAutoRotation = (sprite, nextLocation, forceAutoRotation) => {
30280
30457
  let hasAutoRotation = false;
30281
30458
  let requiredDistance = 0;
@@ -30308,20 +30485,19 @@ const applyAutoRotation = (sprite, nextLocation, forceAutoRotation) => {
30308
30485
  if (distanceMeters < requiredDistance) {
30309
30486
  return false;
30310
30487
  }
30311
- const resolvedAngleRaw = isFiniteNumber(bearingDeg) ? bearingDeg : sprite.lastAutoRotationAngleDeg;
30488
+ const resolvedAngleRaw = isFiniteNumber(bearingDeg) ? bearingDeg : sprite.currentAutoRotateDeg;
30312
30489
  const resolvedAngle = normalizeAngleDeg(resolvedAngleRaw);
30490
+ sprite.currentAutoRotateDeg = resolvedAngle;
30313
30491
  sprite.images.forEach((orderMap) => {
30314
30492
  orderMap.forEach((image) => {
30315
30493
  if (!image.autoRotation) {
30316
30494
  return;
30317
30495
  }
30318
- image.resolvedBaseRotateDeg = resolvedAngle;
30319
- syncImageRotationChannel(image);
30496
+ syncImageRotationChannel(image, resolvedAngle);
30320
30497
  updateImageInterpolationDirtyState(sprite, image);
30321
30498
  });
30322
30499
  });
30323
30500
  sprite.lastAutoRotationLocation = cloneSpriteLocation(nextLocation);
30324
- sprite.lastAutoRotationAngleDeg = resolvedAngle;
30325
30501
  return true;
30326
30502
  };
30327
30503
  const cloneOriginLocation = (origin) => {
@@ -30343,17 +30519,15 @@ const cloneAnchor = (anchor) => {
30343
30519
  }
30344
30520
  return { x: anchor.x, y: anchor.y };
30345
30521
  };
30346
- const cloneOffset = (offset) => {
30347
- if (!offset) {
30348
- return { ...DEFAULT_IMAGE_OFFSET };
30349
- }
30522
+ const resolveOffsetInput = (offset) => {
30523
+ var _a, _b;
30350
30524
  return {
30351
- offsetMeters: offset.offsetMeters,
30352
- offsetDeg: offset.offsetDeg
30525
+ offsetMeters: (_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : DEFAULT_IMAGE_OFFSET.offsetMeters,
30526
+ offsetDeg: (_b = offset == null ? void 0 : offset.offsetDeg) != null ? _b : DEFAULT_IMAGE_OFFSET.offsetDeg
30353
30527
  };
30354
30528
  };
30355
30529
  const createInterpolatedOffsetState = (offset, invalidated) => {
30356
- const base = offset ? cloneOffset(offset) : { ...DEFAULT_IMAGE_OFFSET };
30530
+ const base = resolveOffsetInput(offset);
30357
30531
  return {
30358
30532
  offsetMeters: {
30359
30533
  current: base.offsetMeters,
@@ -30427,11 +30601,14 @@ const sanitizeOpacityMultiplier = (value) => {
30427
30601
  }
30428
30602
  return value;
30429
30603
  };
30430
- const createImageStateFromInit = (imageInit, subLayer, order, originReference, invalidated) => {
30431
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
30604
+ const createImageStateFromInit = (imageInit, subLayer, order, originReference, invalidated, spriteAutoRotationDeg = 0) => {
30605
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
30432
30606
  const mode = (_a = imageInit.mode) != null ? _a : "surface";
30433
30607
  const autoRotationDefault = mode === "surface";
30434
- const initialOffset = cloneOffset(imageInit.offset);
30608
+ const initialOffset = resolveOffsetInput({
30609
+ offsetMeters: imageInit.offsetMeters,
30610
+ offsetDeg: imageInit.offsetDeg
30611
+ });
30435
30612
  const initialOpacity = clampOpacity((_b = imageInit.opacity) != null ? _b : 1);
30436
30613
  const initialRotateDeg = normalizeAngleDeg((_c = imageInit.rotateDeg) != null ? _c : 0);
30437
30614
  const originLocation = cloneOriginLocation(imageInit.originLocation);
@@ -30442,7 +30619,9 @@ const createImageStateFromInit = (imageInit, subLayer, order, originReference, i
30442
30619
  imageId: imageInit.imageId,
30443
30620
  imageHandle: 0,
30444
30621
  mode,
30445
- opacity: {
30622
+ rotateDeg: initialRotateDeg,
30623
+ opacity: initialOpacity,
30624
+ finalOpacity: {
30446
30625
  current: initialOpacity,
30447
30626
  from: void 0,
30448
30627
  to: void 0,
@@ -30463,7 +30642,7 @@ const createImageStateFromInit = (imageInit, subLayer, order, originReference, i
30463
30642
  leaderLine: resolveSpriteImageLineAttribute(imageInit.leaderLine),
30464
30643
  leaderLinePixelWidth: 0,
30465
30644
  offset: createInterpolatedOffsetState(initialOffset, invalidated),
30466
- rotateDeg: {
30645
+ finalRotateDeg: {
30467
30646
  current: initialRotateDeg,
30468
30647
  from: void 0,
30469
30648
  to: void 0,
@@ -30476,25 +30655,28 @@ const createImageStateFromInit = (imageInit, subLayer, order, originReference, i
30476
30655
  targetValue: void 0
30477
30656
  }
30478
30657
  },
30479
- rotationCommandDeg: initialRotateDeg,
30480
- displayedRotateDeg: initialRotateDeg,
30481
30658
  autoRotation: (_e = imageInit.autoRotation) != null ? _e : autoRotationDefault,
30482
30659
  autoRotationMinDistanceMeters: (_f = imageInit.autoRotationMinDistanceMeters) != null ? _f : DEFAULT_AUTO_ROTATION_MIN_DISTANCE_METERS,
30483
- resolvedBaseRotateDeg: 0,
30484
30660
  originLocation,
30485
30661
  originReferenceKey,
30486
30662
  originRenderTargetIndex: SPRITE_ORIGIN_REFERENCE_INDEX_NONE,
30487
- interpolationDirty: false
30663
+ interpolationDirty: false,
30664
+ surfaceShaderInputs: void 0,
30665
+ hitTestCorners: void 0
30488
30666
  };
30489
- const rotateInitOption = (_h = (_g = imageInit.interpolation) == null ? void 0 : _g.rotateDeg) != null ? _h : null;
30667
+ const rotateInitOption = (_h = (_g = imageInit.interpolation) == null ? void 0 : _g.finalRotateDeg) != null ? _h : null;
30490
30668
  if (rotateInitOption) {
30491
- state.rotateDeg.interpolation.options = cloneInterpolationOptions(rotateInitOption);
30669
+ state.finalRotateDeg.interpolation.options = cloneInterpolationOptions(rotateInitOption);
30492
30670
  }
30493
- const opacityInitOption = (_j = (_i = imageInit.interpolation) == null ? void 0 : _i.opacity) != null ? _j : null;
30671
+ const opacityInitOption = (_j = (_i = imageInit.interpolation) == null ? void 0 : _i.finalOpacity) != null ? _j : null;
30494
30672
  if (opacityInitOption) {
30495
- state.opacity.interpolation.options = cloneInterpolationOptions(opacityInitOption);
30673
+ state.finalOpacity.interpolation.options = cloneInterpolationOptions(opacityInitOption);
30496
30674
  }
30497
- syncImageRotationChannel(state);
30675
+ syncImageRotationChannel(
30676
+ state,
30677
+ spriteAutoRotationDeg,
30678
+ (_k = state.finalRotateDeg.interpolation.options) != null ? _k : void 0
30679
+ );
30498
30680
  return state;
30499
30681
  };
30500
30682
  const createSpriteLayer = (options) => {
@@ -30737,6 +30919,7 @@ const createSpriteLayer = (options) => {
30737
30919
  images,
30738
30920
  getResolvedScaling: () => resolvedScaling
30739
30921
  });
30922
+ let trackingController;
30740
30923
  const syncAtlasPlacementsFromManager = () => {
30741
30924
  let placementsChanged = false;
30742
30925
  images.forEach((image, imageId) => {
@@ -30771,14 +30954,14 @@ const createSpriteLayer = (options) => {
30771
30954
  const sprites = /* @__PURE__ */ new Map();
30772
30955
  const invalidateImageInterpolationState = (sprite, image) => {
30773
30956
  var _a2;
30774
- image.rotateDeg.interpolation.state = null;
30957
+ image.finalRotateDeg.interpolation.state = null;
30775
30958
  image.offset.offsetDeg.interpolation.state = null;
30776
30959
  image.offset.offsetMeters.interpolation.state = null;
30777
- image.opacity.interpolation.state = null;
30778
- image.rotateDeg.from = void 0;
30779
- image.rotateDeg.to = void 0;
30780
- image.rotateDeg.invalidated = true;
30781
- image.rotateDeg.interpolation.lastCommandValue = image.rotateDeg.current;
30960
+ image.finalOpacity.interpolation.state = null;
30961
+ image.finalRotateDeg.from = void 0;
30962
+ image.finalRotateDeg.to = void 0;
30963
+ image.finalRotateDeg.invalidated = true;
30964
+ image.finalRotateDeg.interpolation.lastCommandValue = image.finalRotateDeg.current;
30782
30965
  image.offset.offsetDeg.from = void 0;
30783
30966
  image.offset.offsetDeg.to = void 0;
30784
30967
  image.offset.offsetDeg.invalidated = true;
@@ -30787,16 +30970,16 @@ const createSpriteLayer = (options) => {
30787
30970
  image.offset.offsetMeters.to = void 0;
30788
30971
  image.offset.offsetMeters.invalidated = true;
30789
30972
  image.offset.offsetMeters.interpolation.lastCommandValue = image.offset.offsetMeters.current;
30790
- image.opacity.from = void 0;
30791
- image.opacity.to = void 0;
30792
- image.opacity.invalidated = true;
30793
- image.opacity.interpolation.targetValue = image.opacity.current;
30794
- image.opacity.interpolation.lastCommandValue = image.opacity.current;
30973
+ image.finalOpacity.from = void 0;
30974
+ image.finalOpacity.to = void 0;
30975
+ image.finalOpacity.invalidated = true;
30976
+ image.finalOpacity.interpolation.targetValue = image.finalOpacity.current;
30977
+ image.finalOpacity.interpolation.lastCommandValue = image.finalOpacity.current;
30795
30978
  const spriteOpacityMultiplier = (_a2 = sprite.opacityMultiplier) != null ? _a2 : 1;
30796
30979
  const lodMultiplier = image.lodOpacity || 1;
30797
30980
  if (spriteOpacityMultiplier > 0 && lodMultiplier > 0) {
30798
- image.opacity.interpolation.baseValue = clampOpacity(
30799
- image.opacity.current / (spriteOpacityMultiplier * lodMultiplier)
30981
+ image.finalOpacity.interpolation.baseValue = clampOpacity(
30982
+ image.finalOpacity.current / (spriteOpacityMultiplier * lodMultiplier)
30800
30983
  );
30801
30984
  }
30802
30985
  updateImageInterpolationDirtyState(sprite, image);
@@ -30815,7 +30998,8 @@ const createSpriteLayer = (options) => {
30815
30998
  sprite.images.forEach((orderMap) => {
30816
30999
  orderMap.forEach((image) => {
30817
31000
  invalidateImageInterpolationState(sprite, image);
30818
- image.displayedRotateDeg = image.resolvedBaseRotateDeg + image.rotationCommandDeg;
31001
+ const autoRotationDeg = resolveImageAutoRotationDeg(sprite, image);
31002
+ image.finalRotateDeg.current = autoRotationDeg + image.rotateDeg;
30819
31003
  });
30820
31004
  });
30821
31005
  };
@@ -30888,30 +31072,7 @@ const createSpriteLayer = (options) => {
30888
31072
  return Array.from(buckets.keys()).sort((a, b) => a - b).map((subLayer) => [subLayer, buckets.get(subLayer)]);
30889
31073
  };
30890
31074
  const renderTargetEntries = [];
30891
- const eventListeners = /* @__PURE__ */ new Map();
30892
- const getListenerSet = (type) => {
30893
- let set = eventListeners.get(type);
30894
- if (!set) {
30895
- set = /* @__PURE__ */ new Set();
30896
- eventListeners.set(type, set);
30897
- }
30898
- return set;
30899
- };
30900
- const addEventListener2 = (type, listener) => {
30901
- getListenerSet(type).add(listener);
30902
- };
30903
- const removeEventListener2 = (type, listener) => {
30904
- const listeners = eventListeners.get(type);
30905
- if (!listeners) {
30906
- return;
30907
- }
30908
- listeners.delete(listener);
30909
- if (listeners.size === 0) {
30910
- eventListeners.delete(type);
30911
- }
30912
- };
30913
31075
  let canvasElement;
30914
- const inputListenerDisposers = [];
30915
31076
  let mapVisible = typeof document !== "undefined" ? document.visibilityState !== "hidden" : true;
30916
31077
  const resolveDocumentVisibility = () => {
30917
31078
  var _a2;
@@ -30919,15 +31080,6 @@ const createSpriteLayer = (options) => {
30919
31080
  return doc ? doc.visibilityState !== "hidden" : true;
30920
31081
  };
30921
31082
  const isLayerVisible = () => mapVisible;
30922
- const hasSpriteListeners = (type) => {
30923
- var _a2, _b;
30924
- return (
30925
- // Treat missing listener sets as zero, otherwise check the registered count.
30926
- ((_b = (_a2 = eventListeners.get(type)) == null ? void 0 : _a2.size) != null ? _b : 0) > 0
30927
- );
30928
- };
30929
- const hasSpriteClickListeners = () => hasSpriteListeners("spriteclick");
30930
- const hasSpriteHoverListeners = () => hasSpriteListeners("spritehover");
30931
31083
  const resolveSpriteEventPayload = (hitEntry) => {
30932
31084
  var _a2, _b;
30933
31085
  if (!hitEntry) {
@@ -30943,40 +31095,6 @@ const createSpriteLayer = (options) => {
30943
31095
  image: imageState
30944
31096
  };
30945
31097
  };
30946
- const dispatchSpriteClick = (hitEntry, screenPoint, originalEvent) => {
30947
- const listeners = eventListeners.get("spriteclick");
30948
- if (!listeners || listeners.size === 0) {
30949
- return;
30950
- }
30951
- const payload = resolveSpriteEventPayload(hitEntry);
30952
- const clickEvent = {
30953
- type: "spriteclick",
30954
- sprite: payload.sprite,
30955
- image: payload.image,
30956
- screenPoint,
30957
- originalEvent
30958
- };
30959
- listeners.forEach((listener) => {
30960
- listener(clickEvent);
30961
- });
30962
- };
30963
- const dispatchSpriteHover = (hitEntry, screenPoint, originalEvent) => {
30964
- const listeners = eventListeners.get("spritehover");
30965
- if (!listeners || listeners.size === 0) {
30966
- return;
30967
- }
30968
- const payload = resolveSpriteEventPayload(hitEntry);
30969
- const hoverEvent = {
30970
- type: "spritehover",
30971
- sprite: payload.sprite,
30972
- image: payload.image,
30973
- screenPoint,
30974
- originalEvent
30975
- };
30976
- listeners.forEach((listener) => {
30977
- listener(hoverEvent);
30978
- });
30979
- };
30980
31098
  const resolveHitTestResult = (nativeEvent) => {
30981
31099
  return hitTestController.resolveHitTestResult(
30982
31100
  nativeEvent,
@@ -30984,26 +31102,11 @@ const createSpriteLayer = (options) => {
30984
31102
  map
30985
31103
  );
30986
31104
  };
30987
- const processClickEvent = (nativeEvent) => {
30988
- if (!hasSpriteClickListeners()) {
30989
- return;
30990
- }
30991
- const hitResult = resolveHitTestResult(nativeEvent);
30992
- if (!hitResult || !hitResult.hitEntry) {
30993
- return;
30994
- }
30995
- dispatchSpriteClick(hitResult.hitEntry, hitResult.screenPoint, nativeEvent);
30996
- };
30997
- const processHoverEvent = (nativeEvent) => {
30998
- if (!hasSpriteHoverListeners()) {
30999
- return;
31000
- }
31001
- const hitResult = resolveHitTestResult(nativeEvent);
31002
- if (!hitResult) {
31003
- return;
31004
- }
31005
- dispatchSpriteHover(hitResult.hitEntry, hitResult.screenPoint, nativeEvent);
31006
- };
31105
+ const mouseEventsController = createSpriteMouseEventsController({
31106
+ resolveHitTestResult,
31107
+ resolveSpriteEventPayload,
31108
+ updateVisibilityState
31109
+ });
31007
31110
  let isRenderScheduled = false;
31008
31111
  const scheduleRender = () => {
31009
31112
  if (!map || isRenderScheduled) {
@@ -31029,9 +31132,10 @@ const createSpriteLayer = (options) => {
31029
31132
  sprite.images.forEach((orderMap) => {
31030
31133
  orderMap.forEach((image) => {
31031
31134
  var _a3;
31032
- const baseOpacity = (_a3 = image.opacity.interpolation.baseValue) != null ? _a3 : image.opacity.interpolation.lastCommandValue;
31135
+ const isOpacityInterpolating = image.finalOpacity.interpolation.state !== null;
31136
+ const baseOpacity = (_a3 = image.finalOpacity.interpolation.baseValue) != null ? _a3 : image.finalOpacity.interpolation.lastCommandValue;
31033
31137
  const shouldForceVisibilityCheck = sprite.visibilityDistanceMeters !== void 0 && (baseOpacity != null ? baseOpacity : 0) > OPACITY_VISIBILITY_EPSILON;
31034
- if (image.opacity.current <= 0 && !shouldForceVisibilityCheck) {
31138
+ if (image.finalOpacity.current <= 0 && !isOpacityInterpolating && !shouldForceVisibilityCheck) {
31035
31139
  image.originRenderTargetIndex = SPRITE_ORIGIN_REFERENCE_INDEX_NONE;
31036
31140
  image.originReferenceKey = SPRITE_ORIGIN_REFERENCE_KEY_NONE;
31037
31141
  return;
@@ -31089,9 +31193,20 @@ const createSpriteLayer = (options) => {
31089
31193
  image.originRenderTargetIndex = targetIndex;
31090
31194
  }
31091
31195
  };
31196
+ const trackSprite = (spriteId, trackRotation) => {
31197
+ const sprite = sprites.get(spriteId);
31198
+ if (!sprite) {
31199
+ trackingController == null ? void 0 : trackingController.untrackSprite();
31200
+ return;
31201
+ }
31202
+ trackingController == null ? void 0 : trackingController.trackSprite(sprite, trackRotation != null ? trackRotation : true);
31203
+ };
31204
+ const untrackSprite = () => {
31205
+ trackingController == null ? void 0 : trackingController.untrackSprite();
31206
+ };
31092
31207
  const onAdd = (mapInstance, glContext) => {
31093
- var _a2;
31094
31208
  map = mapInstance;
31209
+ trackingController = createSpriteTrackingController(mapInstance);
31095
31210
  gl = glContext;
31096
31211
  anisotropyExtension = resolveAnisotropyExtension(glContext);
31097
31212
  if (anisotropyExtension) {
@@ -31108,96 +31223,15 @@ const createSpriteLayer = (options) => {
31108
31223
  maxSupportedAnisotropy = 1;
31109
31224
  }
31110
31225
  canvasElement = mapInstance.getCanvas();
31111
- const registerDisposer = (disposer) => {
31112
- inputListenerDisposers.push(disposer);
31113
- };
31114
- const supportsPointerEvents = typeof window !== "undefined" && "PointerEvent" in window;
31115
- if (canvasElement) {
31116
- if (supportsPointerEvents) {
31117
- const pointerUpListener = (event) => {
31118
- if (event.pointerType === "mouse" && event.button !== 0) {
31119
- return;
31120
- }
31121
- processClickEvent(event);
31122
- };
31123
- canvasElement.addEventListener("pointerup", pointerUpListener, {
31124
- passive: true
31125
- });
31126
- registerDisposer(() => {
31127
- canvasElement == null ? void 0 : canvasElement.removeEventListener("pointerup", pointerUpListener);
31128
- });
31129
- const pointerMoveListener = (event) => {
31130
- if (!event.isPrimary) {
31131
- return;
31132
- }
31133
- if (event.pointerType === "touch") {
31134
- return;
31135
- }
31136
- processHoverEvent(event);
31137
- };
31138
- canvasElement.addEventListener("pointermove", pointerMoveListener, {
31139
- passive: true
31140
- });
31141
- registerDisposer(() => {
31142
- canvasElement == null ? void 0 : canvasElement.removeEventListener(
31143
- "pointermove",
31144
- pointerMoveListener
31145
- );
31146
- });
31147
- } else {
31148
- const clickListener = (event) => {
31149
- if (event.button !== 0) {
31150
- return;
31151
- }
31152
- processClickEvent(event);
31153
- };
31154
- canvasElement.addEventListener("click", clickListener, {
31155
- passive: true
31156
- });
31157
- registerDisposer(() => {
31158
- canvasElement == null ? void 0 : canvasElement.removeEventListener("click", clickListener);
31159
- });
31160
- const touchListener = (event) => {
31161
- processClickEvent(event);
31162
- };
31163
- canvasElement.addEventListener("touchend", touchListener, {
31164
- passive: true
31165
- });
31166
- registerDisposer(() => {
31167
- canvasElement == null ? void 0 : canvasElement.removeEventListener("touchend", touchListener);
31168
- });
31169
- const mouseMoveListener = (event) => {
31170
- processHoverEvent(event);
31171
- };
31172
- canvasElement.addEventListener("mousemove", mouseMoveListener, {
31173
- passive: true
31174
- });
31175
- registerDisposer(() => {
31176
- canvasElement == null ? void 0 : canvasElement.removeEventListener("mousemove", mouseMoveListener);
31177
- });
31178
- }
31179
- const visibilityTarget = (_a2 = canvasElement.ownerDocument) != null ? _a2 : typeof document !== "undefined" ? document : void 0;
31180
- if (visibilityTarget) {
31181
- const visibilityListener = () => updateVisibilityState();
31182
- visibilityTarget.addEventListener(
31183
- "visibilitychange",
31184
- visibilityListener
31185
- );
31186
- registerDisposer(() => {
31187
- visibilityTarget.removeEventListener(
31188
- "visibilitychange",
31189
- visibilityListener
31190
- );
31191
- });
31192
- updateVisibilityState();
31193
- }
31194
- }
31226
+ mouseEventsController.bindCanvas(canvasElement);
31227
+ canvasElement = mouseEventsController.canvasElement;
31195
31228
  spriteDrawProgram = createSpriteDrawProgram(glContext);
31196
31229
  scheduleRender();
31197
31230
  };
31198
31231
  const onRemove = () => {
31199
- inputListenerDisposers.forEach((dispose) => dispose());
31200
- inputListenerDisposers.length = 0;
31232
+ trackingController == null ? void 0 : trackingController.release();
31233
+ trackingController = void 0;
31234
+ mouseEventsController.release();
31201
31235
  canvasElement = void 0;
31202
31236
  hitTestController.clearAll();
31203
31237
  const glContext = gl;
@@ -31223,8 +31257,6 @@ const createSpriteLayer = (options) => {
31223
31257
  leaderLineRenderer = void 0;
31224
31258
  }
31225
31259
  }
31226
- eventListeners.forEach((set) => set.clear());
31227
- eventListeners.clear();
31228
31260
  gl = void 0;
31229
31261
  map = void 0;
31230
31262
  borderOutlineRenderer = void 0;
@@ -31261,9 +31293,7 @@ const createSpriteLayer = (options) => {
31261
31293
  sprites: spriteStateArray,
31262
31294
  timestamp: interpolationTimestamp2,
31263
31295
  frameContext: {
31264
- baseMetersPerPixel: resolvedScaling.metersPerPixel,
31265
- spriteMinPixel: resolvedScaling.spriteMinPixel,
31266
- spriteMaxPixel: resolvedScaling.spriteMaxPixel
31296
+ baseMetersPerPixel: resolvedScaling.metersPerPixel
31267
31297
  }
31268
31298
  } : null;
31269
31299
  let hasActiveInterpolation = false;
@@ -31302,16 +31332,12 @@ const createSpriteLayer = (options) => {
31302
31332
  const identityOffsetX = 0;
31303
31333
  const identityOffsetY = 0;
31304
31334
  const baseMetersPerPixel = resolvedScaling.metersPerPixel;
31305
- const spriteMinPixel = resolvedScaling.spriteMinPixel;
31306
- const spriteMaxPixel = resolvedScaling.spriteMaxPixel;
31307
31335
  const projectionHost = createProjectionHostForMap(mapInstance);
31308
31336
  try {
31309
31337
  const clipContext = projectionHost.getClipContext();
31310
31338
  if (!clipContext) {
31311
31339
  return;
31312
31340
  }
31313
- const zoom = projectionHost.getZoom();
31314
- const zoomScaleFactor = calculateZoomScaleFactor(zoom, resolvedScaling);
31315
31341
  glContext.enable(glContext.BLEND);
31316
31342
  glContext.blendFunc(glContext.SRC_ALPHA, glContext.ONE_MINUS_SRC_ALPHA);
31317
31343
  glContext.disable(glContext.DEPTH_TEST);
@@ -31356,12 +31382,9 @@ const createSpriteLayer = (options) => {
31356
31382
  resolvedScaling,
31357
31383
  clipContext,
31358
31384
  baseMetersPerPixel,
31359
- spriteMinPixel,
31360
- spriteMaxPixel,
31361
31385
  drawingBufferWidth,
31362
31386
  drawingBufferHeight,
31363
31387
  pixelRatio,
31364
- zoomScaleFactor,
31365
31388
  identityScaleX,
31366
31389
  identityScaleY,
31367
31390
  identityOffsetX,
@@ -31514,7 +31537,7 @@ const createSpriteLayer = (options) => {
31514
31537
  continue;
31515
31538
  }
31516
31539
  const effectiveAlpha = clampOpacity(
31517
- border.rgba[3] * entry.image.opacity.current
31540
+ border.rgba[3] * entry.image.finalOpacity.current
31518
31541
  );
31519
31542
  if (effectiveAlpha <= 0) {
31520
31543
  continue;
@@ -31711,6 +31734,7 @@ const createSpriteLayer = (options) => {
31711
31734
  scheduleRender();
31712
31735
  };
31713
31736
  const getAllImageIds = () => Array.from(images.keys());
31737
+ const getAllSpriteIds = () => Array.from(sprites.keys());
31714
31738
  const addSpriteInternal = (projectionHost, spriteId, init) => {
31715
31739
  var _a2, _b, _c, _d, _e, _f;
31716
31740
  if (sprites.get(spriteId)) {
@@ -31808,7 +31832,7 @@ const createSpriteLayer = (options) => {
31808
31832
  // Tags default to null to simplify downstream comparisons.
31809
31833
  tag: (_f = init.tag) != null ? _f : null,
31810
31834
  lastAutoRotationLocation: cloneSpriteLocation(currentLocation),
31811
- lastAutoRotationAngleDeg: 0,
31835
+ currentAutoRotateDeg: 0,
31812
31836
  autoRotationInvalidated: false,
31813
31837
  interpolationDirty: false,
31814
31838
  cachedMercator: initialMercator,
@@ -31949,7 +31973,8 @@ const createSpriteLayer = (options) => {
31949
31973
  subLayer,
31950
31974
  order,
31951
31975
  originReference,
31952
- !isLayerVisible() || sprite.location.invalidated === true
31976
+ !isLayerVisible() || sprite.location.invalidated === true,
31977
+ sprite.currentAutoRotateDeg
31953
31978
  );
31954
31979
  state.imageHandle = resolveImageHandle(state.imageId);
31955
31980
  if (state.originLocation !== void 0) {
@@ -31983,10 +32008,8 @@ const createSpriteLayer = (options) => {
31983
32008
  curMaybe = getRef(cur);
31984
32009
  }
31985
32010
  }
31986
- if (state.autoRotation) {
31987
- state.resolvedBaseRotateDeg = sprite.lastAutoRotationAngleDeg;
31988
- }
31989
- syncImageRotationChannel(state);
32011
+ const autoRotationDeg = resolveImageAutoRotationDeg(sprite, state);
32012
+ syncImageRotationChannel(state, autoRotationDeg);
31990
32013
  updateImageInterpolationDirtyState(sprite, state);
31991
32014
  setImageState(sprite, state);
31992
32015
  hitTestController.refreshSpriteHitTestBounds(projectionHost, sprite);
@@ -32023,11 +32046,12 @@ const createSpriteLayer = (options) => {
32023
32046
  }
32024
32047
  };
32025
32048
  const updateSpriteImageInternal = (projectionHost, sprite, subLayer, order, imageUpdate, resultOut) => {
32026
- var _a2;
32049
+ var _a2, _b, _c;
32027
32050
  const state = getImageState(sprite, subLayer, order);
32028
32051
  if (!state) return false;
32029
32052
  const mapCurrentlyVisible = isLayerVisible();
32030
32053
  const interpolationAllowed = interpolationCalculationEnabled && mapCurrentlyVisible;
32054
+ const resolveAutoRotationDeg2 = () => resolveImageAutoRotationDeg(sprite, state);
32031
32055
  if (imageUpdate.imageId !== void 0) {
32032
32056
  state.imageId = imageUpdate.imageId;
32033
32057
  state.imageHandle = resolveImageHandle(imageUpdate.imageId);
@@ -32036,12 +32060,12 @@ const createSpriteLayer = (options) => {
32036
32060
  state.mode = imageUpdate.mode;
32037
32061
  }
32038
32062
  const interpolationOptions = imageUpdate.interpolation;
32039
- const opacityInterpolationOption = interpolationOptions == null ? void 0 : interpolationOptions.opacity;
32063
+ const opacityInterpolationOption = interpolationOptions == null ? void 0 : interpolationOptions.finalOpacity;
32040
32064
  if (opacityInterpolationOption !== void 0) {
32041
- state.opacity.interpolation.options = opacityInterpolationOption === null ? null : cloneInterpolationOptions(opacityInterpolationOption);
32065
+ state.finalOpacity.interpolation.options = opacityInterpolationOption === null ? null : cloneInterpolationOptions(opacityInterpolationOption);
32042
32066
  }
32043
- const allowOpacityInterpolation = interpolationAllowed && !state.opacity.invalidated;
32044
- const resolvedOpacityInterpolationOption = allowOpacityInterpolation ? opacityInterpolationOption === void 0 ? (_a2 = state.opacity.interpolation.options) != null ? _a2 : null : opacityInterpolationOption : null;
32067
+ const allowOpacityInterpolation = interpolationAllowed && !state.finalOpacity.invalidated;
32068
+ const resolvedOpacityInterpolationOption = allowOpacityInterpolation ? opacityInterpolationOption === void 0 ? (_a2 = state.finalOpacity.interpolation.options) != null ? _a2 : null : opacityInterpolationOption : null;
32045
32069
  if (imageUpdate.opacity !== void 0) {
32046
32070
  applyOpacityUpdate(
32047
32071
  state,
@@ -32049,8 +32073,8 @@ const createSpriteLayer = (options) => {
32049
32073
  resolvedOpacityInterpolationOption,
32050
32074
  sprite.opacityMultiplier
32051
32075
  );
32052
- if (mapCurrentlyVisible && state.opacity.invalidated) {
32053
- state.opacity.invalidated = false;
32076
+ if (mapCurrentlyVisible && state.finalOpacity.invalidated) {
32077
+ state.finalOpacity.invalidated = false;
32054
32078
  }
32055
32079
  } else if (opacityInterpolationOption === null) {
32056
32080
  clearOpacityInterpolation(state);
@@ -32079,13 +32103,18 @@ const createSpriteLayer = (options) => {
32079
32103
  const allowOffsetMetersInterpolation = interpolationAllowed && !state.offset.offsetMeters.invalidated;
32080
32104
  const offsetDegInterpolationOption = allowOffsetDegInterpolation ? interpolationOptions == null ? void 0 : interpolationOptions.offsetDeg : null;
32081
32105
  const offsetMetersInterpolationOption = allowOffsetMetersInterpolation ? interpolationOptions == null ? void 0 : interpolationOptions.offsetMeters : null;
32082
- const allowRotateInterpolation = interpolationAllowed && !state.rotateDeg.invalidated;
32083
- const rotateInterpolationOption = allowRotateInterpolation ? interpolationOptions == null ? void 0 : interpolationOptions.rotateDeg : null;
32106
+ const allowRotateInterpolation = interpolationAllowed && !state.finalRotateDeg.invalidated;
32107
+ const rotateInterpolationOption = allowRotateInterpolation ? interpolationOptions == null ? void 0 : interpolationOptions.finalRotateDeg : null;
32084
32108
  let rotationOverride;
32085
32109
  let hasRotationOverride = false;
32086
- if (imageUpdate.offset !== void 0) {
32087
- const clonedOffset = cloneOffset(imageUpdate.offset);
32088
- applyOffsetUpdate(state, clonedOffset, {
32110
+ const hasOffsetMetersUpdate = imageUpdate.offsetMeters !== void 0;
32111
+ const hasOffsetDegUpdate = imageUpdate.offsetDeg !== void 0;
32112
+ if (hasOffsetMetersUpdate || hasOffsetDegUpdate) {
32113
+ const nextOffset = {
32114
+ offsetMeters: (_b = imageUpdate.offsetMeters) != null ? _b : state.offset.offsetMeters.current,
32115
+ offsetDeg: (_c = imageUpdate.offsetDeg) != null ? _c : state.offset.offsetDeg.current
32116
+ };
32117
+ applyOffsetUpdate(state, nextOffset, {
32089
32118
  deg: allowOffsetDegInterpolation ? offsetDegInterpolationOption : null,
32090
32119
  meters: allowOffsetMetersInterpolation ? offsetMetersInterpolationOption : null
32091
32120
  });
@@ -32107,11 +32136,11 @@ const createSpriteLayer = (options) => {
32107
32136
  }
32108
32137
  if (rotateInterpolationOption !== void 0) {
32109
32138
  if (rotateInterpolationOption === null) {
32110
- state.rotateDeg.interpolation.options = null;
32139
+ state.finalRotateDeg.interpolation.options = null;
32111
32140
  rotationOverride = null;
32112
32141
  } else {
32113
32142
  const cloned = cloneInterpolationOptions(rotateInterpolationOption);
32114
- state.rotateDeg.interpolation.options = cloned;
32143
+ state.finalRotateDeg.interpolation.options = cloned;
32115
32144
  rotationOverride = cloned;
32116
32145
  }
32117
32146
  hasRotationOverride = true;
@@ -32119,9 +32148,12 @@ const createSpriteLayer = (options) => {
32119
32148
  let requireRotationSync = false;
32120
32149
  if (imageUpdate.rotateDeg !== void 0) {
32121
32150
  const nextRotation = normalizeAngleDeg(imageUpdate.rotateDeg);
32122
- state.rotateDeg.from = state.rotateDeg.current;
32123
- state.rotateDeg.to = nextRotation;
32124
- state.rotationCommandDeg = nextRotation;
32151
+ const targetDisplayed = normalizeAngleDeg(
32152
+ resolveAutoRotationDeg2() + nextRotation
32153
+ );
32154
+ state.finalRotateDeg.from = state.finalRotateDeg.current;
32155
+ state.finalRotateDeg.to = targetDisplayed;
32156
+ state.rotateDeg = nextRotation;
32125
32157
  requireRotationSync = true;
32126
32158
  } else if (hasRotationOverride) {
32127
32159
  requireRotationSync = true;
@@ -32130,7 +32162,6 @@ const createSpriteLayer = (options) => {
32130
32162
  state.autoRotation = imageUpdate.autoRotation;
32131
32163
  if (imageUpdate.autoRotation) {
32132
32164
  if (!prevAutoRotation) {
32133
- state.resolvedBaseRotateDeg = sprite.lastAutoRotationAngleDeg;
32134
32165
  shouldReapplyAutoRotation = true;
32135
32166
  }
32136
32167
  } else if (prevAutoRotation) {
@@ -32144,24 +32175,24 @@ const createSpriteLayer = (options) => {
32144
32175
  }
32145
32176
  }
32146
32177
  if (shouldResetResolvedAngle) {
32147
- state.resolvedBaseRotateDeg = 0;
32148
32178
  requireRotationSync = true;
32149
32179
  }
32150
32180
  if (shouldReapplyAutoRotation) {
32151
32181
  const applied = applyAutoRotation(sprite, sprite.location.current, true);
32152
32182
  if (!applied && state.autoRotation) {
32153
- state.resolvedBaseRotateDeg = sprite.lastAutoRotationAngleDeg;
32154
32183
  requireRotationSync = true;
32155
32184
  }
32156
32185
  }
32157
32186
  if (requireRotationSync) {
32187
+ const autoRotationDeg = resolveAutoRotationDeg2();
32158
32188
  syncImageRotationChannel(
32159
32189
  state,
32190
+ autoRotationDeg,
32160
32191
  // When a rotation override has been computed, pass it along (null clears interpolation); otherwise leave undefined.
32161
32192
  interpolationAllowed ? hasRotationOverride ? rotationOverride != null ? rotationOverride : null : void 0 : null
32162
32193
  );
32163
- if (mapCurrentlyVisible && state.rotateDeg.invalidated) {
32164
- state.rotateDeg.invalidated = false;
32194
+ if (mapCurrentlyVisible && state.finalRotateDeg.invalidated) {
32195
+ state.finalRotateDeg.invalidated = false;
32165
32196
  }
32166
32197
  }
32167
32198
  updateImageInterpolationDirtyState(sprite, state);
@@ -32254,18 +32285,18 @@ const createSpriteLayer = (options) => {
32254
32285
  sprite.images.forEach((orderMap) => {
32255
32286
  orderMap.forEach((image) => {
32256
32287
  var _a3;
32257
- const baseOpacity = (_a3 = image.opacity.interpolation.baseValue) != null ? _a3 : image.opacity.current;
32288
+ const baseOpacity = (_a3 = image.finalOpacity.interpolation.baseValue) != null ? _a3 : image.finalOpacity.current;
32258
32289
  if (!(Number.isFinite(baseOpacity) && baseOpacity > 0)) {
32259
32290
  return;
32260
32291
  }
32261
- if (image.opacity.current > 0) {
32292
+ if (image.finalOpacity.current > 0) {
32262
32293
  return;
32263
32294
  }
32264
32295
  image.lodOpacity = 1;
32265
32296
  applyOpacityUpdate(
32266
32297
  image,
32267
32298
  baseOpacity,
32268
- image.opacity.interpolation.options,
32299
+ image.finalOpacity.interpolation.options,
32269
32300
  sprite.opacityMultiplier
32270
32301
  );
32271
32302
  });
@@ -32329,7 +32360,7 @@ const createSpriteLayer = (options) => {
32329
32360
  );
32330
32361
  let handledByInterpolation = false;
32331
32362
  if (effectiveOptions && effectiveOptions.durationMs > 0) {
32332
- const { state, requiresInterpolation } = createInterpolationState({
32363
+ const { state, requiresInterpolation } = createLocationInterpolationState({
32333
32364
  currentLocation: locationState.current,
32334
32365
  lastCommandLocation: locationInterpolation.lastCommandValue,
32335
32366
  nextCommandLocation: newCommandLocation,
@@ -32641,9 +32672,9 @@ const createSpriteLayer = (options) => {
32641
32672
  scheduleRender();
32642
32673
  }
32643
32674
  };
32644
- const setHitTestEnabled = (enabled) => {
32645
- const changed = hitTestController.setHitTestEnabled(enabled);
32646
- if (!changed || !enabled || !map) {
32675
+ const setHitTestDetection = (detect) => {
32676
+ const changed = hitTestController.setHitTestDetection(detect);
32677
+ if (!changed || !detect || !map) {
32647
32678
  return;
32648
32679
  }
32649
32680
  const projectionHost = createProjectionHostForMap(map);
@@ -32667,6 +32698,7 @@ const createSpriteLayer = (options) => {
32667
32698
  unregisterImage,
32668
32699
  unregisterAllImages,
32669
32700
  getAllImageIds,
32701
+ getAllSpriteIds,
32670
32702
  addSprite,
32671
32703
  addSprites,
32672
32704
  removeSprite,
@@ -32681,9 +32713,11 @@ const createSpriteLayer = (options) => {
32681
32713
  mutateSprites,
32682
32714
  updateForEach,
32683
32715
  setInterpolationCalculation,
32684
- setHitTestEnabled,
32685
- on: addEventListener2,
32686
- off: removeEventListener2
32716
+ setHitTestDetection,
32717
+ trackSprite,
32718
+ untrackSprite,
32719
+ on: mouseEventsController.addEventListener,
32720
+ off: mouseEventsController.removeEventListener
32687
32721
  };
32688
32722
  return spriteLayout;
32689
32723
  };