angular-three 3.7.0 → 4.0.0-next.1

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 (53) hide show
  1. package/dom/README.md +3 -0
  2. package/dom/index.d.ts +2 -0
  3. package/dom/lib/canvas.d.ts +49 -0
  4. package/{lib/dom → dom/lib}/events.d.ts +2 -3
  5. package/dom/lib/renderer.d.ts +1 -0
  6. package/fesm2022/angular-three-dom.mjs +278 -0
  7. package/fesm2022/angular-three-dom.mjs.map +1 -0
  8. package/fesm2022/angular-three-testing.mjs +45 -28
  9. package/fesm2022/angular-three-testing.mjs.map +1 -1
  10. package/fesm2022/angular-three.mjs +2671 -3006
  11. package/fesm2022/angular-three.mjs.map +1 -1
  12. package/index.d.ts +5 -3
  13. package/lib/directives/args.d.ts +4 -8
  14. package/lib/directives/common.d.ts +20 -0
  15. package/lib/directives/parent.d.ts +7 -11
  16. package/lib/events.d.ts +5 -5
  17. package/lib/html.d.ts +4 -7
  18. package/lib/instance.d.ts +8 -4
  19. package/lib/loop.d.ts +13 -25
  20. package/lib/portal.d.ts +26 -45
  21. package/lib/renderer/catalogue.d.ts +4 -12
  22. package/lib/renderer/constants.d.ts +11 -22
  23. package/lib/renderer/renderer.d.ts +53 -0
  24. package/lib/renderer/state.d.ts +62 -22
  25. package/lib/renderer/utils.d.ts +10 -10
  26. package/lib/roots.d.ts +2 -6
  27. package/lib/routed-scene.d.ts +2 -10
  28. package/lib/store.d.ts +7 -12
  29. package/lib/three-types.d.ts +225 -404
  30. package/lib/types.d.ts +168 -162
  31. package/lib/utils/apply-props.d.ts +4 -2
  32. package/lib/utils/attach.d.ts +5 -5
  33. package/lib/utils/before-render.d.ts +1 -1
  34. package/lib/utils/is.d.ts +12 -11
  35. package/lib/utils/make.d.ts +7 -7
  36. package/lib/utils/object-events.d.ts +4 -4
  37. package/lib/utils/parameters.d.ts +11 -11
  38. package/lib/utils/signal-state.d.ts +27 -0
  39. package/lib/utils/update.d.ts +2 -2
  40. package/package.json +79 -97
  41. package/testing/lib/test-bed.d.ts +12 -9
  42. package/testing/lib/test-canvas.d.ts +8 -5
  43. package/LICENSE +0 -21
  44. package/fesm2022/angular-three-nativescript.mjs +0 -134
  45. package/fesm2022/angular-three-nativescript.mjs.map +0 -1
  46. package/lib/canvas.d.ts +0 -368
  47. package/lib/renderer/index.d.ts +0 -65
  48. package/lib/utils/signal-store.d.ts +0 -26
  49. package/metadata.json +0 -1
  50. package/nativescript/README.md +0 -5
  51. package/nativescript/index.d.ts +0 -1
  52. package/nativescript/lib/canvas.d.ts +0 -359
  53. package/web-types.json +0 -1
package/lib/types.d.ts CHANGED
@@ -1,91 +1,88 @@
1
- import { ElementRef, Signal } from '@angular/core';
2
- import { Observable } from 'rxjs';
3
- import { Camera, Clock, EventDispatcher, Intersection, Object3D, OrthographicCamera, PerspectiveCamera, Ray, Raycaster, Scene, Vector2, Vector3, WebGLRenderer, WebGLRendererParameters, WebGLShadowMap } from 'three';
4
- import { NgtObject3DNode } from './three-types';
5
- import { NgtSignalStore } from './utils/signal-store';
6
- export type NgtProperties<T> = {
7
- [K in keyof T as T[K] extends (...args: Array<any>) => any ? never : K]: T[K];
8
- };
1
+ import type { ElementRef, Signal } from '@angular/core';
2
+ import type { Observable } from 'rxjs';
3
+ import type * as THREE from 'three';
4
+ import type { NgtProperties, NgtThreeElement, NgtVector3 } from './three-types';
5
+ import type { SignalState } from './utils/signal-state';
6
+ export type NgtArguments<T> = T extends NgtConstructorRepresentation ? T extends typeof THREE.Color ? [r: number, g: number, b: number] | [color: THREE.ColorRepresentation] : ConstructorParameters<T> : any[];
7
+ export type NgtConstructorRepresentation<T = any> = new (...args: any[]) => T;
9
8
  export type NgtAnyRecord = Record<string, any>;
10
9
  export type NgtNullish<T> = T | null | undefined;
11
- export type NgtEquConfig = {
10
+ export interface NgtDisposable {
11
+ type?: string;
12
+ dispose?: () => void;
13
+ }
14
+ export interface NgtEquConfig {
12
15
  /** Compare arrays by reference equality a === b (default), or by shallow equality */
13
16
  arrays?: 'reference' | 'shallow';
14
17
  /** Compare objects by reference equality a === b (default), or by shallow equality */
15
18
  objects?: 'reference' | 'shallow';
16
19
  /** If true the keys in both a and b must match 1:1 (default), if false a's keys must intersect b's */
17
20
  strict?: boolean;
21
+ }
22
+ export type NgtCameraLike = THREE.OrthographicCamera | THREE.PerspectiveCamera;
23
+ export type NgtCamera = NgtCameraLike & {
24
+ manual?: boolean;
18
25
  };
19
- export type NgtGLOptions = NgtRendererLike | ((canvas: NgtCanvasElement) => NgtRendererLike) | Partial<NgtProperties<WebGLRenderer> | WebGLRendererParameters> | undefined;
20
- export interface NgtCanvasOptions {
21
- /** A threejs renderer instance or props that go into the default renderer */
22
- gl?: NgtGLOptions;
23
- /** Dimensions to fit the renderer to. Will measure canvas dimensions if omitted */
24
- size?: NgtSize;
25
- /**
26
- * Enables shadows (by default PCFsoft). Can accept `gl.shadowMap` options for fine-tuning,
27
- * but also strings: 'basic' | 'percentage' | 'soft' | 'variance'.
28
- * @see https://threejs.org/docs/#api/en/renderers/WebGLRenderer.shadowMap
29
- */
30
- shadows?: boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<WebGLShadowMap>;
31
- /**
32
- * Disables three r139 color management.
33
- * @see https://threejs.org/docs/#manual/en/introduction/Color-management
34
- */
35
- legacy?: boolean;
36
- /** Switch off automatic sRGB color space and gamma correction */
37
- linear?: boolean;
38
- /** Use `THREE.NoToneMapping` instead of `THREE.ACESFilmicToneMapping` */
39
- flat?: boolean;
40
- /** Creates an orthographic camera */
41
- orthographic?: boolean;
42
- /**
43
- * R3F's render mode. Set to `demand` to only render on state change or `never` to take control.
44
- * @see https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#on-demand-rendering
45
- */
46
- frameloop?: 'always' | 'demand' | 'never';
47
- /**
48
- * R3F performance options for adaptive performance.
49
- * @see https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#movement-regression
50
- */
51
- performance?: Partial<Omit<NgtPerformance, 'regress'>>;
52
- /** Target pixel ratio. Can clamp between a range: `[min, max]` */
53
- dpr?: NgtDpr;
54
- /** Props that go into the default raycaster */
55
- raycaster?: Partial<Raycaster>;
56
- /** A `Scene` instance or props that go into the default scene */
57
- scene?: Scene | Partial<Scene>;
58
- /** A `Camera` instance or props that go into the default camera */
59
- camera?: (NgtCamera | Partial<NgtObject3DNode<Camera, typeof Camera> & NgtObject3DNode<PerspectiveCamera, typeof PerspectiveCamera> & NgtObject3DNode<OrthographicCamera, typeof OrthographicCamera>>) & {
60
- /** Flags the camera as manual, putting projection into your own hands */
61
- manual?: boolean;
62
- };
63
- /** An R3F event manager to manage elements' pointer events */
64
- events?: (store: NgtSignalStore<NgtState>) => NgtEventManager<HTMLElement>;
65
- /** The target where events are being subscribed to, default: the div that wraps canvas */
66
- eventSource?: HTMLElement | ElementRef<HTMLElement>;
67
- /** The event prefix that is cast into canvas pointer x/y events, default: "offset" */
68
- eventPrefix?: 'offset' | 'client' | 'page' | 'layer' | 'screen';
69
- /** Default coordinate for the camera to look at */
70
- lookAt?: Vector3 | Parameters<Vector3['set']>;
26
+ export type NgtCameraParameters = Partial<NgtThreeElement<typeof THREE.Camera> & NgtThreeElement<typeof THREE.PerspectiveCamera> & NgtThreeElement<typeof THREE.OrthographicCamera>> & {
27
+ manual?: boolean;
28
+ };
29
+ export interface NgtRendererLike {
30
+ render: (scene: THREE.Scene, camera: THREE.Camera) => any;
31
+ }
32
+ export type NgtCanvasElement = HTMLCanvasElement | OffscreenCanvas;
33
+ export type NgtGlobalRenderCallback = (timeStamp: number) => void;
34
+ export type NgtGLOptions = NgtRendererLike | ((canvas: NgtCanvasElement) => NgtRendererLike) | Partial<NgtProperties<THREE.WebGLRenderer> | THREE.WebGLRendererParameters> | undefined;
35
+ export type NgtDpr = number | [min: number, max: number];
36
+ export interface NgtSize {
37
+ width: number;
38
+ height: number;
39
+ top: number;
40
+ left: number;
71
41
  }
72
- export interface NgtIntersection extends Intersection {
42
+ export interface NgtViewport extends NgtSize {
43
+ /** The initial pixel ratio */
44
+ initialDpr: number;
45
+ /** Current pixel ratio */
46
+ dpr: number;
47
+ /** size.width / viewport.width */
48
+ factor: number;
49
+ /** Camera distance */
50
+ distance: number;
51
+ /** Camera aspect ratio: width / height */
52
+ aspect: number;
53
+ }
54
+ export type NgtShadows = boolean | 'basic' | 'percentage' | 'soft' | 'variance' | Partial<THREE.WebGLShadowMap>;
55
+ export type NgtFrameloop = 'always' | 'demand' | 'never';
56
+ export interface NgtPerformance {
57
+ /** Current performance normal, between min and max */
58
+ current: number;
59
+ /** How low the performance can go, between 0 and max */
60
+ min: number;
61
+ /** How high the performance can go, between min and max */
62
+ max: number;
63
+ /** Time until current returns to max in ms */
64
+ debounce: number;
65
+ /** Sets current to min, puts the system in regression */
66
+ regress: () => void;
67
+ }
68
+ export type NgtEventPrefix = 'offset' | 'client' | 'page' | 'layer' | 'screen';
69
+ export interface NgtIntersection extends THREE.Intersection {
73
70
  /** The event source (the object which registered the handler) */
74
- eventObject: Object3D;
71
+ eventObject: THREE.Object3D;
75
72
  }
76
73
  export interface NgtIntersectionEvent<TSourceEvent> extends NgtIntersection {
77
74
  /** The event source (the object which registered the handler) */
78
- eventObject: Object3D;
75
+ eventObject: THREE.Object3D;
79
76
  /** An array of intersections */
80
77
  intersections: NgtIntersection[];
81
78
  /** vec3.set(pointer.x, pointer.y, 0).unproject(camera) */
82
- unprojectedPoint: Vector3;
79
+ unprojectedPoint: THREE.Vector3;
83
80
  /** Normalized event coordinates */
84
- pointer: Vector2;
81
+ pointer: THREE.Vector2;
85
82
  /** Delta between first click and this event */
86
83
  delta: number;
87
84
  /** The ray that pierced it */
88
- ray: Ray;
85
+ ray: THREE.Ray;
89
86
  /** The camera that was used by the raycaster */
90
87
  camera: NgtCamera;
91
88
  /** stopPropagation will stop underlying handlers from firing */
@@ -95,10 +92,9 @@ export interface NgtIntersectionEvent<TSourceEvent> extends NgtIntersection {
95
92
  /** If the event was stopped by calling stopPropagation */
96
93
  stopped: boolean;
97
94
  }
98
- export type NgtCamera = OrthographicCamera | PerspectiveCamera;
99
95
  export type NgtThreeEvent<TEvent> = NgtIntersectionEvent<TEvent> & NgtProperties<TEvent>;
100
96
  export type NgtDomEvent = PointerEvent | MouseEvent | WheelEvent;
101
- export type NgtEventHandlers = {
97
+ export interface NgtEventHandlers {
102
98
  click?: (event: NgtThreeEvent<MouseEvent>) => void;
103
99
  contextmenu?: (event: NgtThreeEvent<MouseEvent>) => void;
104
100
  dblclick?: (event: NgtThreeEvent<MouseEvent>) => void;
@@ -112,13 +108,13 @@ export type NgtEventHandlers = {
112
108
  pointermissed?: (event: MouseEvent) => void;
113
109
  pointercancel?: (event: NgtThreeEvent<PointerEvent>) => void;
114
110
  wheel?: (event: NgtThreeEvent<WheelEvent>) => void;
115
- };
111
+ }
116
112
  export type NgtEvents = {
117
113
  [TEvent in keyof NgtEventHandlers]-?: EventListener;
118
114
  };
119
- export type NgtFilterFunction = (items: Intersection[], store: NgtSignalStore<NgtState>) => Intersection[];
120
- export type NgtComputeFunction = (event: NgtDomEvent, root: NgtSignalStore<NgtState>, previous: NgtSignalStore<NgtState> | null) => void;
121
- export type NgtEventManager<TTarget> = {
115
+ export type NgtFilterFunction = (items: THREE.Intersection[], store: SignalState<NgtState>) => THREE.Intersection[];
116
+ export type NgtComputeFunction = (event: NgtDomEvent, root: SignalState<NgtState>, previous: SignalState<NgtState> | null) => void;
117
+ export interface NgtEventManager<TTarget> {
122
118
  /** Determines if the event layer is active */
123
119
  enabled: boolean;
124
120
  /** Event layer priority, higher prioritized layers come first and may stop(-propagate) lower layer */
@@ -139,148 +135,139 @@ export type NgtEventManager<TTarget> = {
139
135
  * explicit user interaction, for instance when the camera moves a hoverable object underneath the cursor.
140
136
  */
141
137
  update?: () => void;
142
- };
138
+ }
143
139
  export interface NgtPointerCaptureTarget {
144
140
  intersection: NgtIntersection;
145
141
  target: Element;
146
142
  }
147
- export type NgtAttachFunction<TChild = any, TParent = any> = (parent: TParent, child: TChild, store: NgtSignalStore<NgtState>) => void | (() => void);
148
- export type NgtAttachable<TChild = any, TParent = any> = NgtAttachFunction<TChild, TParent> | string | (string | number)[];
149
- export interface NgtAfterAttach<TChild extends NgtInstanceNode = NgtInstanceNode, TParent extends NgtInstanceNode = NgtInstanceNode> {
150
- parent: TParent;
151
- node: TChild;
152
- }
153
- export interface NgtLocalInstanceState {
143
+ export interface NgtInstanceHierarchyState {
154
144
  objects: NgtInstanceNode[];
155
145
  nonObjects: NgtInstanceNode[];
156
146
  parent: NgtInstanceNode | null;
157
147
  geometryStamp: number;
158
148
  }
159
- export interface NgtLocalState {
160
- /** the store of the canvas that the instance is being rendered to */
161
- store: NgtSignalStore<NgtState>;
162
- instanceStore: NgtSignalStore<NgtLocalInstanceState>;
163
- parent: Signal<NgtLocalInstanceState['parent']>;
164
- objects: Signal<NgtLocalInstanceState['objects']>;
165
- nonObjects: Signal<NgtLocalInstanceState['nonObjects']>;
149
+ export interface NgtInstanceState<TObject extends NgtAnyRecord = NgtAnyRecord> {
150
+ /**
151
+ * The store that the intsance is being rendered with
152
+ */
153
+ store: SignalState<NgtState> | null;
154
+ /**
155
+ * hierachy store for the instance
156
+ */
157
+ hierarchyStore: SignalState<NgtInstanceHierarchyState>;
158
+ parent: Signal<NgtInstanceHierarchyState['parent']>;
159
+ objects: Signal<NgtInstanceHierarchyState['objects']>;
160
+ nonObjects: Signal<NgtInstanceHierarchyState['nonObjects']>;
161
+ /**
162
+ * reference back to the object
163
+ */
164
+ object: TObject & {
165
+ __ngt__?: NgtInstanceState<TObject>;
166
+ };
166
167
  add: (instance: NgtInstanceNode, type: 'objects' | 'nonObjects') => void;
167
168
  remove: (instance: NgtInstanceNode, type: 'objects' | 'nonObjects') => void;
168
169
  setParent: (parent: NgtInstanceNode | null) => void;
169
170
  updateGeometryStamp: () => void;
170
- primitive?: boolean;
171
+ /**
172
+ * event count for the instance
173
+ */
171
174
  eventCount: number;
175
+ /**
176
+ * handlers for the instance
177
+ */
172
178
  handlers: Partial<NgtEventHandlers>;
179
+ /**
180
+ * attach information so that we can detach as well as reset
181
+ */
173
182
  attach?: string[] | NgtAttachFunction;
183
+ /**
184
+ * previously attach information so we can reset as well as clean up
185
+ */
174
186
  previousAttach?: unknown | (() => void);
175
- isRaw?: boolean;
176
- priority?: number;
187
+ /**
188
+ * the element tag used to create this instance
189
+ */
190
+ type: string;
177
191
  onUpdate?: (node: NgtInstanceNode) => void;
178
192
  onAttach?: (afterAttach: NgtAfterAttach) => void;
193
+ setPointerEvent?: <TEvent extends keyof NgtEventHandlers>(eventName: TEvent, callback: NgtEventHandlers[TEvent]) => () => void;
194
+ addInteraction?: (store?: SignalState<NgtState> | null) => void;
195
+ removeInteraction?: (store?: SignalState<NgtState> | null) => void;
179
196
  }
180
- export type NgtInstanceNode<TNode = any> = {
181
- __ngt__: NgtLocalState;
182
- } & NgtAnyRecord & TNode;
183
- export type NgtCanvasElement = HTMLCanvasElement | OffscreenCanvas;
184
- export type NgtGlobalRenderCallback = (timeStamp: number) => void;
185
- export type NgtRendererLike = {
186
- render: (scene: Scene, camera: Camera) => any;
187
- };
188
- export type NgtCameraManual = NgtCamera & {
189
- manual?: boolean;
190
- };
191
- export type NgtDpr = number | [min: number, max: number];
192
- export type NgtSize = {
193
- width: number;
194
- height: number;
195
- top: number;
196
- left: number;
197
- };
198
- export type NgtViewport = NgtSize & {
199
- /** The initial pixel ratio */
200
- initialDpr: number;
201
- /** Current pixel ratio */
202
- dpr: number;
203
- /** size.width / viewport.width */
204
- factor: number;
205
- /** Camera distance */
206
- distance: number;
207
- /** Camera aspect ratio: width / height */
208
- aspect: number;
209
- };
210
- export type NgtPerformance = {
211
- /** Current performance normal, between min and max */
212
- current: number;
213
- /** How low the performance can go, between 0 and max */
214
- min: number;
215
- /** How high the performance can go, between min and max */
216
- max: number;
217
- /** Time until current returns to max in ms */
218
- debounce: number;
219
- /** Sets current to min, puts the system in regression */
220
- regress: () => void;
197
+ export type NgtInstanceNode<TObject extends NgtAnyRecord = NgtAnyRecord> = TObject & {
198
+ __ngt__: NgtInstanceState<TObject>;
221
199
  };
222
- export type NgtRenderState = NgtState & {
200
+ export type NgtAttachFunction<TChild = any, TParent = any> = (parent: TParent, child: TChild, store: SignalState<NgtState>) => void | (() => void);
201
+ export type NgtAttachable<TChild = any, TParent = any> = NgtAttachFunction<TChild, TParent> | string | (string | number)[];
202
+ export interface NgtAfterAttach<TChild = NgtInstanceNode, TParent = NgtInstanceNode> {
203
+ parent: TParent;
204
+ node: TChild;
205
+ }
206
+ export interface NgtRenderState extends NgtState {
223
207
  delta: number;
224
208
  frame?: XRFrame;
225
- };
226
- export type NgtBeforeRenderEvent<TObject extends NgtInstanceNode = NgtInstanceNode> = {
209
+ }
210
+ export interface NgtBeforeRenderEvent<TObject = NgtInstanceNode> {
227
211
  state: NgtRenderState;
228
212
  object: TObject;
229
- };
230
- export type NgtBeforeRenderRecord = {
213
+ }
214
+ export interface NgtBeforeRenderRecord {
231
215
  callback: (state: NgtRenderState) => void;
232
- store: NgtSignalStore<NgtState>;
216
+ store: SignalState<NgtState>;
233
217
  priority?: number;
234
- };
235
- export type NgtInternalState = {
218
+ }
219
+ export interface NgtXRManager {
220
+ connect: () => void;
221
+ disconnect: () => void;
222
+ }
223
+ export interface NgtInternalState {
236
224
  active: boolean;
237
225
  priority: number;
238
226
  frames: number;
239
227
  lastEvent: ElementRef<NgtDomEvent | null>;
240
- interaction: Object3D[];
228
+ interaction: THREE.Object3D[];
241
229
  hovered: Map<string, NgtThreeEvent<NgtDomEvent>>;
242
- capturedMap: Map<number, Map<Object3D, NgtPointerCaptureTarget>>;
230
+ capturedMap: Map<number, Map<THREE.Object3D, NgtPointerCaptureTarget>>;
243
231
  initialClick: [x: number, y: number];
244
- initialHits: Object3D[];
232
+ initialHits: THREE.Object3D[];
245
233
  subscribers: NgtBeforeRenderRecord[];
246
- subscribe: (callback: NgtBeforeRenderRecord['callback'], priority?: number, store?: NgtSignalStore<NgtState>) => () => void;
247
- };
248
- export type NgtState = {
234
+ subscribe: (callback: NgtBeforeRenderRecord['callback'], priority?: number, store?: SignalState<NgtState>) => () => void;
235
+ }
236
+ export interface NgtState {
237
+ /** id **/
238
+ id: string;
249
239
  /** The instance of the renderer */
250
- gl: WebGLRenderer;
240
+ gl: THREE.WebGLRenderer;
251
241
  /** Default camera */
252
- camera: NgtCameraManual;
242
+ camera: NgtCamera;
253
243
  /** Default scene */
254
- scene: Scene;
244
+ scene: THREE.Scene;
255
245
  /** Default raycaster */
256
- raycaster: Raycaster;
246
+ raycaster: THREE.Raycaster;
257
247
  /** Default clock */
258
- clock: Clock;
248
+ clock: THREE.Clock;
259
249
  /** Event layer interface, contains the event handler and the node they're connected to */
260
250
  events: NgtEventManager<any>;
261
251
  /** XR interface */
262
- xr: {
263
- connect: () => void;
264
- disconnect: () => void;
265
- };
252
+ xr: NgtXRManager;
266
253
  /** Currently used controls */
267
- controls: EventDispatcher | null;
254
+ controls: THREE.EventDispatcher | null;
268
255
  /** Normalized event coordinates */
269
- pointer: Vector2;
256
+ pointer: THREE.Vector2;
270
257
  legacy: boolean;
271
258
  /** Shortcut to gl.outputColorSpace = LinearSRGBColorSpace */
272
259
  linear: boolean;
273
260
  /** Shortcut to gl.toneMapping = NoTonemapping */
274
261
  flat: boolean;
275
262
  /** Render loop flags */
276
- frameloop: 'always' | 'demand' | 'never';
263
+ frameloop: NgtFrameloop;
277
264
  /** Adaptive performance interface */
278
265
  performance: NgtPerformance;
279
266
  /** Reactive pixel-size of the canvas */
280
267
  size: NgtSize;
281
268
  /** Reactive size of the viewport in threejs units */
282
269
  viewport: NgtViewport & {
283
- getCurrentViewport: (camera?: NgtCamera, target?: Vector3 | Parameters<Vector3['set']>, size?: NgtSize) => Omit<NgtViewport, 'dpr' | 'initialDpr'>;
270
+ getCurrentViewport: (camera: NgtCamera, target?: THREE.Vector3 | Parameters<THREE.Vector3['set']>, size?: NgtSize) => Omit<NgtViewport, 'dpr' | 'initialDpr'>;
284
271
  };
285
272
  /** Flags the canvas for render, but doesn't render in itself */
286
273
  invalidate: (frames?: number) => void;
@@ -295,12 +282,31 @@ export type NgtState = {
295
282
  /** Shortcut to manual setting the pixel ratio */
296
283
  setDpr: (dpr: NgtDpr) => void;
297
284
  /** Shortcut to frameloop flags */
298
- setFrameloop: (frameloop?: 'always' | 'demand' | 'never') => void;
285
+ setFrameloop: (frameloop?: NgtFrameloop) => void;
299
286
  /** When the canvas was clicked but nothing was hit */
300
287
  /** PointerMissed Observable */
301
288
  pointerMissed$: Observable<MouseEvent>;
302
289
  /** If this state model is layered (via createPortal) then this contains the previous layer */
303
- previousRoot: NgtSignalStore<NgtState> | null;
290
+ previousRoot: SignalState<NgtState> | null;
304
291
  /** Internals */
305
292
  internal: NgtInternalState;
306
- };
293
+ }
294
+ export interface NgtCanvasOptions {
295
+ gl?: NgtGLOptions;
296
+ size?: NgtSize;
297
+ shadows?: NgtShadows;
298
+ legacy?: boolean;
299
+ linear?: boolean;
300
+ flat?: boolean;
301
+ orthographic?: boolean;
302
+ frameloop?: NgtFrameloop;
303
+ performance?: Partial<Omit<NgtPerformance, 'regress'>>;
304
+ dpr?: NgtDpr;
305
+ raycaster?: Partial<THREE.Raycaster>;
306
+ scene?: THREE.Scene | Partial<THREE.Scene>;
307
+ camera?: NgtCamera | NgtCameraParameters;
308
+ events?: (store: SignalState<NgtState>) => NgtEventManager<HTMLElement>;
309
+ eventSource?: HTMLElement | ElementRef<HTMLElement>;
310
+ eventPrefix?: NgtEventPrefix;
311
+ lookAt?: NgtVector3;
312
+ }
@@ -1,3 +1,5 @@
1
- import { NgtAnyRecord, NgtInstanceNode } from '../types';
1
+ import type { NgtAnyRecord, NgtInstanceState } from '../types';
2
2
  export declare const NGT_APPLY_PROPS = "__ngt_apply_props__";
3
- export declare function applyProps(instance: NgtInstanceNode, props: NgtAnyRecord): any;
3
+ export declare function applyProps<T extends NgtAnyRecord>(instance: NgtInstanceState<T>['object'], props: NgtAnyRecord): T & {
4
+ __ngt__?: NgtInstanceState<T> | undefined;
5
+ };
@@ -1,9 +1,9 @@
1
- import { NgtAnyRecord, NgtAttachFunction, NgtState } from '../types';
2
- import { NgtSignalStore } from './signal-store';
3
- export declare function attach(object: NgtAnyRecord, value: unknown, paths?: string[], useApplyProps?: boolean): void;
4
- export declare function detach(parent: NgtAnyRecord, child: NgtAnyRecord, attachProp: string[] | NgtAttachFunction): void;
1
+ import type { NgtAttachFunction, NgtInstanceNode, NgtState } from '../types';
2
+ import { SignalState } from './signal-state';
3
+ export declare function attach(object: NgtInstanceNode, value: unknown, paths?: string[], useApplyProps?: boolean): void;
4
+ export declare function detach(parent: NgtInstanceNode, child: NgtInstanceNode, attachProp: string[] | NgtAttachFunction): void;
5
5
  export declare function createAttachFunction<TChild = any, TParent = any>(cb: (params: {
6
6
  parent: TParent;
7
7
  child: TChild;
8
- store: NgtSignalStore<NgtState>;
8
+ store: SignalState<NgtState>;
9
9
  }) => (() => void) | void): NgtAttachFunction<TChild, TParent>;
@@ -1,5 +1,5 @@
1
1
  import { Injector } from '@angular/core';
2
- import { NgtBeforeRenderRecord } from '../types';
2
+ import type { NgtBeforeRenderRecord } from '../types';
3
3
  /**
4
4
  * `injectBeforeRender` invokes its callback on every frame. Hence, the notion of tracking
5
5
  * changes (i.e: signals) does not really matter since we're getting latest values of the things we need on every frame anyway.
package/lib/utils/is.d.ts CHANGED
@@ -1,19 +1,20 @@
1
- import { ElementRef } from '@angular/core';
2
- import { BufferGeometry, Camera, Material, Object3D, OrthographicCamera, PerspectiveCamera, Scene, Texture } from 'three';
3
- import { NgtEquConfig, NgtInstanceNode, NgtRendererLike } from '../types';
1
+ import type { ElementRef } from '@angular/core';
2
+ import type * as THREE from 'three';
3
+ import type { NgtEquConfig, NgtInstanceNode, NgtRendererLike } from '../types';
4
4
  export declare const is: {
5
5
  obj: (a: unknown) => a is object;
6
- material: (a: unknown) => a is Material;
7
- geometry: (a: unknown) => a is BufferGeometry;
8
- orthographicCamera: (a: unknown) => a is OrthographicCamera;
9
- perspectiveCamera: (a: unknown) => a is PerspectiveCamera;
10
- camera: (a: unknown) => a is Camera;
6
+ material: (a: unknown) => a is THREE.Material;
7
+ geometry: (a: unknown) => a is THREE.BufferGeometry;
8
+ orthographicCamera: (a: unknown) => a is THREE.OrthographicCamera;
9
+ perspectiveCamera: (a: unknown) => a is THREE.PerspectiveCamera;
10
+ camera: (a: unknown) => a is THREE.Camera;
11
11
  renderer: (a: unknown) => boolean;
12
- scene: (a: unknown) => a is Scene;
12
+ scene: (a: unknown) => a is THREE.Scene;
13
13
  ref: (a: unknown) => a is ElementRef;
14
14
  instance: (a: unknown) => a is NgtInstanceNode;
15
- object3D: (a: unknown) => a is Object3D;
16
- colorSpaceExist: <T extends NgtRendererLike | Texture | object, P = T extends NgtRendererLike ? {
15
+ object3D: (a: unknown) => a is THREE.Object3D;
16
+ three: <TThreeEntity extends object, TKey extends keyof TThreeEntity = keyof TThreeEntity>(a: unknown, isKey: TKey extends `is${infer K}` ? TKey : never) => a is TThreeEntity;
17
+ colorSpaceExist: <T extends NgtRendererLike | THREE.Texture | object, P = T extends NgtRendererLike ? {
17
18
  outputColorSpace: string;
18
19
  } : {
19
20
  colorSpace: string;
@@ -1,12 +1,12 @@
1
- import { Material, Object3D, OrthographicCamera, PerspectiveCamera, WebGLRenderer } from 'three';
2
- import { NgtCanvasElement, NgtDpr, NgtGLOptions, NgtIntersection, NgtSize } from '../types';
1
+ import * as THREE from 'three';
2
+ import type { NgtCanvasElement, NgtDpr, NgtGLOptions, NgtIntersection, NgtSize } from '../types';
3
3
  export declare function makeId(event?: NgtIntersection): string;
4
4
  export declare function makeDpr(dpr: NgtDpr, window?: Window): number;
5
- export declare function makeRendererInstance<TCanvas extends NgtCanvasElement>(glOptions: NgtGLOptions, canvas: TCanvas): WebGLRenderer;
6
- export declare function makeCameraInstance(isOrthographic: boolean, size: NgtSize): OrthographicCamera | PerspectiveCamera;
5
+ export declare function makeRendererInstance<TCanvas extends NgtCanvasElement>(glOptions: NgtGLOptions, canvas: TCanvas): THREE.WebGLRenderer;
6
+ export declare function makeCameraInstance(isOrthographic: boolean, size: NgtSize): THREE.OrthographicCamera | THREE.PerspectiveCamera;
7
7
  export type NgtObjectMap = {
8
- nodes: Record<string, Object3D<any>>;
9
- materials: Record<string, Material>;
8
+ nodes: Record<string, THREE.Object3D<any>>;
9
+ materials: Record<string, THREE.Material>;
10
10
  [key: string]: any;
11
11
  };
12
- export declare function makeObjectGraph(object: Object3D): NgtObjectMap;
12
+ export declare function makeObjectGraph(object: THREE.Object3D): NgtObjectMap;
@@ -1,6 +1,6 @@
1
1
  import { ElementRef, Injector } from '@angular/core';
2
- import { Object3D } from 'three';
3
- import { NgtEventHandlers, NgtThreeEvent } from '../types';
2
+ import type * as THREE from 'three';
3
+ import type { NgtEventHandlers, NgtThreeEvent } from '../types';
4
4
  import * as i0 from "@angular/core";
5
5
  export declare class NgtObjectEvents {
6
6
  click: import("@angular/core").OutputEmitterRef<NgtThreeEvent<MouseEvent>>;
@@ -16,12 +16,12 @@ export declare class NgtObjectEvents {
16
16
  pointermissed: import("@angular/core").OutputEmitterRef<NgtThreeEvent<MouseEvent>>;
17
17
  pointercancel: import("@angular/core").OutputEmitterRef<NgtThreeEvent<PointerEvent>>;
18
18
  wheel: import("@angular/core").OutputEmitterRef<NgtThreeEvent<WheelEvent>>;
19
- ngtObjectEvents: import("@angular/core").ModelSignal<Object3D<import("three").Object3DEventMap> | ElementRef<Object3D<import("three").Object3DEventMap>> | null | undefined>;
19
+ ngtObjectEvents: import("@angular/core").ModelSignal<THREE.Object3D<THREE.Object3DEventMap> | ElementRef<THREE.Object3D<THREE.Object3DEventMap>> | (() => ElementRef<THREE.Object3D> | THREE.Object3D | null | undefined) | null | undefined>;
20
20
  constructor();
21
21
  private emitEvent;
22
22
  static ɵfac: i0.ɵɵFactoryDeclaration<NgtObjectEvents, never>;
23
23
  static ɵdir: i0.ɵɵDirectiveDeclaration<NgtObjectEvents, "[ngtObjectEvents]", never, { "ngtObjectEvents": { "alias": "ngtObjectEvents"; "required": false; "isSignal": true; }; }, { "click": "click"; "dblclick": "dblclick"; "contextmenu": "contextmenu"; "pointerup": "pointerup"; "pointerdown": "pointerdown"; "pointerover": "pointerover"; "pointerout": "pointerout"; "pointerenter": "pointerenter"; "pointerleave": "pointerleave"; "pointermove": "pointermove"; "pointermissed": "pointermissed"; "pointercancel": "pointercancel"; "wheel": "wheel"; "ngtObjectEvents": "ngtObjectEventsChange"; }, never, never, true, never>;
24
24
  }
25
- export declare function injectObjectEvents(target: () => ElementRef<Object3D> | Object3D | null | undefined, events: NgtEventHandlers, { injector }?: {
25
+ export declare function injectObjectEvents(target: () => ElementRef<THREE.Object3D> | THREE.Object3D | null | undefined, events: NgtEventHandlers, { injector }?: {
26
26
  injector?: Injector;
27
27
  }): (() => void)[];
@@ -1,20 +1,20 @@
1
- import { Signal } from '@angular/core';
2
- import { Vector2, Vector3, Vector4 } from 'three';
3
- import { NgtVector2, NgtVector3, NgtVector4 } from '../three-types';
1
+ import { Signal, ValueEqualityFn } from '@angular/core';
2
+ import * as THREE from 'three';
3
+ import type { NgtVector2, NgtVector3, NgtVector4 } from '../three-types';
4
4
  type KeysOfType<TObject extends object, TType> = Exclude<{
5
5
  [K in keyof TObject]: TObject[K] extends TType | undefined | null ? K : never;
6
6
  }[keyof TObject], undefined>;
7
- export declare function omit<TObject extends object, TKeys extends (keyof TObject)[]>(objFn: () => TObject, keysToOmit: TKeys): Signal<Omit<TObject, TKeys[number]>>;
8
- export declare function pick<TObject extends object, TKey extends keyof TObject>(objFn: () => TObject, key: TKey): Signal<TObject[TKey]>;
9
- export declare function pick<TObject extends object, TKeys extends (keyof TObject)[]>(objFn: () => TObject, keys: TKeys): Signal<Pick<TObject, TKeys[number]>>;
10
- export declare function merge<TObject extends object>(objFn: () => TObject, toMerge: Partial<TObject>, mode?: 'override' | 'backfill'): Signal<TObject & Partial<TObject>>;
11
- type NgtVectorComputed<TVector extends Vector2 | Vector3 | Vector4, TNgtVector = TVector extends Vector2 ? NgtVector2 : TVector extends Vector3 ? NgtVector3 : NgtVector4> = {
7
+ export declare function omit<TObject extends object, TKeys extends (keyof TObject)[]>(objFn: () => TObject, keysToOmit: TKeys, equal?: ValueEqualityFn<NoInfer<Omit<TObject, TKeys[number]>>>): Signal<Omit<TObject, TKeys[number]>>;
8
+ export declare function pick<TObject extends object, TKey extends keyof TObject>(objFn: () => TObject, key: TKey, equal?: ValueEqualityFn<NoInfer<TObject[TKey]>>): Signal<TObject[TKey]>;
9
+ export declare function pick<TObject extends object, TKeys extends (keyof TObject)[]>(objFn: () => TObject, keys: TKeys, equal?: ValueEqualityFn<NoInfer<Pick<TObject, TKeys[number]>>>): Signal<Pick<TObject, TKeys[number]>>;
10
+ export declare function merge<TObject extends object>(objFn: () => TObject, toMerge: Partial<TObject>, mode?: 'override' | 'backfill', equal?: ValueEqualityFn<NoInfer<TObject>>): Signal<TObject & Partial<TObject>>;
11
+ type NgtVectorComputed<TVector extends THREE.Vector2 | THREE.Vector3 | THREE.Vector4, TNgtVector = TVector extends THREE.Vector2 ? NgtVector2 : TVector extends THREE.Vector3 ? NgtVector3 : NgtVector4> = {
12
12
  (input: Signal<TNgtVector>): Signal<TVector>;
13
13
  (input: Signal<TNgtVector>, keepUndefined: true): Signal<TVector | undefined>;
14
14
  <TObject extends object>(options: Signal<TObject>, key: KeysOfType<TObject, TNgtVector>): Signal<TVector>;
15
15
  <TObject extends object>(options: Signal<TObject>, key: KeysOfType<TObject, TNgtVector>, keepUndefined: true): Signal<TVector | undefined>;
16
16
  };
17
- export declare const vector2: NgtVectorComputed<Vector2, NgtVector2>;
18
- export declare const vector3: NgtVectorComputed<Vector3, NgtVector3>;
19
- export declare const vector4: NgtVectorComputed<Vector4, NgtVector4>;
17
+ export declare const vector2: NgtVectorComputed<THREE.Vector2, number | THREE.Vector2 | [x: number, y: number]>;
18
+ export declare const vector3: NgtVectorComputed<THREE.Vector3, number | THREE.Vector3 | [x: number, y: number, z: number]>;
19
+ export declare const vector4: NgtVectorComputed<THREE.Vector4, number | THREE.Vector4 | [x: number, y: number, z: number, w: number]>;
20
20
  export {};
@@ -0,0 +1,27 @@
1
+ /** ported from ngrx/signals */
2
+ import { Signal as NgSignal, WritableSignal } from '@angular/core';
3
+ type NonRecord = Iterable<any> | WeakSet<any> | WeakMap<any, any> | Promise<any> | Date | Error | RegExp | ArrayBuffer | DataView | Function;
4
+ type Prettify<T> = {
5
+ [K in keyof T]: T[K];
6
+ } & {};
7
+ type IsRecord<T> = T extends object ? (T extends NonRecord ? false : true) : false;
8
+ type IsUnknownRecord<T> = string extends keyof T ? true : number extends keyof T ? true : false;
9
+ type IsKnownRecord<T> = IsRecord<T> extends true ? (IsUnknownRecord<T> extends true ? false : true) : false;
10
+ declare const STATE_SOURCE: unique symbol;
11
+ type WritableStateSource<State extends object> = {
12
+ [STATE_SOURCE]: WritableSignal<State>;
13
+ };
14
+ export type PartialStateUpdater<State extends object> = (state: State) => Partial<State>;
15
+ export interface Signal<T> extends NgSignal<T> {
16
+ name: unknown;
17
+ length: unknown;
18
+ }
19
+ export type DeepSignal<T> = Signal<T> & (IsKnownRecord<T> extends true ? Readonly<{
20
+ [K in keyof T]: IsKnownRecord<T[K]> extends true ? DeepSignal<T[K]> : Signal<T[K]>;
21
+ }> : unknown);
22
+ export type SignalState<State extends object> = DeepSignal<State> & WritableStateSource<State> & {
23
+ update: (...updaters: Array<Partial<Prettify<State>> | PartialStateUpdater<Prettify<State>>>) => void;
24
+ get snapshot(): State;
25
+ };
26
+ export declare function signalState<State extends object>(initialState: State): SignalState<State>;
27
+ export {};
@@ -1,4 +1,4 @@
1
- import { NgtCameraManual, NgtSize } from '../types';
1
+ import type { NgtCamera, NgtSize } from '../types';
2
2
  export declare function checkNeedsUpdate(value: unknown): void;
3
3
  export declare function checkUpdate(value: unknown): void;
4
- export declare function updateCamera(camera: NgtCameraManual, size: NgtSize): void;
4
+ export declare function updateCamera(camera: NgtCamera, size: NgtSize): void;