@expofp/renderer 1.3.2 → 1.4.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 (3) hide show
  1. package/dist/index.d.ts +38 -407
  2. package/dist/index.js +2618 -68
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,26 +1,21 @@
1
- import { Camera } from 'three';
2
1
  import { default as default_2 } from 'stats-gl';
3
- import { default as default_3 } from 'camera-controls';
4
- import { EventManager } from 'mjolnir.js';
5
- import { Intersection } from 'three';
6
- import { Object3D } from 'three';
7
- import { Object3DEventMap } from 'three';
8
- import { PerspectiveCamera } from 'three';
9
- import { Scene } from 'three';
10
2
  import { Vector2 } from 'three';
11
3
  import { Vector2Like } from 'three';
12
4
  import { Vector2Tuple } from 'three';
13
5
  import { WebGLRenderer } from 'three';
14
6
 
15
- /** Camera controller. Manages the camera, it's controls and smooth updates. */
16
- declare class CameraController extends default_3 {
17
- private renderer;
18
- /**
19
- * @param camera {@link PerspectiveCamera} instance
20
- * @param renderer {@link Renderer} instance
21
- */
22
- constructor(camera: PerspectiveCamera, renderer: Renderer);
23
- update(delta: number): boolean;
7
+ /** Camera state returned by {@link ControlsAPI.getCameraState}. */
8
+ export declare interface CameraState {
9
+ /** Camera target position in SVG coordinates */
10
+ center: Vector2Like;
11
+ /** Current zoom factor */
12
+ zoom: number;
13
+ /** Roll angle in degrees */
14
+ roll: number;
15
+ /** Pitch angle in degrees */
16
+ pitch: number;
17
+ /** Pixel to SVG scale factor */
18
+ ptScale: number;
24
19
  }
25
20
 
26
21
  export declare type ColorInput = string | number;
@@ -39,7 +34,10 @@ export declare interface ConfigureOptions {
39
34
 
40
35
  /** Controls system public API. */
41
36
  export declare interface ControlsAPI {
42
- /** Gesture handlers for camera controls. */
37
+ /**
38
+ * Gesture handlers for camera controls.
39
+ * @inlineType Handlers
40
+ */
43
41
  handlers: Readonly<Handlers>;
44
42
  /**
45
43
  * Zooms the camera by the given factor.
@@ -118,6 +116,17 @@ export declare interface ControlsAPI {
118
116
  * @param options Partial configuration object with time values in seconds
119
117
  */
120
118
  configure(options: Partial<ConfigureOptions>): void;
119
+ /**
120
+ * Sets the camera bounds to restrict camera movement.
121
+ * Note: This method must be called after the viewport is initialized by `renderer.start()`.
122
+ * @param rect Rectangle in SVG coordinates defining the camera boundary or `undefined` to remove the boundary
123
+ */
124
+ setCameraBounds(rect?: Rect): void;
125
+ /**
126
+ * Gets the current camera state.
127
+ * @returns Camera state object with center, zoom, roll, pitch, and ptScale
128
+ */
129
+ getCameraState(): CameraState;
121
130
  }
122
131
 
123
132
  /**
@@ -157,156 +166,6 @@ export declare interface EventsAPI {
157
166
  clear(): void;
158
167
  }
159
168
 
160
- /**
161
- * System for managing engine-wide events
162
- */
163
- declare class EventSystem implements EventsAPI {
164
- private handlers;
165
- /**
166
- * Add an event listener for a specific event
167
- * @param event - The event to listen for
168
- * @param handler - The handler to call when the event is emitted
169
- */
170
- addEventListener<E extends keyof EngineEvents>(event: E, handler: EventHandler<EngineEvents[E]>): void;
171
- /**
172
- * Remove an event listener for a specific event
173
- * @param event - The event to remove the listener for
174
- * @param handler - The handler to remove
175
- */
176
- removeEventListener<E extends keyof EngineEvents>(event: E, handler: EventHandler<EngineEvents[E]>): void;
177
- /**
178
- * Check if there are any listeners for a specific event
179
- * @param event - The event to check
180
- * @returns true if there are listeners, false otherwise
181
- */
182
- hasListeners<E extends keyof EngineEvents>(event: E): boolean;
183
- /**
184
- * Emit an event with a specific payload
185
- * @param event - The event to emit
186
- * @param args - The payload to emit
187
- */
188
- emit<E extends keyof EngineEvents>(event: E, ...args: EngineEvents[E] extends void ? [] : [EngineEvents[E]]): void;
189
- /**
190
- * Clear all event listeners
191
- */
192
- clear(): void;
193
- }
194
-
195
- /**
196
- * Abstract base class for all interaction handlers.
197
- * Provides common lifecycle management and access to camera controller, DOM element, and event manager.
198
- * Subclasses can:
199
- * - Configure camera-controls in onEnable/onDisable (e.g., set mouseButtons, limits)
200
- * - Subscribe to DOM events or Mjolnir gestures in onEnable/onDisable
201
- * - Or do both
202
- * @template T Handler-specific options type (undefined if no options)
203
- * @example
204
- * ```typescript
205
- * // Simple handler that just configures camera-controls
206
- * class PanHandler extends Handler {
207
- * protected onEnable(): void {
208
- * this.controller.mouseButtons.left = CameraController.ACTION.TRUCK;
209
- * }
210
- *
211
- * protected onDisable(): void {
212
- * this.controller.mouseButtons.left = CameraController.ACTION.NONE;
213
- * }
214
- *
215
- * reset(enableTransition = true): Promise<void> {
216
- * // No custom state to reset
217
- * }
218
- * }
219
- *
220
- * // Handler with custom gesture recognition
221
- * class RotateHandler extends Handler {
222
- * private rotating = false;
223
- *
224
- * protected onEnable(): void {
225
- * this.controller.touches.two = CameraController.ACTION.NONE; // Disable built-in
226
- * this.eventManager.on('rotate', this.onRotate);
227
- * this.domElement.addEventListener('pointerdown', this.onPointerDown);
228
- * }
229
- *
230
- * protected onDisable(): void {
231
- * this.eventManager.off('rotate', this.onRotate);
232
- * this.domElement.removeEventListener('pointerdown', this.onPointerDown);
233
- * this.rotating = false;
234
- * }
235
- *
236
- * reset(enableTransition = true): Promise<void> {
237
- * this.rotating = false;
238
- * }
239
- * }
240
- * ```
241
- */
242
- declare abstract class Handler<T = undefined> implements HandlerAPI<T> {
243
- protected viewportSystem: ViewportSystem;
244
- protected domElement: HTMLElement;
245
- protected eventManager: EventManager;
246
- /** Whether this handler is enabled */
247
- protected enabled: boolean;
248
- /** The camera-controls instance for camera manipulation */
249
- protected controller: CameraController;
250
- /**
251
- * @param viewportSystem The viewport system instance
252
- * @param domElement The DOM element to attach event listeners to
253
- * @param eventManager Shared Mjolnir EventManager for gesture recognition
254
- */
255
- constructor(viewportSystem: ViewportSystem, domElement: HTMLElement, eventManager: EventManager);
256
- /**
257
- * Per-frame update for this handler.
258
- * Called every frame in the render loop.
259
- * Override if handler needs per-frame logic (e.g., smooth interpolation).
260
- * @param delta Time elapsed since last frame in seconds
261
- * @returns true if the handler made changes that require re-rendering
262
- */
263
- update(delta: number): boolean;
264
- /**
265
- * Reset this handler to its initial state.
266
- * @param enableTransition Whether to animate the transition (default: true)
267
- * @returns Promise that resolves when the reset is complete
268
- */
269
- abstract reset(enableTransition?: boolean): Promise<void>;
270
- /**
271
- * Configure this handler with handler-specific options.
272
- * Does NOT handle enabled state - use enable()/disable() for that.
273
- * Subclasses should override to handle their specific options
274
- * @param options Partial options to update (handler-specific, not including enabled flag)
275
- */
276
- configure(options: T extends undefined ? never : Partial<T>): void;
277
- /**
278
- * Enable this handler.
279
- * Calls onEnable() hook for subclass-specific enabling logic
280
- */
281
- enable(): void;
282
- /**
283
- * Disable this handler.
284
- * Resets to initial state without transition, then calls onDisable() hook for subclass-specific disabling logic
285
- */
286
- disable(): void;
287
- /**
288
- * Check if this handler is currently enabled
289
- * @returns true if enabled, false otherwise
290
- */
291
- isEnabled(): boolean;
292
- /**
293
- * Hook called when the handler is enabled.
294
- * Subclasses override this to:
295
- * - Configure camera-controls (set mouseButtons, touches, limits, etc.)
296
- * - Subscribe to DOM events (addEventListener)
297
- * - Subscribe to Mjolnir gestures (eventManager.on)
298
- */
299
- protected abstract onEnable(): void;
300
- /**
301
- * Hook called when the handler is disabled.
302
- * Subclasses override this to:
303
- * - Reset camera-controls configuration
304
- * - Unsubscribe from DOM events (removeEventListener)
305
- * - Unsubscribe from Mjolnir gestures (eventManager.off)
306
- */
307
- protected abstract onDisable(): void;
308
- }
309
-
310
169
  /**
311
170
  * Public API interface exposed through renderer.controls.handlers.
312
171
  * Each handler implements this interface to provide consistent enable/disable/configure functionality.
@@ -341,17 +200,17 @@ export declare interface HandlerAPI<T = undefined> {
341
200
  }
342
201
 
343
202
  /**
344
- * Gesture handlers - all fields are readonly to prevent reassignment
203
+ * Gesture handlers
345
204
  */
346
205
  declare interface Handlers {
347
206
  /** Pan handler */
348
- pan: PanHandler;
207
+ pan: HandlerAPI;
349
208
  /** Zoom handler */
350
- zoom: ZoomHandler;
209
+ zoom: HandlerAPI;
351
210
  /** Roll handler */
352
- roll: RollHandler;
211
+ roll: HandlerAPI<RollHandlerOptions>;
353
212
  /** Pitch handler */
354
- pitch: PitchHandler;
213
+ pitch: HandlerAPI<PitchHandlerOptions>;
355
214
  }
356
215
 
357
216
  /** Image definition */
@@ -425,75 +284,10 @@ export declare interface MouseEventData {
425
284
  defs: RenderableDef[];
426
285
  }
427
286
 
428
- /**
429
- * Pan handler - wraps camera-controls TRUCK action.
430
- * Handles both mouse drag (left-click) and single-finger touch pan.
431
- * No custom event listeners needed - camera-controls handles everything
432
- */
433
- declare class PanHandler extends Handler {
434
- private inertia;
435
- reset(enableTransition?: boolean): Promise<void>;
436
- update(delta: number): boolean;
437
- /**
438
- * Enable pan gestures.
439
- * Configures camera-controls to handle left-click drag and single-touch drag
440
- */
441
- protected onEnable(): void;
442
- /**
443
- * Disable pan gestures.
444
- * Removes pan actions from camera-controls
445
- */
446
- protected onDisable(): void;
447
- }
448
-
449
- /**
450
- * Pitch handler - controls camera polar angle (vertical pitch).
451
- * Configures camera-controls polar angle limits.
452
- * No gesture recognition yet - only sets angle constraints.
453
- */
454
- declare class PitchHandler extends Handler<PitchHandlerOptions> {
455
- private minPitch;
456
- private maxPitch;
457
- private isValid?;
458
- private firstMove?;
459
- private lastPoints?;
460
- private prevTwoFingerAction?;
461
- /**
462
- * @param viewportSystem {@link ViewportSystem} instance
463
- * @param domElement {@link HTMLElement} instance
464
- * @param eventManager {@link EventManager} instance
465
- */
466
- constructor(viewportSystem: ViewportSystem, domElement: HTMLElement, eventManager: EventManager);
467
- reset(enableTransition?: boolean): Promise<void>;
468
- /**
469
- * Configure pitch handler options
470
- * @param options Partial options to update
471
- */
472
- configure(options: Partial<PitchHandlerOptions>): void;
473
- /**
474
- * Enable pitch.
475
- * Configures camera-controls to allow polar angle changes within configured range
476
- */
477
- protected onEnable(): void;
478
- /**
479
- * Disable pitch.
480
- */
481
- protected onDisable(): void;
482
- /**
483
- * Update controller polar angles based on current configuration
484
- */
485
- private updatePolarAngles;
486
- private onPitchStart;
487
- private onPitchEnd;
488
- private onPitch;
489
- private gestureBeginsVertically;
490
- private isVertical;
491
- }
492
-
493
287
  /**
494
288
  * Configuration options for PitchHandler
495
289
  */
496
- declare interface PitchHandlerOptions {
290
+ export declare interface PitchHandlerOptions {
497
291
  /**
498
292
  * Minimum pitch angle in degrees (0 = looking straight down at the map)
499
293
  * @default 0
@@ -675,83 +469,18 @@ export declare interface RendererOptions {
675
469
  ui?: Partial<UI>;
676
470
  }
677
471
 
678
- /** Options for the {@link ControlsAPI.resetCamera} method. */
472
+ /**
473
+ * Options for the {@link ControlsAPI.resetCamera} method.
474
+ * @inline
475
+ */
679
476
  export declare type ResetCameraOptions = {
680
477
  [Property in keyof Handlers]?: boolean;
681
478
  };
682
479
 
683
- /**
684
- * Roll handler - implements custom two-finger rotation around arbitrary pivot point.
685
- * Handles mouse drag (right-click) via camera-controls and custom touch rotation.
686
- * Uses Mapbox-style threshold to prevent accidental rotations.
687
- */
688
- declare class RollHandler extends Handler<RollHandlerOptions> {
689
- private isRolling;
690
- private rotationThreshold;
691
- private startVector?;
692
- private vector?;
693
- private minDiameter;
694
- private prevAngle;
695
- private pivotWorld;
696
- private targetWorld;
697
- private cameraPosition;
698
- private cameraForward;
699
- private rotationMatrix;
700
- /**
701
- * Get bearing angle between current camera orientation and true north (in radians).
702
- * Angle is in range [0, 2π), going clockwise from north.
703
- */
704
- get bearing(): number;
705
- reset(enableTransition?: boolean): Promise<void>;
706
- /**
707
- * Configure roll handler options
708
- * @param options Partial options to update
709
- */
710
- configure(options: Partial<RollHandlerOptions>): void;
711
- /**
712
- * Enable roll gestures.
713
- * Configures camera-controls to allow any azimuth angle and two-finger touch rotate
714
- */
715
- protected onEnable(): void;
716
- /**
717
- * Disable roll gestures.
718
- */
719
- protected onDisable(): void;
720
- private onRotateStart;
721
- private onRotateEnd;
722
- private onRotate;
723
- private setPivot;
724
- /**
725
- * Check if rotation is below threshold (Mapbox-style).
726
- * The threshold before a rotation actually happens is configured in
727
- * pixels along the circumference of the circle formed by the two fingers.
728
- * This makes the threshold in degrees larger when the fingers are close
729
- * together and smaller when the fingers are far apart.
730
- * Uses the smallest diameter from the whole gesture to reduce sensitivity
731
- * when pinching in and out.
732
- * @param vector Current vector between fingers
733
- * @returns true if below threshold, false otherwise
734
- */
735
- private isBelowThreshold;
736
- /**
737
- * Get signed angle between two vectors in degrees (Mapbox pattern)
738
- * @param a First vector
739
- * @param b Second vector
740
- * @returns Angle difference in degrees
741
- */
742
- private getBearingDelta;
743
- /**
744
- * Normalize angle to be between -π and π
745
- * @param angle Angle in radians
746
- * @returns Normalized angle in radians
747
- */
748
- private normalizeAngle;
749
- }
750
-
751
480
  /**
752
481
  * Configuration options for RollHandler
753
482
  */
754
- declare interface RollHandlerOptions {
483
+ export declare interface RollHandlerOptions {
755
484
  /**
756
485
  * Rotation threshold in pixels along circumference of touch circle (Mapbox-style).
757
486
  * Higher values require more movement before rotation starts.
@@ -768,8 +497,6 @@ export declare interface SceneDef {
768
497
  background?: ColorInput;
769
498
  /** SVG viewbox */
770
499
  viewbox: Rect;
771
- /** Scene's rectangle bounds in SVG coordinates. Essentially, the size of a largest layer */
772
- bounds?: Rect;
773
500
  /** Textures memory limit in megabytes */
774
501
  memoryLimit?: number;
775
502
  }
@@ -792,8 +519,6 @@ export declare interface SharedDef {
792
519
  dim?: boolean;
793
520
  }
794
521
 
795
- declare type Space = "svg" | "world";
796
-
797
522
  /** Text alignment */
798
523
  export declare interface TextAlignment {
799
524
  /** Horizontal alignment */
@@ -848,100 +573,6 @@ export declare interface UI {
848
573
  memoryInfoPanel: HTMLDivElement;
849
574
  }
850
575
 
851
- /** Viewport system. Manages the scene and camera. */
852
- declare class ViewportSystem {
853
- private renderer;
854
- private eventSystem;
855
- private sceneSystem;
856
- private cameraSystem;
857
- private raycaster;
858
- private intersectionPoint;
859
- private viewboxPlane;
860
- private pxToSvgScaleThreshold;
861
- private prevPxToSvgScale?;
862
- private externalStaticTransformMatrix;
863
- /**
864
- * @param renderer {@link Renderer} instance
865
- * @param eventSystem {@link EventSystem} instance
866
- */
867
- constructor(renderer: Renderer, eventSystem: EventSystem);
868
- /** {@link Scene} instance */
869
- get scene(): Scene;
870
- /** Current {@link Camera} instance */
871
- get camera(): Camera;
872
- /** {@link CameraController} instance */
873
- get cameraController(): CameraController;
874
- /** Current camera zoom factor. */
875
- get zoomFactor(): number;
876
- /** Scene scale factor (SVG to pixel) */
877
- get scaleFactor(): number;
878
- /**
879
- * Initializes the viewport and zoom bounds with the given scene definition.
880
- * @param sceneDef {@link SceneDef} scene definition
881
- */
882
- initViewport(sceneDef: SceneDef): void;
883
- /** Updates the viewport when the renderer size changes. */
884
- updateViewport(): void;
885
- /**
886
- * Recalculates the svg to pixel scale factor and emits the event if necessary.
887
- */
888
- updatePtScale(): void;
889
- /**
890
- * Gets the objects intersected by the raycaster.
891
- * @param normalizedCoords raycast point in NDC (normalized device coordinates
892
- * @returns Array of {@link Intersection} instances
893
- */
894
- getIntersectedObjects(normalizedCoords: Vector2): Intersection<Object3D<Object3DEventMap>>[];
895
- /**
896
- * Converts a point from SVG coordinates to world coordinates.
897
- * @param svgCoords Point in SVG coordinates
898
- * @returns Point in world coordinates
899
- */
900
- svgToWorld(svgCoords: Vector2): Vector2;
901
- /**
902
- * Converts a point from screen coordinates to the given coordinate space.
903
- * @param space Space to convert to (either "svg" or "world")
904
- * @param normalizedCoords Point in NDC (normalized device coordinates)
905
- * @returns Point in the given space
906
- */
907
- screenTo(space: Space, normalizedCoords: Vector2): Vector2Like;
908
- /**
909
- * Calculates the camera distance from the scene's plane for a given zoom factor.
910
- * @param zoomFactor Zoom factor
911
- * @returns Corresponding camera distance on the Z axis
912
- */
913
- zoomFactorToDistance(zoomFactor: number): number;
914
- /**
915
- * Sets the external transform matrix.
916
- * @param staticTransformMatrix static transform matrix to apply to the scene
917
- */
918
- setExternalTransform(staticTransformMatrix: number[]): void;
919
- /**
920
- * Updates the external camera.
921
- * @param dynamicTransformMatrix dynamic transform matrix to apply to the scene
922
- */
923
- updateExternalCamera(dynamicTransformMatrix: number[]): void;
924
- }
925
-
926
- /**
927
- * Zoom handler - wraps camera-controls DOLLY action.
928
- * Handles both mouse wheel and two-finger pinch gestures.
929
- * No custom event listeners needed - camera-controls handles everything
930
- */
931
- declare class ZoomHandler extends Handler {
932
- reset(enableTransition?: boolean): Promise<void>;
933
- /**
934
- * Enable zoom gestures.
935
- * Configures camera-controls to handle mouse wheel and two-finger pinch
936
- */
937
- protected onEnable(): void;
938
- /**
939
- * Disable zoom gestures.
940
- * Removes zoom actions from camera-controls
941
- */
942
- protected onDisable(): void;
943
- }
944
-
945
576
  /** Options for the {@link ControlsAPI.zoomTo} method. */
946
577
  export declare interface ZoomToOptions {
947
578
  /** Maximum zoom factor. */