angular-three 2.0.0-beta.223 → 2.0.0-beta.225

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.
@@ -1,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { untracked, computed, signal, ElementRef, inject, effect, InjectionToken, Optional, SkipSelf, ViewContainerRef, NgZone, TemplateRef, DestroyRef, Directive, Input, EventEmitter, getDebugNode, RendererFactory2, Injectable, Injector, provideZoneChangeDetection, makeEnvironmentProviders, EnvironmentInjector, afterNextRender, createEnvironmentInjector, Component, ChangeDetectionStrategy, Output, ViewChild, CUSTOM_ELEMENTS_SCHEMA, ContentChild, ChangeDetectorRef, forwardRef } from '@angular/core';
2
+ import { untracked, computed, signal, ElementRef, inject, effect, InjectionToken, Optional, SkipSelf, ViewContainerRef, NgZone, TemplateRef, DestroyRef, Directive, input, getDebugNode, RendererFactory2, Injectable, Injector, makeEnvironmentProviders, provideZoneChangeDetection, EnvironmentInjector, EventEmitter, viewChild, afterNextRender, createEnvironmentInjector, Component, ChangeDetectionStrategy, Output, CUSTOM_ELEMENTS_SCHEMA, contentChild, forwardRef } from '@angular/core';
3
3
  import { injectAutoEffect } from 'ngxtension/auto-effect';
4
4
  import { provideResizeOptions, NgxResize } from 'ngxtension/resize';
5
5
  import * as THREE from 'three';
6
6
  import { DOCUMENT } from '@angular/common';
7
7
  import { createInjectionToken } from 'ngxtension/create-injection-token';
8
- import { Subject, filter } from 'rxjs';
8
+ import { Subject, ReplaySubject, filter } from 'rxjs';
9
9
  import { assertInjector } from 'ngxtension/assert-injector';
10
10
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
11
  import * as i1 from '@angular/router';
@@ -837,8 +837,9 @@ function applyProps(instance, props) {
837
837
  if (rootState?.gl) {
838
838
  if (is.colorSpaceExist(texture) && is.colorSpaceExist(rootState.gl))
839
839
  texture.colorSpace = rootState.gl.outputColorSpace;
840
+ // @ts-expect-error - these are removed in new version of three but still available in older versions
840
841
  else
841
- texture.encoding = rootState.gl.outputEncoding;
842
+ texture['encoding'] = rootState.gl['outputEncoding'];
842
843
  }
843
844
  }
844
845
  }
@@ -858,7 +859,7 @@ function applyProps(instance, props) {
858
859
  rootState.internal.interaction.push(instance);
859
860
  }
860
861
  if (parent && localState?.afterUpdate && localState.afterUpdate.observed && changes.length) {
861
- localState.afterUpdate.emit(instance);
862
+ localState.afterUpdate.next(instance);
862
863
  }
863
864
  return instance;
864
865
  }
@@ -933,8 +934,17 @@ function injectCanvasRootInitializer(injector) {
933
934
  let camera = isCamera ? cameraOptions : makeCameraInstance(orthographic, state.size);
934
935
  if (!isCamera) {
935
936
  camera.position.z = 5;
936
- if (cameraOptions)
937
+ if (cameraOptions) {
937
938
  applyProps(camera, cameraOptions);
939
+ if ('aspect' in cameraOptions ||
940
+ 'left' in cameraOptions ||
941
+ 'right' in cameraOptions ||
942
+ 'top' in cameraOptions ||
943
+ 'bottom' in cameraOptions) {
944
+ Object.assign(camera, { manual: true });
945
+ camera?.updateProjectionMatrix();
946
+ }
947
+ }
938
948
  // always look at center or passed-in lookAt by default
939
949
  if (!state.camera && !cameraOptions?.rotation && !cameraOptions?.quaternion) {
940
950
  if (Array.isArray(lookAt))
@@ -1170,6 +1180,7 @@ function render(timestamp, store, frame) {
1170
1180
  }
1171
1181
  function createLoop(roots) {
1172
1182
  let running = false;
1183
+ let injectBeforeRenderInProgress = false;
1173
1184
  let repeat;
1174
1185
  let frame;
1175
1186
  function loop(timestamp) {
@@ -1179,6 +1190,7 @@ function createLoop(roots) {
1179
1190
  // Run effects
1180
1191
  flushGlobalEffects('before', timestamp);
1181
1192
  // Render all roots
1193
+ injectBeforeRenderInProgress = true;
1182
1194
  for (const root of roots.values()) {
1183
1195
  const state = root.snapshot;
1184
1196
  // If the frameloop is invalidated, do not run another frame
@@ -1188,6 +1200,7 @@ function createLoop(roots) {
1188
1200
  repeat += render(timestamp, root);
1189
1201
  }
1190
1202
  }
1203
+ injectBeforeRenderInProgress = false;
1191
1204
  // Run after-effects
1192
1205
  flushGlobalEffects('after', timestamp);
1193
1206
  // Stop the loop if nothing invalidates it
@@ -1205,8 +1218,21 @@ function createLoop(roots) {
1205
1218
  return roots.forEach((root) => invalidate(root, frames));
1206
1219
  if (state.gl.xr?.isPresenting || !state.internal.active || state.frameloop === 'never')
1207
1220
  return;
1208
- // Increase frames, do not go higher than 60
1209
- state.internal.frames = Math.min(60, state.internal.frames + frames);
1221
+ if (frames > 1) {
1222
+ // legacy support for people using frames parameters
1223
+ // Increase frames, do not go higher than 60
1224
+ state.internal.frames = Math.min(60, state.internal.frames + frames);
1225
+ }
1226
+ else {
1227
+ if (injectBeforeRenderInProgress) {
1228
+ // called from within a injectBeforeRender, it means the user wants an additional frame
1229
+ state.internal.frames = 2;
1230
+ }
1231
+ else {
1232
+ // the user needs a new frame, no need to increment
1233
+ state.internal.frames = 1;
1234
+ }
1235
+ }
1210
1236
  // If the render-loop isn't active, start it
1211
1237
  if (!running) {
1212
1238
  running = true;
@@ -1469,26 +1495,28 @@ class NgtCommonDirective {
1469
1495
  }
1470
1496
  });
1471
1497
  }
1472
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtCommonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1473
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.1", type: NgtCommonDirective, ngImport: i0 }); }
1498
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtCommonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1499
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.9", type: NgtCommonDirective, ngImport: i0 }); }
1474
1500
  }
1475
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtCommonDirective, decorators: [{
1501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtCommonDirective, decorators: [{
1476
1502
  type: Directive
1477
1503
  }], ctorParameters: () => [] });
1478
1504
 
1479
1505
  class NgtArgs extends NgtCommonDirective {
1480
1506
  constructor() {
1481
- super(...arguments);
1507
+ super();
1508
+ this.args = input(null);
1482
1509
  this.injectedArgs = [];
1510
+ effect(() => {
1511
+ const args = this.args();
1512
+ if (args == null || !Array.isArray(args) || (args.length === 1 && args[0] === null))
1513
+ return;
1514
+ this.injected = false;
1515
+ this.injectedArgs = args;
1516
+ this.createView();
1517
+ });
1483
1518
  }
1484
- set args(args) {
1485
- if (args == null || !Array.isArray(args) || (args.length === 1 && args[0] === null))
1486
- return;
1487
- this.injected = false;
1488
- this.injectedArgs = args;
1489
- this.createView();
1490
- }
1491
- get args() {
1519
+ get value() {
1492
1520
  if (this.validate()) {
1493
1521
  this.injected = true;
1494
1522
  return this.injectedArgs;
@@ -1498,29 +1526,29 @@ class NgtArgs extends NgtCommonDirective {
1498
1526
  validate() {
1499
1527
  return !this.injected && !!this.injectedArgs.length;
1500
1528
  }
1501
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtArgs, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1502
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.1", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: "args" }, providers: [provideNodeType('args')], usesInheritance: true, ngImport: i0 }); }
1529
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtArgs, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1530
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.9", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: { classPropertyName: "args", publicName: "args", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideNodeType('args')], usesInheritance: true, ngImport: i0 }); }
1503
1531
  }
1504
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtArgs, decorators: [{
1532
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtArgs, decorators: [{
1505
1533
  type: Directive,
1506
1534
  args: [{ selector: 'ng-template[args]', standalone: true, providers: [provideNodeType('args')] }]
1507
- }], propDecorators: { args: [{
1508
- type: Input
1509
- }] } });
1535
+ }], ctorParameters: () => [] });
1510
1536
 
1511
1537
  class NgtParent extends NgtCommonDirective {
1512
1538
  constructor() {
1513
- super(...arguments);
1539
+ super();
1540
+ this.parent = input.required();
1514
1541
  this.injectedParent = null;
1542
+ effect(() => {
1543
+ const parent = this.parent();
1544
+ if (!parent)
1545
+ return;
1546
+ this.injected = false;
1547
+ this.injectedParent = parent;
1548
+ this.createView();
1549
+ });
1515
1550
  }
1516
- set parent(parent) {
1517
- if (!parent)
1518
- return;
1519
- this.injected = false;
1520
- this.injectedParent = parent;
1521
- this.createView();
1522
- }
1523
- get parent() {
1551
+ get value() {
1524
1552
  if (this.validate()) {
1525
1553
  this.injected = true;
1526
1554
  return this.injectedParent;
@@ -1530,15 +1558,13 @@ class NgtParent extends NgtCommonDirective {
1530
1558
  validate() {
1531
1559
  return !this.injected && !!this.injectedParent;
1532
1560
  }
1533
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtParent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1534
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.1", type: NgtParent, isStandalone: true, selector: "ng-template[parent]", inputs: { parent: "parent" }, providers: [provideNodeType('parent')], usesInheritance: true, ngImport: i0 }); }
1561
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtParent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1562
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "17.3.9", type: NgtParent, isStandalone: true, selector: "ng-template[parent]", inputs: { parent: { classPropertyName: "parent", publicName: "parent", isSignal: true, isRequired: true, transformFunction: null } }, providers: [provideNodeType('parent')], usesInheritance: true, ngImport: i0 }); }
1535
1563
  }
1536
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtParent, decorators: [{
1564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtParent, decorators: [{
1537
1565
  type: Directive,
1538
1566
  args: [{ selector: 'ng-template[parent]', standalone: true, providers: [provideNodeType('parent')] }]
1539
- }], propDecorators: { parent: [{
1540
- type: Input
1541
- }] } });
1567
+ }], ctorParameters: () => [] });
1542
1568
 
1543
1569
  function attach(object, value, paths = []) {
1544
1570
  const [base, ...remaining] = paths;
@@ -1670,7 +1696,7 @@ function attachThreeChild(parent, child) {
1670
1696
  cLS.setParent(parent);
1671
1697
  }
1672
1698
  if (cLS.afterAttach)
1673
- cLS.afterAttach.emit({ parent, node: child });
1699
+ cLS.afterAttach.next({ parent, node: child });
1674
1700
  invalidateInstance(child);
1675
1701
  invalidateInstance(parent);
1676
1702
  }
@@ -1720,9 +1746,19 @@ function processThreeEvent(instance, priority, eventName, callback) {
1720
1746
  if (eventName === SPECIAL_EVENTS.AFTER_UPDATE || eventName === SPECIAL_EVENTS.AFTER_ATTACH) {
1721
1747
  let emitter = lS[eventName];
1722
1748
  if (!emitter)
1723
- emitter = lS[eventName] = new EventEmitter();
1749
+ emitter = lS[eventName] = new ReplaySubject(1);
1724
1750
  const sub = emitter.subscribe(callback);
1725
- return sub.unsubscribe.bind(sub);
1751
+ // NOTE: for afterAttach event, if the instance already has a parent,
1752
+ // then we'll emit the event immediately
1753
+ if (eventName === SPECIAL_EVENTS.AFTER_ATTACH && untracked(lS.parent)) {
1754
+ emitter.next({ parent: untracked(lS.parent), node: instance });
1755
+ }
1756
+ return () => {
1757
+ sub.unsubscribe();
1758
+ if (emitter && !emitter.observed) {
1759
+ emitter.complete();
1760
+ }
1761
+ };
1726
1762
  }
1727
1763
  if (!lS.handlers)
1728
1764
  lS.handlers = {};
@@ -1872,8 +1908,8 @@ class NgtRendererStore {
1872
1908
  }
1873
1909
  getCreationState() {
1874
1910
  return [
1875
- this.firstNonInjectedDirective('argsCommentNodes', NgtArgs)?.args || [],
1876
- this.firstNonInjectedDirective('parentCommentNodes', NgtParent)?.parent || null,
1911
+ this.firstNonInjectedDirective('argsCommentNodes', NgtArgs)?.value || [],
1912
+ this.firstNonInjectedDirective('parentCommentNodes', NgtParent)?.value || null,
1877
1913
  this.tryGetPortalStore(),
1878
1914
  ];
1879
1915
  }
@@ -2009,6 +2045,12 @@ class NgtRendererStore {
2009
2045
  value = compound[NgtCompoundClassId.props][name];
2010
2046
  }
2011
2047
  applyProps(node, { [name]: value });
2048
+ // NOTE: special case for Geometry and Material
2049
+ if (value && (name === 'geometry' || name === 'material')) {
2050
+ const childLS = getLocalState(value);
2051
+ childLS?.setParent(node);
2052
+ localState?.add(value, 'nonObjects');
2053
+ }
2012
2054
  this.updateNativeProps(node, name, value);
2013
2055
  }
2014
2056
  get rootScene() {
@@ -2195,10 +2237,10 @@ class NgtRendererFactory {
2195
2237
  }
2196
2238
  return renderer;
2197
2239
  }
2198
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2199
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtRendererFactory }); }
2240
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2241
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtRendererFactory }); }
2200
2242
  }
2201
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtRendererFactory, decorators: [{
2243
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtRendererFactory, decorators: [{
2202
2244
  type: Injectable
2203
2245
  }] });
2204
2246
  class NgtRenderer {
@@ -2566,24 +2608,18 @@ function provideNgtRenderer(store, compoundPrefixes) {
2566
2608
  }
2567
2609
 
2568
2610
  class NgtCanvas {
2569
- set _sceneGraphInputs(value) {
2570
- this.sceneGraphInputs.set(value);
2571
- }
2572
- set _canvasInputs(value) {
2573
- this.canvasInputs.update(value);
2574
- }
2575
2611
  constructor() {
2576
2612
  this.store = injectNgtStore();
2577
2613
  this.initRoot = injectCanvasRootInitializer();
2578
2614
  this.autoEffect = injectAutoEffect();
2579
2615
  this.host = inject(ElementRef);
2580
- this.viewContainerRef = inject(ViewContainerRef);
2581
2616
  this.zone = inject(NgZone);
2582
2617
  this.environmentInjector = inject(EnvironmentInjector);
2583
2618
  this.injector = inject(Injector);
2584
- this.compoundPrefixes = [];
2585
- this.sceneGraphInputs = signal({}, { equal: Object.is });
2586
- this.canvasInputs = signalStore({
2619
+ this.sceneGraph = input.required();
2620
+ this.compoundPrefixes = input([]);
2621
+ this.sceneGraphInputs = input({});
2622
+ this.options = input({
2587
2623
  shadows: false,
2588
2624
  linear: false,
2589
2625
  flat: false,
@@ -2594,13 +2630,15 @@ class NgtCanvas {
2594
2630
  events: createPointerEvents,
2595
2631
  });
2596
2632
  this.created = new EventEmitter();
2633
+ this.glCanvas = viewChild.required('glCanvas');
2634
+ this.glCanvasViewContainerRef = viewChild.required('glCanvas', { read: ViewContainerRef });
2597
2635
  // NOTE: this signal is updated outside of Zone
2598
2636
  this.resizeResult = signal({}, { equal: Object.is });
2599
- this.eventSource = this.canvasInputs.select('eventSource');
2637
+ this.eventSource = computed(() => this.options().eventSource);
2600
2638
  this.hbPointerEvents = computed(() => (this.eventSource() ? 'none' : 'auto'));
2601
2639
  afterNextRender(() => {
2602
2640
  this.zone.runOutsideAngular(() => {
2603
- this.configurator = this.initRoot(this.glCanvas.nativeElement);
2641
+ this.configurator = this.initRoot(this.glCanvas().nativeElement);
2604
2642
  this.noZoneResizeEffect();
2605
2643
  this.noZoneSceneGraphInputsEffect();
2606
2644
  });
@@ -2616,8 +2654,8 @@ class NgtCanvas {
2616
2654
  const resizeResult = this.resizeResult();
2617
2655
  if (resizeResult.width > 0 && resizeResult.height > 0) {
2618
2656
  if (!this.configurator)
2619
- this.configurator = this.initRoot(this.glCanvas.nativeElement);
2620
- this.configurator.configure({ ...this.canvasInputs.state(), size: resizeResult });
2657
+ this.configurator = this.initRoot(this.glCanvas().nativeElement);
2658
+ this.configurator.configure({ ...this.options(), size: resizeResult });
2621
2659
  untracked(() => {
2622
2660
  if (this.glRef) {
2623
2661
  this.glRef.changeDetectorRef.detectChanges();
@@ -2635,7 +2673,7 @@ class NgtCanvas {
2635
2673
  this.glRef?.destroy();
2636
2674
  // NOTE: Flag the canvas active, rendering will now begin
2637
2675
  this.store.update((state) => ({ internal: { ...state.internal, active: true } }));
2638
- const [inputs, state] = [this.canvasInputs.snapshot, this.store.snapshot];
2676
+ const [inputs, state] = [untracked(this.options), this.store.snapshot];
2639
2677
  // connect to event source
2640
2678
  state.events.connect?.(inputs.eventSource
2641
2679
  ? is.ref(inputs.eventSource)
@@ -2659,10 +2697,10 @@ class NgtCanvas {
2659
2697
  this.created.emit(this.store.snapshot);
2660
2698
  }
2661
2699
  if (!this.store.get('events', 'connected')) {
2662
- this.store.get('events').connect?.(this.glCanvas.nativeElement);
2700
+ this.store.get('events').connect?.(this.glCanvas().nativeElement);
2663
2701
  }
2664
- this.glEnvironmentInjector = createEnvironmentInjector([provideNgtRenderer(this.store, this.compoundPrefixes)], this.environmentInjector);
2665
- this.glRef = this.viewContainerRef.createComponent(this.sceneGraph, {
2702
+ this.glEnvironmentInjector = createEnvironmentInjector([provideNgtRenderer(this.store, untracked(this.compoundPrefixes))], this.environmentInjector);
2703
+ this.glRef = untracked(this.glCanvasViewContainerRef).createComponent(untracked(this.sceneGraph), {
2666
2704
  environmentInjector: this.glEnvironmentInjector,
2667
2705
  injector: this.injector,
2668
2706
  });
@@ -2681,17 +2719,17 @@ class NgtCanvas {
2681
2719
  }
2682
2720
  }
2683
2721
  }
2684
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2685
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.1", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: "sceneGraph", compoundPrefixes: "compoundPrefixes", _sceneGraphInputs: ["sceneGraphInputs", "_sceneGraphInputs"], _canvasInputs: ["options", "_canvasInputs"] }, outputs: { created: "created" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
2722
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2723
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "17.3.9", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: { classPropertyName: "sceneGraph", publicName: "sceneGraph", isSignal: true, isRequired: true, transformFunction: null }, compoundPrefixes: { classPropertyName: "compoundPrefixes", publicName: "compoundPrefixes", isSignal: true, isRequired: false, transformFunction: null }, sceneGraphInputs: { classPropertyName: "sceneGraphInputs", publicName: "sceneGraphInputs", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { created: "created" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
2686
2724
  provideResizeOptions({ emitInZone: false, emitInitialResult: true, debounce: 250 }),
2687
2725
  provideNgtStore(),
2688
- ], viewQueries: [{ propertyName: "glCanvas", first: true, predicate: ["glCanvas"], descendants: true, static: true }], ngImport: i0, template: `
2726
+ ], viewQueries: [{ propertyName: "glCanvas", first: true, predicate: ["glCanvas"], descendants: true, isSignal: true }, { propertyName: "glCanvasViewContainerRef", first: true, predicate: ["glCanvas"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
2689
2727
  <div (ngxResize)="resizeResult.set($event)" style="height: 100%; width: 100%;">
2690
2728
  <canvas #glCanvas style="display: block;"></canvas>
2691
2729
  </div>
2692
2730
  `, isInline: true, dependencies: [{ kind: "directive", type: NgxResize, selector: "[ngxResize]", inputs: ["ngxResizeOptions"], outputs: ["ngxResize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2693
2731
  }
2694
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtCanvas, decorators: [{
2732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtCanvas, decorators: [{
2695
2733
  type: Component,
2696
2734
  args: [{
2697
2735
  selector: 'ngt-canvas',
@@ -2712,22 +2750,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImpor
2712
2750
  },
2713
2751
  changeDetection: ChangeDetectionStrategy.OnPush,
2714
2752
  }]
2715
- }], ctorParameters: () => [], propDecorators: { sceneGraph: [{
2716
- type: Input,
2717
- args: [{ required: true }]
2718
- }], compoundPrefixes: [{
2719
- type: Input
2720
- }], _sceneGraphInputs: [{
2721
- type: Input,
2722
- args: [{ alias: 'sceneGraphInputs' }]
2723
- }], _canvasInputs: [{
2724
- type: Input,
2725
- args: [{ alias: 'options' }]
2726
- }], created: [{
2753
+ }], ctorParameters: () => [], propDecorators: { created: [{
2727
2754
  type: Output
2728
- }], glCanvas: [{
2729
- type: ViewChild,
2730
- args: ['glCanvas', { static: true }]
2731
2755
  }] } });
2732
2756
 
2733
2757
  const cached = new Map();
@@ -2874,16 +2898,18 @@ class NgtPortalBeforeRender {
2874
2898
  constructor() {
2875
2899
  this.portalStore = injectNgtStore();
2876
2900
  this.injector = inject(Injector);
2877
- this.renderPriority = 1;
2901
+ this.renderPriority = input(1);
2902
+ this.parentScene = input.required();
2903
+ this.parentCamera = input.required();
2878
2904
  afterNextRender(() => {
2879
2905
  let oldClear;
2880
2906
  injectBeforeRender(() => {
2881
2907
  const { gl, scene, camera } = this.portalStore.get();
2882
2908
  oldClear = gl.autoClear;
2883
- if (this.renderPriority === 1) {
2909
+ if (this.renderPriority() === 1) {
2884
2910
  // clear scene and render with default
2885
2911
  gl.autoClear = true;
2886
- gl.render(this.parentScene, this.parentCamera);
2912
+ gl.render(this.parentScene(), this.parentCamera());
2887
2913
  }
2888
2914
  // disable cleaning
2889
2915
  gl.autoClear = false;
@@ -2891,19 +2917,19 @@ class NgtPortalBeforeRender {
2891
2917
  gl.render(scene, camera);
2892
2918
  // restore
2893
2919
  gl.autoClear = oldClear;
2894
- }, { priority: this.renderPriority, injector: this.injector });
2920
+ }, { priority: this.renderPriority(), injector: this.injector });
2895
2921
  });
2896
2922
  }
2897
2923
  onPointerOver() {
2898
2924
  /* noop */
2899
2925
  }
2900
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2901
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.1", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: "renderPriority", parentScene: "parentScene", parentCamera: "parentCamera" }, ngImport: i0, template: `
2926
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2927
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "17.3.9", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: { classPropertyName: "renderPriority", publicName: "renderPriority", isSignal: true, isRequired: false, transformFunction: null }, parentScene: { classPropertyName: "parentScene", publicName: "parentScene", isSignal: true, isRequired: true, transformFunction: null }, parentCamera: { classPropertyName: "parentCamera", publicName: "parentCamera", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
2902
2928
  <!-- Without an element that receives pointer events state.pointer will always be 0/0 -->
2903
2929
  <ngt-group (pointerover)="onPointerOver()" attach="none" />
2904
2930
  `, isInline: true }); }
2905
2931
  }
2906
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
2932
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
2907
2933
  type: Component,
2908
2934
  args: [{
2909
2935
  selector: 'ngt-portal-before-render',
@@ -2914,15 +2940,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImpor
2914
2940
  `,
2915
2941
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
2916
2942
  }]
2917
- }], ctorParameters: () => [], propDecorators: { renderPriority: [{
2918
- type: Input
2919
- }], parentScene: [{
2920
- type: Input,
2921
- args: [{ required: true }]
2922
- }], parentCamera: [{
2923
- type: Input,
2924
- args: [{ required: true }]
2925
- }] } });
2943
+ }], ctorParameters: () => [] });
2926
2944
  class NgtPortalContent {
2927
2945
  constructor(vcr, parentVcr) {
2928
2946
  const commentNode = vcr.element.nativeElement;
@@ -2931,28 +2949,24 @@ class NgtPortalContent {
2931
2949
  delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
2932
2950
  }
2933
2951
  }
2934
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtPortalContent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ViewContainerRef, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }
2935
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.1", type: NgtPortalContent, isStandalone: true, selector: "ng-template[ngtPortalContent]", ngImport: i0 }); }
2952
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtPortalContent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ViewContainerRef, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }
2953
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.9", type: NgtPortalContent, isStandalone: true, selector: "ng-template[ngtPortalContent]", ngImport: i0 }); }
2936
2954
  }
2937
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtPortalContent, decorators: [{
2955
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtPortalContent, decorators: [{
2938
2956
  type: Directive,
2939
2957
  args: [{ selector: 'ng-template[ngtPortalContent]', standalone: true }]
2940
2958
  }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ViewContainerRef, decorators: [{
2941
2959
  type: SkipSelf
2942
2960
  }] }] });
2943
2961
  class NgtPortal {
2944
- set _portalInputs(value) {
2945
- this.portalInputs.update(value);
2946
- }
2947
- set _autoRender(value) {
2948
- this.autoRender.set(value);
2949
- }
2950
2962
  constructor() {
2951
- this.portalInputs = signalStore({
2963
+ this.options = input({
2952
2964
  container: injectNgtRef(prepare(new THREE.Scene())),
2953
2965
  });
2954
- this.autoRender = signal(false);
2955
- this.autoRenderPriority = 1;
2966
+ this.autoRender = input(false);
2967
+ this.autoRenderPriority = input(1);
2968
+ this.portalContentTemplate = contentChild.required(NgtPortalContent, { read: TemplateRef });
2969
+ this.portalContentAnchor = viewChild.required('portalContentAnchor', { read: ViewContainerRef });
2956
2970
  this.destroyRef = inject(DestroyRef);
2957
2971
  this.autoEffect = injectAutoEffect();
2958
2972
  this.parentStore = injectNgtStore({ skipSelf: true });
@@ -2963,7 +2977,7 @@ class NgtPortal {
2963
2977
  this.parentCamera = this.parentStore.get('camera');
2964
2978
  afterNextRender(() => {
2965
2979
  const parentState = this.parentStore.snapshot;
2966
- const { container, state: { events = {}, size = {}, ...rest }, } = this.portalInputs.snapshot;
2980
+ const { container, state: { events = {}, size = {}, ...rest } = {} } = untracked(this.options);
2967
2981
  this.portalStore.update({
2968
2982
  scene: (is.ref(container) ? container.nativeElement : container),
2969
2983
  events: { ...parentState.events, ...events },
@@ -2975,7 +2989,7 @@ class NgtPortal {
2975
2989
  this.portalStore.update((state) => this.inject(previous, state));
2976
2990
  });
2977
2991
  untracked(() => {
2978
- const portalView = this.portalContentAnchor.createEmbeddedView(this.portalContentTemplate);
2992
+ const portalView = this.portalContentAnchor().createEmbeddedView(this.portalContentTemplate());
2979
2993
  portalView.detectChanges();
2980
2994
  this.destroyRef.onDestroy(portalView.destroy.bind(portalView));
2981
2995
  });
@@ -2990,7 +3004,7 @@ class NgtPortal {
2990
3004
  delete intersect[key];
2991
3005
  }
2992
3006
  });
2993
- const inputs = this.portalInputs.snapshot;
3007
+ const inputs = untracked(this.options);
2994
3008
  const { size, events, ...restInputsState } = inputs.state || {};
2995
3009
  let viewport = undefined;
2996
3010
  if (injectState && size) {
@@ -3009,12 +3023,12 @@ class NgtPortal {
3009
3023
  ...restInputsState,
3010
3024
  };
3011
3025
  }
3012
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3013
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.1", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { _portalInputs: ["options", "_portalInputs"], _autoRender: ["autoRender", "_autoRender"], autoRenderPriority: "autoRenderPriority" }, providers: [providePortalStore()], queries: [{ propertyName: "portalContentTemplate", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "portalContentAnchor", first: true, predicate: ["portalContentAnchor"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
3026
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3027
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.9", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, autoRender: { classPropertyName: "autoRender", publicName: "autoRender", isSignal: true, isRequired: false, transformFunction: null }, autoRenderPriority: { classPropertyName: "autoRenderPriority", publicName: "autoRenderPriority", isSignal: true, isRequired: false, transformFunction: null } }, providers: [providePortalStore()], queries: [{ propertyName: "portalContentTemplate", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "portalContentAnchor", first: true, predicate: ["portalContentAnchor"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
3014
3028
  <ng-container #portalContentAnchor>
3015
3029
  @if (renderAutoBeforeRender()) {
3016
3030
  <ngt-portal-before-render
3017
- [renderPriority]="autoRenderPriority"
3031
+ [renderPriority]="autoRenderPriority()"
3018
3032
  [parentScene]="parentScene"
3019
3033
  [parentCamera]="parentCamera"
3020
3034
  />
@@ -3022,7 +3036,7 @@ class NgtPortal {
3022
3036
  </ng-container>
3023
3037
  `, isInline: true, dependencies: [{ kind: "component", type: NgtPortalBeforeRender, selector: "ngt-portal-before-render", inputs: ["renderPriority", "parentScene", "parentCamera"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3024
3038
  }
3025
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtPortal, decorators: [{
3039
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtPortal, decorators: [{
3026
3040
  type: Component,
3027
3041
  args: [{
3028
3042
  selector: 'ngt-portal',
@@ -3031,7 +3045,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImpor
3031
3045
  <ng-container #portalContentAnchor>
3032
3046
  @if (renderAutoBeforeRender()) {
3033
3047
  <ngt-portal-before-render
3034
- [renderPriority]="autoRenderPriority"
3048
+ [renderPriority]="autoRenderPriority()"
3035
3049
  [parentScene]="parentScene"
3036
3050
  [parentCamera]="parentCamera"
3037
3051
  />
@@ -3042,21 +3056,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImpor
3042
3056
  providers: [providePortalStore()],
3043
3057
  changeDetection: ChangeDetectionStrategy.OnPush,
3044
3058
  }]
3045
- }], ctorParameters: () => [], propDecorators: { _portalInputs: [{
3046
- type: Input,
3047
- args: [{ alias: 'options' }]
3048
- }], _autoRender: [{
3049
- type: Input,
3050
- args: [{ alias: 'autoRender' }]
3051
- }], autoRenderPriority: [{
3052
- type: Input
3053
- }], portalContentTemplate: [{
3054
- type: ContentChild,
3055
- args: [NgtPortalContent, { read: TemplateRef, static: true }]
3056
- }], portalContentAnchor: [{
3057
- type: ViewChild,
3058
- args: ['portalContentAnchor', { read: ViewContainerRef, static: true }]
3059
- }] } });
3059
+ }], ctorParameters: () => [] });
3060
3060
 
3061
3061
  var _a;
3062
3062
  class NgtRoutedScene {
@@ -3067,12 +3067,12 @@ class NgtRoutedScene {
3067
3067
  .pipe(filter((event) => event instanceof ActivationEnd), takeUntilDestroyed())
3068
3068
  .subscribe(cdr.detectChanges.bind(cdr));
3069
3069
  }
3070
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3071
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.1", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
3070
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3071
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
3072
3072
  <router-outlet />
3073
3073
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); }
3074
3074
  }
3075
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NgtRoutedScene, decorators: [{
3075
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: NgtRoutedScene, decorators: [{
3076
3076
  type: Component,
3077
3077
  args: [{
3078
3078
  standalone: true,
@@ -3084,28 +3084,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImpor
3084
3084
  }]
3085
3085
  }], ctorParameters: () => [{ type: i1.Router }, { type: i0.ChangeDetectorRef }] });
3086
3086
 
3087
- // TODO: use scheduler instead of force CD
3088
- function cdAwareSignal(initialValue, { injector, ...options } = {}) {
3089
- return assertInjector(cdAwareSignal, injector, () => {
3090
- if (!options.equal) {
3091
- options.equal = Object.is;
3092
- }
3093
- const cdr = inject(ChangeDetectorRef);
3094
- const source = signal(initialValue, options);
3095
- const originalSet = source.set.bind(source);
3096
- const originalUpdate = source.update.bind(source);
3097
- source.set = (...args) => {
3098
- originalSet(...args);
3099
- cdr.detectChanges();
3100
- };
3101
- source.update = (...args) => {
3102
- originalUpdate(...args);
3103
- cdr.detectChanges();
3104
- };
3105
- return source;
3106
- });
3107
- }
3108
-
3109
3087
  function apiFactory(obj) {
3110
3088
  return obj.api;
3111
3089
  }
@@ -3121,5 +3099,5 @@ function createApiToken(forwardedObject) {
3121
3099
  * Generated bundle index. Do not edit.
3122
3100
  */
3123
3101
 
3124
- export { HTML, NGT_STORE, NgtArgs, NgtCanvas, NgtPortal, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, cdAwareSignal, checkNeedsUpdate, checkUpdate, createApiToken, createAttachFunction, extend, getLocalState, injectBeforeRender, injectNgtLoader, injectNgtRef, injectNgtStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, prepare, provideNgtRenderer, provideNgtStore, signalStore, updateCamera };
3102
+ export { HTML, NGT_STORE, NgtArgs, NgtCanvas, NgtPortal, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, checkNeedsUpdate, checkUpdate, createApiToken, createAttachFunction, extend, getLocalState, injectBeforeRender, injectNgtLoader, injectNgtRef, injectNgtStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, prepare, provideNgtRenderer, provideNgtStore, signalStore, updateCamera };
3125
3103
  //# sourceMappingURL=angular-three.mjs.map