angular-three 1.0.0-beta.9 → 1.0.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.
@@ -1,11 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ElementRef, Injectable, inject, InjectionToken, ViewContainerRef, TemplateRef, Directive, Input, EventEmitter, getDebugNode, ChangeDetectorRef, RendererFactory2, EnvironmentInjector, createEnvironmentInjector, Component, HostBinding, Output, ViewChild, Pipe } from '@angular/core';
2
+ import { ElementRef, Injectable, inject, InjectionToken, ViewContainerRef, TemplateRef, Directive, Input, EventEmitter, getDebugNode, ChangeDetectorRef, RendererFactory2, EnvironmentInjector, createEnvironmentInjector, Component, HostBinding, Output, ViewChild, Pipe, SkipSelf, ContentChild } from '@angular/core';
3
3
  import { provideNgxResizeOptions, NgxResize } from 'ngx-resize';
4
4
  import { isObservable, of, map, from, tap, retry, catchError, share, ReplaySubject, switchMap, forkJoin, take, BehaviorSubject, startWith, filter, distinctUntilChanged, takeUntil, merge } from 'rxjs';
5
5
  import * as THREE from 'three';
6
- import { DOCUMENT, NgForOf } from '@angular/common';
6
+ import { DOCUMENT, NgForOf, NgIf } from '@angular/common';
7
7
  import { RxState, selectSlice } from '@rx-angular/state';
8
8
  import { ɵDomRendererFactory2 } from '@angular/platform-browser';
9
+ import { __classPrivateFieldGet } from 'tslib';
9
10
 
10
11
  const idCache = {};
11
12
  function makeId(event) {
@@ -342,7 +343,7 @@ function invalidateInstance(instance) {
342
343
  checkUpdate(instance);
343
344
  }
344
345
  function prepare(object, localState) {
345
- const instance = object;
346
+ const instance = (typeof object === 'function' ? object() : object);
346
347
  if (localState?.primitive || !instance.__ngt__) {
347
348
  const { objects = new BehaviorSubject([]), nonObjects = new BehaviorSubject([]), ...rest } = localState || {};
348
349
  instance.__ngt__ = {
@@ -355,7 +356,15 @@ function prepare(object, localState) {
355
356
  objects,
356
357
  nonObjects,
357
358
  add: (object, type) => {
358
- instance.__ngt__[type].next([...instance.__ngt__[type].value, object]);
359
+ const current = instance.__ngt__[type].value;
360
+ const foundIndex = current.indexOf((obj) => obj === object);
361
+ if (foundIndex > -1) {
362
+ current.splice(foundIndex, 1, object);
363
+ instance.__ngt__[type].next(current);
364
+ }
365
+ else {
366
+ instance.__ngt__[type].next([...instance.__ngt__[type].value, object]);
367
+ }
359
368
  notifyAncestors(instance.__ngt__.parent);
360
369
  },
361
370
  remove: (object, type) => {
@@ -840,7 +849,7 @@ class NgtStore extends NgtRxStore {
840
849
  // Safely set color management if available.
841
850
  // Avoid accessing THREE.ColorManagement to play nice with older versions
842
851
  if (THREE.ColorManagement)
843
- THREE.ColorManagement.legacyMode = state.legacy;
852
+ THREE.ColorManagement.legacyMode = legacy ?? true;
844
853
  const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
845
854
  const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
846
855
  if (gl.outputEncoding !== outputEncoding)
@@ -1353,6 +1362,9 @@ function assignEmpty(obj, base) {
1353
1362
  obj[base] = {};
1354
1363
  }
1355
1364
  }
1365
+ function createAttachFunction(cb) {
1366
+ return (parent, child, store) => cb({ parent, child, store });
1367
+ }
1356
1368
 
1357
1369
  const SPECIAL_DOM_TAG = {
1358
1370
  NGT_PORTAL: 'ngt-portal',
@@ -1456,7 +1468,7 @@ function removeThreeChild(parent, child, dispose) {
1456
1468
  removeThreeRecursive(child.childre, child, !!dispose);
1457
1469
  }
1458
1470
  // dispose
1459
- if (child['dispose'] && !is.scene(child)) {
1471
+ if (!isPrimitive && child['dispose'] && !is.scene(child)) {
1460
1472
  queueMicrotask(() => child['dispose']());
1461
1473
  }
1462
1474
  invalidateInstance(parent);
@@ -1554,14 +1566,18 @@ class NgtRendererStore {
1554
1566
  state[13 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(rendererNode).injector;
1555
1567
  // we attach an arrow function to the Comment node
1556
1568
  // In our directives, we can call this function to then start tracking the RendererNode
1557
- rendererNode['__ngt_renderer_add_comment__'] = () => {
1558
- this.comments.push(rendererNode);
1569
+ rendererNode['__ngt_renderer_add_comment__'] = (portalNode) => {
1570
+ if (portalNode && portalNode.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'portal') {
1571
+ this.portals.push(portalNode);
1572
+ }
1573
+ else {
1574
+ this.comments.push(rendererNode);
1575
+ }
1559
1576
  };
1560
1577
  return rendererNode;
1561
1578
  }
1562
1579
  if (state[0 /* NgtRendererClassId.type */] === 'portal') {
1563
1580
  state[13 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(rendererNode).injector;
1564
- this.portals.push(rendererNode);
1565
1581
  return rendererNode;
1566
1582
  }
1567
1583
  if (state[0 /* NgtRendererClassId.type */] === 'compound') {
@@ -1674,6 +1690,7 @@ class NgtRendererStore {
1674
1690
  if (node.__ngt_renderer__[3 /* NgtRendererClassId.destroyed */])
1675
1691
  return;
1676
1692
  // setup [ref] here
1693
+ // ref should never change
1677
1694
  if (name === SPECIAL_PROPERTIES.REF && is.ref(value)) {
1678
1695
  node.__ngt_renderer__[11 /* NgtRendererClassId.ref */] = value;
1679
1696
  value.nativeElement = node;
@@ -1859,7 +1876,8 @@ class NgtRendererStore {
1859
1876
  continue;
1860
1877
  }
1861
1878
  const instance = injector.get(NgtStore, null);
1862
- if (instance) {
1879
+ // only the instance with previousStore should pass
1880
+ if (instance && instance.get('previousStore')) {
1863
1881
  store = instance;
1864
1882
  break;
1865
1883
  }
@@ -2626,9 +2644,239 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
2626
2644
  args: [{ name: 'ngtPush', pure: false, standalone: true }]
2627
2645
  }] });
2628
2646
 
2647
+ var _NgtPortal_instances, _NgtPortal_inject;
2648
+ const privateKeys = [
2649
+ 'get',
2650
+ 'set',
2651
+ 'select',
2652
+ 'setSize',
2653
+ 'setDpr',
2654
+ 'setFrameloop',
2655
+ 'events',
2656
+ 'invalidate',
2657
+ 'advance',
2658
+ 'size',
2659
+ 'viewport',
2660
+ 'addInteraction',
2661
+ 'removeInteraction',
2662
+ ];
2663
+ class NgtPortalBeforeRender {
2664
+ constructor() {
2665
+ this.portalStore = inject(NgtStore);
2666
+ this.renderPriority = 1;
2667
+ this.beforeRender = new EventEmitter();
2668
+ }
2669
+ ngOnInit() {
2670
+ let oldClear;
2671
+ this.subscription = this.portalStore.get('internal').subscribe(({ delta, frame }) => {
2672
+ this.beforeRender.emit({ ...this.portalStore.get(), delta, frame });
2673
+ const { gl, scene, camera } = this.portalStore.get();
2674
+ oldClear = gl.autoClear;
2675
+ if (this.renderPriority === 1) {
2676
+ // clear scene and render with default
2677
+ gl.autoClear = true;
2678
+ gl.render(this.parentScene, this.parentCamera);
2679
+ }
2680
+ // disable cleaning
2681
+ gl.autoClear = false;
2682
+ gl.clearDepth();
2683
+ gl.render(scene, camera);
2684
+ // restore
2685
+ gl.autoClear = oldClear;
2686
+ }, this.renderPriority, this.portalStore);
2687
+ }
2688
+ ngOnDestroy() {
2689
+ this.subscription?.();
2690
+ }
2691
+ }
2692
+ NgtPortalBeforeRender.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2693
+ NgtPortalBeforeRender.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.1", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: "renderPriority", parentScene: "parentScene", parentCamera: "parentCamera" }, outputs: { beforeRender: "beforeRender" }, ngImport: i0 });
2694
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
2695
+ type: Directive,
2696
+ args: [{
2697
+ selector: 'ngt-portal-before-render',
2698
+ standalone: true,
2699
+ }]
2700
+ }], propDecorators: { renderPriority: [{
2701
+ type: Input
2702
+ }], parentScene: [{
2703
+ type: Input
2704
+ }], parentCamera: [{
2705
+ type: Input
2706
+ }], beforeRender: [{
2707
+ type: Output
2708
+ }] } });
2709
+ class NgtPortalContent {
2710
+ constructor(vcr, parentVcr) {
2711
+ const commentNode = vcr.element.nativeElement;
2712
+ if (commentNode['__ngt_renderer_add_comment__']) {
2713
+ commentNode['__ngt_renderer_add_comment__'](parentVcr.element.nativeElement);
2714
+ delete commentNode['__ngt_renderer_add_comment__'];
2715
+ }
2716
+ }
2717
+ }
2718
+ NgtPortalContent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalContent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ViewContainerRef, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive });
2719
+ NgtPortalContent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.1", type: NgtPortalContent, isStandalone: true, selector: "ng-template[ngtPortalContent]", ngImport: i0 });
2720
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalContent, decorators: [{
2721
+ type: Directive,
2722
+ args: [{ selector: 'ng-template[ngtPortalContent]', standalone: true }]
2723
+ }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ViewContainerRef, decorators: [{
2724
+ type: SkipSelf
2725
+ }] }]; } });
2726
+ class NgtPortal extends NgtRxStore {
2727
+ constructor() {
2728
+ super(...arguments);
2729
+ _NgtPortal_instances.add(this);
2730
+ this.autoRender = true;
2731
+ this.autoRenderPriority = 1;
2732
+ this.beforeRender = new EventEmitter();
2733
+ this.parentStore = inject(NgtStore, { skipSelf: true });
2734
+ this.parentScene = this.parentStore.get('scene');
2735
+ this.parentCamera = this.parentStore.get('camera');
2736
+ this.portalStore = inject(NgtStore, { self: true });
2737
+ this.raycaster = new THREE.Raycaster();
2738
+ this.pointer = new THREE.Vector2();
2739
+ this.portalContentRendered = false;
2740
+ }
2741
+ set container(container) {
2742
+ this.set({ container });
2743
+ }
2744
+ set state(state) {
2745
+ this.set({ state });
2746
+ }
2747
+ initialize() {
2748
+ super.initialize();
2749
+ this.set({ container: injectNgtRef(prepare(new THREE.Scene())) });
2750
+ }
2751
+ ngOnInit() {
2752
+ const previousState = this.parentStore.get();
2753
+ const inputsState = this.get();
2754
+ if (!inputsState.state && this.autoRender) {
2755
+ inputsState.state = { events: { priority: this.autoRenderPriority + 1 } };
2756
+ }
2757
+ const { events, size, ...restInputsState } = inputsState.state || {};
2758
+ const containerState = inputsState.container;
2759
+ const container = is.ref(containerState) ? containerState.nativeElement : containerState;
2760
+ const localState = getLocalState(container);
2761
+ if (!localState.store) {
2762
+ localState.store = this.portalStore;
2763
+ }
2764
+ this.portalStore.set({
2765
+ ...previousState,
2766
+ scene: container,
2767
+ raycaster: this.raycaster,
2768
+ pointer: this.pointer,
2769
+ previousStore: this.parentStore,
2770
+ events: { ...previousState.events, ...(events || {}) },
2771
+ size: { ...previousState.size, ...(size || {}) },
2772
+ ...restInputsState,
2773
+ get: this.portalStore.get.bind(this.portalStore),
2774
+ set: this.portalStore.set.bind(this.portalStore),
2775
+ select: this.portalStore.select.bind(this.portalStore),
2776
+ setEvents: (events) => this.portalStore.set((state) => ({ ...state, events: { ...state.events, ...events } })),
2777
+ });
2778
+ this.hold(this.parentStore.select(), (previous) => this.portalStore.set((state) => __classPrivateFieldGet(this, _NgtPortal_instances, "m", _NgtPortal_inject).call(this, previous, state)));
2779
+ requestAnimationFrame(() => {
2780
+ this.portalStore.set((injectState) => __classPrivateFieldGet(this, _NgtPortal_instances, "m", _NgtPortal_inject).call(this, this.parentStore.get(), injectState));
2781
+ });
2782
+ this.portalContentView = this.portalContentAnchor.createEmbeddedView(this.portalContentTemplate);
2783
+ this.portalContentView.detectChanges();
2784
+ this.portalContentRendered = true;
2785
+ }
2786
+ onBeforeRender(portal) {
2787
+ this.beforeRender.emit({
2788
+ root: { ...this.parentStore.get(), delta: portal.delta, frame: portal.frame },
2789
+ portal,
2790
+ });
2791
+ }
2792
+ ngOnDestroy() {
2793
+ if (this.portalContentView && !this.portalContentView.destroyed) {
2794
+ this.portalContentView.destroy();
2795
+ }
2796
+ super.ngOnDestroy();
2797
+ }
2798
+ }
2799
+ _NgtPortal_instances = new WeakSet(), _NgtPortal_inject = function _NgtPortal_inject(rootState, injectState) {
2800
+ const intersect = { ...rootState };
2801
+ Object.keys(intersect).forEach((key) => {
2802
+ if (privateKeys.includes(key) ||
2803
+ rootState[key] !== injectState[key]) {
2804
+ delete intersect[key];
2805
+ }
2806
+ });
2807
+ const inputs = this.get();
2808
+ const { size, events, ...restInputsState } = inputs.state || {};
2809
+ let viewport = undefined;
2810
+ if (injectState && size) {
2811
+ const camera = injectState.camera;
2812
+ viewport = rootState.viewport.getCurrentViewport(camera, new THREE.Vector3(), size);
2813
+ if (camera !== rootState.camera)
2814
+ updateCamera(camera, size);
2815
+ }
2816
+ return {
2817
+ ...intersect,
2818
+ scene: is.ref(inputs.container) ? inputs.container.nativeElement : inputs.container,
2819
+ raycaster: this.raycaster,
2820
+ pointer: this.pointer,
2821
+ previousStore: this.parentStore,
2822
+ events: { ...rootState.events, ...(injectState?.events || {}), ...events },
2823
+ size: { ...rootState.size, ...size },
2824
+ viewport: { ...rootState.viewport, ...(viewport || {}) },
2825
+ ...restInputsState,
2826
+ };
2827
+ };
2828
+ NgtPortal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortal, deps: null, target: i0.ɵɵFactoryTarget.Component });
2829
+ NgtPortal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.1", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { container: "container", state: "state", autoRender: "autoRender", autoRenderPriority: "autoRenderPriority" }, outputs: { beforeRender: "beforeRender" }, providers: [NgtStore], 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 }], usesInheritance: true, ngImport: i0, template: `
2830
+ <ng-container #portalContentAnchor>
2831
+ <ngt-portal-before-render
2832
+ *ngIf="autoRender && portalContentRendered"
2833
+ [renderPriority]="autoRenderPriority"
2834
+ [parentScene]="parentScene"
2835
+ [parentCamera]="parentCamera"
2836
+ (beforeRender)="onBeforeRender($event)"
2837
+ />
2838
+ </ng-container>
2839
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgtPortalBeforeRender, selector: "ngt-portal-before-render", inputs: ["renderPriority", "parentScene", "parentCamera"], outputs: ["beforeRender"] }] });
2840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortal, decorators: [{
2841
+ type: Component,
2842
+ args: [{
2843
+ selector: 'ngt-portal',
2844
+ standalone: true,
2845
+ template: `
2846
+ <ng-container #portalContentAnchor>
2847
+ <ngt-portal-before-render
2848
+ *ngIf="autoRender && portalContentRendered"
2849
+ [renderPriority]="autoRenderPriority"
2850
+ [parentScene]="parentScene"
2851
+ [parentCamera]="parentCamera"
2852
+ (beforeRender)="onBeforeRender($event)"
2853
+ />
2854
+ </ng-container>
2855
+ `,
2856
+ imports: [NgIf, NgtPortalBeforeRender],
2857
+ providers: [NgtStore],
2858
+ }]
2859
+ }], propDecorators: { container: [{
2860
+ type: Input
2861
+ }], state: [{
2862
+ type: Input
2863
+ }], autoRender: [{
2864
+ type: Input
2865
+ }], autoRenderPriority: [{
2866
+ type: Input
2867
+ }], beforeRender: [{
2868
+ type: Output
2869
+ }], portalContentTemplate: [{
2870
+ type: ContentChild,
2871
+ args: [NgtPortalContent, { read: TemplateRef, static: true }]
2872
+ }], portalContentAnchor: [{
2873
+ type: ViewChild,
2874
+ args: ['portalContentAnchor', { read: ViewContainerRef, static: true }]
2875
+ }] } });
2876
+
2629
2877
  /**
2630
2878
  * Generated bundle index. Do not edit.
2631
2879
  */
2632
2880
 
2633
- export { NGT_CATALOGUE, NgtArgs, NgtCanvas, NgtPush, NgtRepeat, NgtRxStore, NgtStore, checkNeedsUpdate, checkUpdate, extend, getLocalState, injectBeforeRender, injectNgtDestroy, injectNgtLoader, injectNgtRef, invalidateInstance, is, prepare, rootStateMap, startWithUndefined, updateCamera };
2881
+ export { NGT_CATALOGUE, NgtArgs, NgtCanvas, NgtPortal, NgtPortalBeforeRender, NgtPortalContent, NgtPush, NgtRepeat, NgtRxStore, NgtStore, checkNeedsUpdate, checkUpdate, createAttachFunction, extend, getLocalState, injectBeforeRender, injectNgtDestroy, injectNgtLoader, injectNgtRef, invalidateInstance, is, makeDefaultCamera, makeDefaultRenderer, makeDpr, makeId, makeObjectGraph, prepare, rootStateMap, startWithUndefined, updateCamera };
2634
2882
  //# sourceMappingURL=angular-three.mjs.map