venue-js 1.0.0-1 → 1.0.0-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -142,7 +142,6 @@ var createPopulator = ({
142
142
  const populateAddress = (address) => Promise.resolve(address);
143
143
  const populateBuilding = (building) => Promise.resolve(building);
144
144
  const populateDetail = (detail) => Promise.resolve(detail);
145
- const populateFixture = (fixture) => Promise.resolve(fixture);
146
145
  const populateFootprint = (footprint) => Promise.resolve(footprint);
147
146
  const populateGeofence = (geofence) => Promise.resolve(geofence);
148
147
  const populateOpening = (opening) => Promise.resolve(opening);
@@ -198,6 +197,21 @@ var createPopulator = ({
198
197
  }
199
198
  };
200
199
  };
200
+ const populateFixture = async (fixture) => {
201
+ const level = await internalFindById(fixture.properties.level_id);
202
+ const venue = await internalFindById(fixture.properties.venue_id);
203
+ const anchor = await internalFindById(fixture.properties.anchor_id);
204
+ return {
205
+ ...fixture,
206
+ properties: {
207
+ ...fixture.properties,
208
+ anchor: anchor ? await populateAnchor(anchor) : null,
209
+ level: await populateLevel(level),
210
+ venue: await populateVenue(venue),
211
+ ordinal: level.properties.ordinal
212
+ }
213
+ };
214
+ };
201
215
  const populateKiosk = async (kiosk) => {
202
216
  const level = await internalFindById(kiosk.properties.level_id);
203
217
  const venue = await internalFindById(kiosk.properties.venue_id);
@@ -388,23 +402,33 @@ var getDataClient = (options) => {
388
402
  };
389
403
  const populator = createPopulator({ internalFindById, internalFilterByType });
390
404
  const registerObserver = (featureType, refetchInterval) => {
391
- let observer = observers.get(featureType);
392
- if (!observer) {
393
- const options2 = createDeliveryApiQueryOptions(featureType);
394
- observer = new QueryObserver(queryClient, {
395
- ...options2,
396
- refetchInterval
397
- });
398
- observers.set(featureType, observer);
399
- } else {
400
- console.error(
401
- `An observer for featureType ${featureType} already exists, fail to register new one`
402
- );
405
+ if (observers.has(featureType)) {
406
+ console.warn(`Observer for ${featureType} already exists`);
407
+ const record = observers.get(featureType);
408
+ return record.observer;
403
409
  }
410
+ const options2 = createDeliveryApiQueryOptions(featureType);
411
+ const observer = new QueryObserver(queryClient, {
412
+ ...options2,
413
+ refetchInterval
414
+ });
415
+ const unsubscribe = observer.subscribe(() => {
416
+ console.log(`[venue-js] Listening to ${featureType} changes (interval = ${refetchInterval}ms)`);
417
+ });
418
+ observers.set(featureType, { observer, unsubscribe });
404
419
  return observer;
405
420
  };
421
+ const destroyObserver = (featureType) => {
422
+ const record = observers.get(featureType);
423
+ if (!record) return;
424
+ record.unsubscribe();
425
+ observers.delete(featureType);
426
+ };
406
427
  const destroyObservers = () => {
407
- observers.forEach((o) => o.destroy());
428
+ observers.forEach(({ observer, unsubscribe }) => {
429
+ unsubscribe();
430
+ observer.destroy();
431
+ });
408
432
  observers.clear();
409
433
  };
410
434
  const createFilterByTypeQueryOptions = (featureType, params = {}, options2 = {}) => ({
@@ -444,6 +468,7 @@ var getDataClient = (options) => {
444
468
  projectId,
445
469
  queryClient,
446
470
  registerObserver,
471
+ destroyObserver,
447
472
  destroyObservers,
448
473
  createFilterByTypeQueryOptions,
449
474
  createFindByIdQueryOptions,
@@ -461,7 +486,8 @@ import {
461
486
  Extent,
462
487
  LineString as LineString3,
463
488
  animation,
464
- Marker as Marker2
489
+ Marker as Marker2,
490
+ Coordinate as Coordinate3
465
491
  } from "maptalks";
466
492
  import TWEEN2 from "@tweenjs/tween.js";
467
493
  import _6 from "lodash";
@@ -3114,50 +3140,16 @@ var createHighlighExtrudeObjectController = (obj, { color }) => {
3114
3140
  };
3115
3141
 
3116
3142
  // src/IndoorMap/camera/CameraManager.ts
3143
+ var ZOOM_OUT_LEVEL = 21;
3144
+ var ZOOM_IN_LEVEL = 24;
3117
3145
  var CameraManager = class {
3118
3146
  map;
3119
- // Use for various animation view
3120
- #defaultCenter;
3121
- #defaultZoom;
3122
- #defaultBearing = 0;
3123
- #defaultPitch = 45;
3124
- // Store current map zoomlevel
3125
- constructor(map, { defaultCenter, defaultZoom }) {
3147
+ constructor(map, options) {
3126
3148
  this.map = map;
3127
- this.#defaultCenter = defaultCenter;
3128
- if (defaultZoom) {
3129
- this.#defaultZoom = defaultZoom;
3130
- this.map.setZoom(defaultZoom);
3149
+ if (options?.defaultView) {
3150
+ this.setView(options?.defaultView);
3131
3151
  }
3132
3152
  }
3133
- set defaultBearing(value) {
3134
- this.#defaultBearing = value;
3135
- }
3136
- set defaultPitch(value) {
3137
- this.#defaultPitch = value;
3138
- }
3139
- set defaultCenter(value) {
3140
- this.#defaultCenter = value;
3141
- }
3142
- set defaultZoom(value) {
3143
- this.#defaultZoom = value;
3144
- }
3145
- get defaultCenter() {
3146
- return this.#defaultCenter;
3147
- }
3148
- get defaultZoom() {
3149
- return this.#defaultZoom;
3150
- }
3151
- get defaultBearing() {
3152
- return this.#defaultBearing;
3153
- }
3154
- get defaultPitch() {
3155
- return this.#defaultPitch;
3156
- }
3157
- getBearing = () => this.map.getBearing();
3158
- getPitch = () => this.map.getPitch();
3159
- getZoom = () => this.map.getZoom();
3160
- setBearing = (bearing) => this.map.setBearing(bearing);
3161
3153
  /** Private method */
3162
3154
  #animateflyTo(viewOptions = {}, options = {}, callbackOption = () => {
3163
3155
  }) {
@@ -3175,13 +3167,23 @@ var CameraManager = class {
3175
3167
  });
3176
3168
  }
3177
3169
  /** Public methods */
3170
+ getView = () => {
3171
+ return this.map.getView();
3172
+ };
3173
+ getZoom = () => {
3174
+ return this.map.getView().zoom;
3175
+ };
3176
+ setView = (value) => {
3177
+ this.map.setView(value);
3178
+ };
3178
3179
  flyTo = (center2, options = {}) => {
3180
+ const currentView = this.getView();
3179
3181
  const {
3180
- zoom = this.#defaultZoom,
3182
+ zoom = ZOOM_OUT_LEVEL,
3181
3183
  pitch = 60,
3182
3184
  duration = 600,
3183
3185
  easing = "out",
3184
- bearing = this.getBearing()
3186
+ bearing = currentView.bearing
3185
3187
  } = options;
3186
3188
  this.#animateflyTo(
3187
3189
  {
@@ -3195,7 +3197,7 @@ var CameraManager = class {
3195
3197
  };
3196
3198
  flyToAndZoomIn = (centerPoint, options = {}) => {
3197
3199
  const {
3198
- zoom = this.#defaultZoom + 3,
3200
+ zoom = ZOOM_IN_LEVEL,
3199
3201
  pitch = 60,
3200
3202
  duration = 600,
3201
3203
  easing = "out"
@@ -3375,7 +3377,7 @@ var DEFAULT_POLYGON_OPTION = {
3375
3377
  offset: 0,
3376
3378
  altitude: 0
3377
3379
  };
3378
- var HEIGHT_METER = 16;
3380
+ var HEIGHT_METER = 4;
3379
3381
  var getGeometryOption = (feature2, options) => {
3380
3382
  try {
3381
3383
  const option = options[feature2.feature_type];
@@ -3413,7 +3415,7 @@ var Element3DRenderer = class extends EventTarget {
3413
3415
  const hemi = new THREE2.HemisphereLight(16777215, 4473924, 0.4);
3414
3416
  scene.add(hemi);
3415
3417
  this.isReady = true;
3416
- _this.dispatchEvent(new CustomEvent("renderer:ready"));
3418
+ _this.dispatchEvent(new CustomEvent("threelayer:ready"));
3417
3419
  };
3418
3420
  this.lineMaterial = new THREE2.LineBasicMaterial({ color: "#000" });
3419
3421
  this.threeLayer.addTo(this.map);
@@ -3445,7 +3447,7 @@ var Element3DRenderer = class extends EventTarget {
3445
3447
  markerPath: [
3446
3448
  {
3447
3449
  path: "M21.75 0H0.25V21.5H8.35L11.3 24L14.2 21.5H21.75V0Z",
3448
- fill: "#044B7F"
3450
+ fill: "#ff0000"
3449
3451
  }
3450
3452
  ],
3451
3453
  markerPathWidth: 24,
@@ -3474,33 +3476,55 @@ var Element3DRenderer = class extends EventTarget {
3474
3476
  }
3475
3477
  createGeometry = (feature2) => {
3476
3478
  const options = getGeometryOption(feature2, this.options);
3477
- const offset = options.offset ?? 0;
3479
+ const offset = options?.offset ?? 0;
3480
+ const createPolygon = (geometry, feature3) => {
3481
+ const [outerRing, ...innerRings] = geometry.coordinates;
3482
+ const offsetFeature = offset !== 0 ? turfBuffer2(geometry, offset, { units: "meters" }) : feature3;
3483
+ const color = options.color ?? feature3.properties.style.polygonFill ?? "#ffffff";
3484
+ if (color === "transparent") return;
3485
+ const material = this.getOrCreateMaterialByColor(color);
3486
+ const altitude = feature3.properties.ordinal * HEIGHT_METER;
3487
+ const bottomHeight = options.bottomHeight ?? 0;
3488
+ const polygon = this.threeLayer.toExtrudePolygon(
3489
+ offsetFeature,
3490
+ { asynchronous: true, ...options, altitude },
3491
+ material
3492
+ );
3493
+ const topLineStrings = [
3494
+ new maptalks5.LineString(outerRing),
3495
+ ...innerRings.map((innerRing) => new maptalks5.LineString(innerRing))
3496
+ ];
3497
+ const topLines = this.threeLayer.toLines(
3498
+ topLineStrings,
3499
+ { altitude: altitude + options.height + 1e-3, bottomHeight, interactive: false },
3500
+ this.lineMaterial
3501
+ );
3502
+ const bottomLineStrings = [
3503
+ new maptalks5.LineString(outerRing),
3504
+ ...innerRings.map((innerRing) => new maptalks5.LineString(innerRing))
3505
+ ];
3506
+ const bottomLines = this.threeLayer.toLines(
3507
+ bottomLineStrings,
3508
+ { altitude, bottomHeight, interactive: false },
3509
+ this.lineMaterial
3510
+ );
3511
+ return [polygon, topLines, bottomLines];
3512
+ };
3478
3513
  try {
3479
3514
  switch (feature2.geometry.type) {
3480
- case "Polygon": {
3481
- const offsetFeature = offset !== 0 ? turfBuffer2(feature2.geometry, offset, { units: "meters" }) : feature2;
3482
- const color = options.color ?? feature2.properties.style.polygonFill ?? "#ffffff";
3483
- if (color === "transparent") return;
3484
- const material = this.getOrCreateMaterialByColor(color);
3485
- const altitude = feature2.properties.ordinal * HEIGHT_METER;
3486
- const polygon = this.threeLayer.toExtrudePolygon(
3487
- offsetFeature,
3488
- { asynchronous: true, ...options, altitude },
3489
- material
3490
- );
3491
- const lineString2 = new maptalks5.LineString(
3492
- feature2.geometry.coordinates[0]
3493
- );
3494
- const line = this.threeLayer.toLine(
3495
- lineString2,
3496
- { altitude: altitude + options.height + 1e-3, interactive: false },
3497
- this.lineMaterial
3498
- );
3499
- this.threeLayer.addMesh([polygon, line]);
3500
- return [polygon, line];
3501
- }
3502
3515
  case "MultiPolygon": {
3503
- throw new Error("Dost not support MultiPolygon");
3516
+ const { coordinates } = feature2.geometry;
3517
+ const multiMeshes = coordinates.flatMap((polygonCoordinates) => {
3518
+ const meshes = createPolygon({ type: "Polygon", coordinates: polygonCoordinates }, feature2);
3519
+ this.threeLayer.addMesh(meshes);
3520
+ return meshes;
3521
+ });
3522
+ return multiMeshes;
3523
+ }
3524
+ case "Polygon": {
3525
+ const meshes = createPolygon(feature2.geometry, feature2);
3526
+ this.threeLayer.addMesh(meshes);
3527
+ return meshes;
3504
3528
  }
3505
3529
  }
3506
3530
  } catch (err) {
@@ -3510,7 +3534,7 @@ var Element3DRenderer = class extends EventTarget {
3510
3534
  createMarker = (coordinates, ordinal, label) => {
3511
3535
  const options = {
3512
3536
  scale: 0.05,
3513
- altitude: ordinal * HEIGHT_METER + 4,
3537
+ altitude: ordinal * HEIGHT_METER,
3514
3538
  // highlight: highlightOptions,
3515
3539
  interactive: true
3516
3540
  };
@@ -3662,7 +3686,8 @@ var Element2DRenderer = class extends EventTarget {
3662
3686
  };
3663
3687
 
3664
3688
  // src/IndoorMap/renderer/RendererManager.ts
3665
- var RendererManager = class {
3689
+ var RendererManager = class extends EventTarget {
3690
+ map;
3666
3691
  options;
3667
3692
  // Client for fetching data
3668
3693
  #dataClient;
@@ -3671,6 +3696,8 @@ var RendererManager = class {
3671
3696
  elementsMap;
3672
3697
  elementsByOrdinal;
3673
3698
  constructor(map, options) {
3699
+ super();
3700
+ this.map = map;
3674
3701
  this.options = options;
3675
3702
  this.elementsMap = /* @__PURE__ */ new Map();
3676
3703
  this.elementsByOrdinal = /* @__PURE__ */ new Map();
@@ -3681,17 +3708,31 @@ var RendererManager = class {
3681
3708
  if (this.elementRenderer.isReady) {
3682
3709
  this.#createElements();
3683
3710
  } else {
3684
- this.elementRenderer.addEventListener("renderer:ready", (e) => {
3711
+ this.elementRenderer.addEventListener("threelayer:ready", (e) => {
3712
+ this.dispatchEvent(new CustomEvent("renderermanager:ready"));
3685
3713
  this.#createElements();
3686
3714
  });
3687
3715
  }
3688
3716
  }
3717
+ getElementsByOrdinal = (ordinal) => {
3718
+ const exist = this.elementsByOrdinal.get(ordinal);
3719
+ if (!exist) this.elementsByOrdinal.set(ordinal, []);
3720
+ return this.elementsByOrdinal.get(ordinal);
3721
+ };
3689
3722
  async #createElements() {
3690
3723
  const levels = await this.#dataClient.filterByType("level", {
3691
3724
  populate: true
3692
3725
  });
3693
- levels.forEach((level) => {
3694
- this.elementsByOrdinal.set(level.properties.ordinal, []);
3726
+ const fixtures = await this.#dataClient.filterByType("fixture", { populate: true });
3727
+ fixtures.forEach((fixture) => {
3728
+ const element = this.elementRenderer.createGeometry(fixture);
3729
+ if (element) {
3730
+ const _elements = Array.isArray(element) ? element : [element];
3731
+ _elements.forEach((el) => {
3732
+ this.elementsMap.set(fixture.id, el);
3733
+ this.getElementsByOrdinal(fixture.properties.level.properties.ordinal).push(el);
3734
+ });
3735
+ }
3695
3736
  });
3696
3737
  const units = await this.#dataClient.filterByType("unit", {
3697
3738
  populate: true
@@ -3704,7 +3745,7 @@ var RendererManager = class {
3704
3745
  const _elements = Array.isArray(element) ? element : [element];
3705
3746
  _elements.forEach((el) => {
3706
3747
  this.elementsMap.set(unit.id, el);
3707
- this.elementsByOrdinal.get(unit.properties.level.properties.ordinal).push(el);
3748
+ this.getElementsByOrdinal(unit.properties.level.properties.ordinal).push(el);
3708
3749
  });
3709
3750
  }
3710
3751
  });
@@ -3717,10 +3758,11 @@ var RendererManager = class {
3717
3758
  const _elements = Array.isArray(element) ? element : [element];
3718
3759
  _elements.forEach((el) => {
3719
3760
  this.elementsMap.set(kiosk.id, el);
3720
- this.elementsByOrdinal.get(kiosk.properties.level.properties.ordinal).push(el);
3761
+ this.getElementsByOrdinal(kiosk.properties.level.properties.ordinal).push(el);
3721
3762
  });
3722
3763
  }
3723
3764
  });
3765
+ this.dispatchEvent(new CustomEvent("renderermanager:elements_created"));
3724
3766
  }
3725
3767
  changeLevelByOrdinal(targetOrdinal) {
3726
3768
  for (const [ordinal, elements] of this.elementsByOrdinal) {
@@ -3739,19 +3781,19 @@ var RendererManager = class {
3739
3781
  createMarker(coordinate, ordinal, label) {
3740
3782
  const marker = this.elementRenderer.createMarker(coordinate, ordinal, label);
3741
3783
  this.elementsMap.set(label, marker);
3742
- this.elementsByOrdinal.get(ordinal).push(marker);
3784
+ this.getElementsByOrdinal(ordinal).push(marker);
3743
3785
  }
3744
3786
  };
3745
3787
 
3746
3788
  // src/IndoorMap/IndoorMap.ts
3789
+ var INITIAL_CENTER = [100.5017051, 13.7572619];
3790
+ var INITIAL_ZOOM = 18.5;
3791
+ var CLICK_TOLERANCE = 20;
3747
3792
  var defaultOptions = {
3748
- center: [100.5017051, 13.7572619],
3749
- defaultZoom: 18.5,
3750
3793
  pixelRatio: 1,
3751
3794
  locale: DEFAULT_LOCALE
3752
3795
  };
3753
- var CLICK_TOLERANCE = 20;
3754
- var IndoorMap = class {
3796
+ var IndoorMap = class extends EventTarget {
3755
3797
  //TODO: refac functions; let them do only 1 thing in a function
3756
3798
  /** Note: "#" means private variables */
3757
3799
  #styler = null;
@@ -3793,7 +3835,7 @@ var IndoorMap = class {
3793
3835
  #animationsToRun = [];
3794
3836
  map = null;
3795
3837
  #dataClient;
3796
- cameraManager;
3838
+ camera;
3797
3839
  rendererManager;
3798
3840
  showVenueObject = false;
3799
3841
  threeLayer = null;
@@ -3802,9 +3844,8 @@ var IndoorMap = class {
3802
3844
  onMapLoading = () => {
3803
3845
  };
3804
3846
  constructor(elementId, options) {
3847
+ super();
3805
3848
  const {
3806
- center: center2,
3807
- defaultZoom,
3808
3849
  onMapReady,
3809
3850
  onMapLoading,
3810
3851
  pixelRatio,
@@ -3812,13 +3853,13 @@ var IndoorMap = class {
3812
3853
  } = _6.merge({}, defaultOptions, options);
3813
3854
  this.map = new Map2(elementId, {
3814
3855
  attribution: false,
3815
- center: center2,
3816
- zoom: defaultZoom,
3856
+ center: INITIAL_CENTER,
3857
+ zoom: INITIAL_ZOOM,
3817
3858
  clickTimeThreshold: 600,
3818
3859
  baseLayer: new TileLayer("base", {
3819
3860
  urlTemplate: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
3820
3861
  subdomains: ["a", "b", "c", "d"],
3821
- opacity: 0.6,
3862
+ opacity: 1,
3822
3863
  attribution: "",
3823
3864
  hitDetect: false,
3824
3865
  decodeImageInWorker: true,
@@ -3826,11 +3867,14 @@ var IndoorMap = class {
3826
3867
  }),
3827
3868
  layers: []
3828
3869
  });
3829
- this.cameraManager = new CameraManager(this.map, {
3830
- defaultCenter: center2,
3831
- defaultZoom
3832
- });
3833
3870
  this.rendererManager = new RendererManager(this.map, options.renderer);
3871
+ this.rendererManager.addEventListener("renderermanager:ready", (e) => {
3872
+ this.dispatchEvent(new CustomEvent("renderer:ready"));
3873
+ });
3874
+ this.rendererManager.addEventListener("renderermanager:elements_created", (e) => {
3875
+ this.dispatchEvent(new CustomEvent("renderer:elements_created"));
3876
+ });
3877
+ this.camera = new CameraManager(this.map);
3834
3878
  this.locale = locale;
3835
3879
  this.pixelRatio = pixelRatio;
3836
3880
  this.onMapReady = onMapReady;
@@ -3841,7 +3885,13 @@ var IndoorMap = class {
3841
3885
  }
3842
3886
  set dataClient(value) {
3843
3887
  this.#dataClient = value;
3844
- if (this.rendererManager) this.rendererManager.dataClient = this.#dataClient;
3888
+ this.#dataClient.filterByType("venue").then((venues) => {
3889
+ const venueCenters = turfCenter2(featureCollection(venues));
3890
+ const [x, y] = venueCenters.geometry.coordinates;
3891
+ const center2 = new Coordinate3(x, y);
3892
+ this.camera.setView({ center: center2, pitch: 60, zoom: 19 });
3893
+ });
3894
+ this.rendererManager.dataClient = this.#dataClient;
3845
3895
  }
3846
3896
  /**
3847
3897
  * Events
@@ -3870,30 +3920,6 @@ var IndoorMap = class {
3870
3920
  /**
3871
3921
  * Getters & Setters
3872
3922
  */
3873
- set defaultBearing(value) {
3874
- this.cameraManager.defaultBearing = value;
3875
- }
3876
- set defaultPitch(value) {
3877
- this.cameraManager.defaultPitch = value;
3878
- }
3879
- set defaultCenter(value) {
3880
- this.cameraManager.defaultCenter = value;
3881
- }
3882
- set defaultZoom(value) {
3883
- this.cameraManager.defaultZoom = value;
3884
- }
3885
- get defaultBearing() {
3886
- return this.cameraManager.defaultBearing;
3887
- }
3888
- get defaultPitch() {
3889
- return this.cameraManager.defaultPitch;
3890
- }
3891
- get defaultCenter() {
3892
- return this.cameraManager.defaultCenter;
3893
- }
3894
- get defaultZoom() {
3895
- return this.cameraManager.defaultZoom;
3896
- }
3897
3923
  get elementsLoaded() {
3898
3924
  return this.#elementsLoaded;
3899
3925
  }
@@ -4325,7 +4351,7 @@ var IndoorMap = class {
4325
4351
  const {
4326
4352
  geometry: { coordinates }
4327
4353
  } = turfCenter2(feature2);
4328
- this.cameraManager.flyToAndZoomIn(coordinates, { pitch: 45 });
4354
+ this.camera.flyToAndZoomIn(coordinates, { pitch: 45 });
4329
4355
  });
4330
4356
  object3ds.push(object);
4331
4357
  this.#objects.push(object);
@@ -4476,7 +4502,7 @@ var IndoorMap = class {
4476
4502
  return result;
4477
4503
  };
4478
4504
  flyTo = (center2, options) => {
4479
- this.cameraManager.flyTo(center2, options);
4505
+ this.camera.flyTo(center2, options);
4480
4506
  };
4481
4507
  getLineStringBearing = (feature2) => {
4482
4508
  const { geometry } = feature2;
@@ -5028,7 +5054,7 @@ var IndoorMap = class {
5028
5054
  this.threeLayer.redraw();
5029
5055
  }
5030
5056
  if (this.threeLayer) {
5031
- const objectOpacity = _6.clamp(38 - 2 * this.cameraManager.getZoom(), 0, 1);
5057
+ const objectOpacity = _6.clamp(38 - 2 * this.camera.getZoom(), 0, 1);
5032
5058
  this.#objects.forEach((object) => {
5033
5059
  object.getObject3d().traverse((child) => {
5034
5060
  if (child.isMesh) child.material.opacity = objectOpacity;
@@ -5039,7 +5065,7 @@ var IndoorMap = class {
5039
5065
  if (this.#billboardObjects) {
5040
5066
  this.#billboardObjects.forEach((object) => {
5041
5067
  const objectScale = _6.clamp(
5042
- 20 - 1 * this.cameraManager.getZoom(),
5068
+ 20 - 1 * this.camera.getZoom(),
5043
5069
  1,
5044
5070
  1.05
5045
5071
  );