angular-three 1.0.0-beta.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
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 { __rest } from 'tslib';
7
- import { DOCUMENT, NgForOf } from '@angular/common';
6
+ import { __rest, __classPrivateFieldGet } from 'tslib';
7
+ import { DOCUMENT, NgForOf, NgIf } from '@angular/common';
8
8
  import { RxState, selectSlice } from '@rx-angular/state';
9
9
  import { ɵDomRendererFactory2 } from '@angular/platform-browser';
10
10
 
@@ -340,12 +340,20 @@ function invalidateInstance(instance) {
340
340
  checkUpdate(instance);
341
341
  }
342
342
  function prepare(object, localState) {
343
- const instance = object;
343
+ const instance = (typeof object === 'function' ? object() : object);
344
344
  if ((localState === null || localState === void 0 ? void 0 : localState.primitive) || !instance.__ngt__) {
345
345
  const _a = localState || {}, { objects = new BehaviorSubject([]), nonObjects = new BehaviorSubject([]) } = _a, rest = __rest(_a, ["objects", "nonObjects"]);
346
346
  instance.__ngt__ = Object.assign({ previousAttach: null, store: null, parent: null, memoized: {}, eventCount: 0, handlers: {}, objects,
347
347
  nonObjects, add: (object, type) => {
348
- instance.__ngt__[type].next([...instance.__ngt__[type].value, object]);
348
+ const current = instance.__ngt__[type].value;
349
+ const foundIndex = current.indexOf((obj) => obj === object);
350
+ if (foundIndex > -1) {
351
+ current.splice(foundIndex, 1, object);
352
+ instance.__ngt__[type].next(current);
353
+ }
354
+ else {
355
+ instance.__ngt__[type].next([...instance.__ngt__[type].value, object]);
356
+ }
349
357
  notifyAncestors(instance.__ngt__.parent);
350
358
  }, remove: (object, type) => {
351
359
  instance.__ngt__[type].next(instance.__ngt__[type].value.filter((o) => o !== object));
@@ -821,7 +829,7 @@ class NgtStore extends NgtRxStore {
821
829
  // Safely set color management if available.
822
830
  // Avoid accessing THREE.ColorManagement to play nice with older versions
823
831
  if (THREE.ColorManagement)
824
- THREE.ColorManagement.legacyMode = state.legacy;
832
+ THREE.ColorManagement.legacyMode = legacy !== null && legacy !== void 0 ? legacy : true;
825
833
  const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
826
834
  const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
827
835
  if (gl.outputEncoding !== outputEncoding)
@@ -1331,6 +1339,9 @@ function assignEmpty(obj, base) {
1331
1339
  obj[base] = {};
1332
1340
  }
1333
1341
  }
1342
+ function createAttachFunction(cb) {
1343
+ return (parent, child, store) => cb({ parent, child, store });
1344
+ }
1334
1345
 
1335
1346
  const SPECIAL_DOM_TAG = {
1336
1347
  NGT_PORTAL: 'ngt-portal',
@@ -1435,7 +1446,7 @@ function removeThreeChild(parent, child, dispose) {
1435
1446
  removeThreeRecursive(child.childre, child, !!dispose);
1436
1447
  }
1437
1448
  // dispose
1438
- if (child['dispose'] && !is.scene(child)) {
1449
+ if (!isPrimitive && child['dispose'] && !is.scene(child)) {
1439
1450
  queueMicrotask(() => child['dispose']());
1440
1451
  }
1441
1452
  invalidateInstance(parent);
@@ -1531,14 +1542,18 @@ class NgtRendererStore {
1531
1542
  state[13 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(rendererNode).injector;
1532
1543
  // we attach an arrow function to the Comment node
1533
1544
  // In our directives, we can call this function to then start tracking the RendererNode
1534
- rendererNode['__ngt_renderer_add_comment__'] = () => {
1535
- this.comments.push(rendererNode);
1545
+ rendererNode['__ngt_renderer_add_comment__'] = (portalNode) => {
1546
+ if (portalNode && portalNode.__ngt_renderer__[0 /* NgtRendererClassId.type */] === 'portal') {
1547
+ this.portals.push(portalNode);
1548
+ }
1549
+ else {
1550
+ this.comments.push(rendererNode);
1551
+ }
1536
1552
  };
1537
1553
  return rendererNode;
1538
1554
  }
1539
1555
  if (state[0 /* NgtRendererClassId.type */] === 'portal') {
1540
1556
  state[13 /* NgtRendererClassId.injectorFactory */] = () => getDebugNode(rendererNode).injector;
1541
- this.portals.push(rendererNode);
1542
1557
  return rendererNode;
1543
1558
  }
1544
1559
  if (state[0 /* NgtRendererClassId.type */] === 'compound') {
@@ -1652,6 +1667,7 @@ class NgtRendererStore {
1652
1667
  if (node.__ngt_renderer__[3 /* NgtRendererClassId.destroyed */])
1653
1668
  return;
1654
1669
  // setup [ref] here
1670
+ // ref should never change
1655
1671
  if (name === SPECIAL_PROPERTIES.REF && is.ref(value)) {
1656
1672
  node.__ngt_renderer__[11 /* NgtRendererClassId.ref */] = value;
1657
1673
  value.nativeElement = node;
@@ -1838,7 +1854,8 @@ class NgtRendererStore {
1838
1854
  continue;
1839
1855
  }
1840
1856
  const instance = injector.get(NgtStore, null);
1841
- if (instance) {
1857
+ // only the instance with previousStore should pass
1858
+ if (instance && instance.get('previousStore')) {
1842
1859
  store = instance;
1843
1860
  break;
1844
1861
  }
@@ -2607,9 +2624,219 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImpor
2607
2624
  args: [{ name: 'ngtPush', pure: false, standalone: true }]
2608
2625
  }] });
2609
2626
 
2627
+ var _NgtPortal_instances, _NgtPortal_inject;
2628
+ const privateKeys = [
2629
+ 'get',
2630
+ 'set',
2631
+ 'select',
2632
+ 'setSize',
2633
+ 'setDpr',
2634
+ 'setFrameloop',
2635
+ 'events',
2636
+ 'invalidate',
2637
+ 'advance',
2638
+ 'size',
2639
+ 'viewport',
2640
+ 'addInteraction',
2641
+ 'removeInteraction',
2642
+ ];
2643
+ class NgtPortalBeforeRender {
2644
+ constructor() {
2645
+ this.portalStore = inject(NgtStore);
2646
+ this.renderPriority = 1;
2647
+ this.beforeRender = new EventEmitter();
2648
+ }
2649
+ ngOnInit() {
2650
+ let oldClear;
2651
+ this.subscription = this.portalStore.get('internal').subscribe(({ delta, frame }) => {
2652
+ this.beforeRender.emit(Object.assign(Object.assign({}, this.portalStore.get()), { delta, frame }));
2653
+ const { gl, scene, camera } = this.portalStore.get();
2654
+ oldClear = gl.autoClear;
2655
+ if (this.renderPriority === 1) {
2656
+ // clear scene and render with default
2657
+ gl.autoClear = true;
2658
+ gl.render(this.parentScene, this.parentCamera);
2659
+ }
2660
+ // disable cleaning
2661
+ gl.autoClear = false;
2662
+ gl.clearDepth();
2663
+ gl.render(scene, camera);
2664
+ // restore
2665
+ gl.autoClear = oldClear;
2666
+ }, this.renderPriority, this.portalStore);
2667
+ }
2668
+ ngOnDestroy() {
2669
+ var _a;
2670
+ (_a = this.subscription) === null || _a === void 0 ? void 0 : _a.call(this);
2671
+ }
2672
+ }
2673
+ NgtPortalBeforeRender.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2674
+ 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 });
2675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
2676
+ type: Directive,
2677
+ args: [{
2678
+ selector: 'ngt-portal-before-render',
2679
+ standalone: true,
2680
+ }]
2681
+ }], propDecorators: { renderPriority: [{
2682
+ type: Input
2683
+ }], parentScene: [{
2684
+ type: Input
2685
+ }], parentCamera: [{
2686
+ type: Input
2687
+ }], beforeRender: [{
2688
+ type: Output
2689
+ }] } });
2690
+ class NgtPortalContent {
2691
+ constructor(vcr, parentVcr) {
2692
+ const commentNode = vcr.element.nativeElement;
2693
+ if (commentNode['__ngt_renderer_add_comment__']) {
2694
+ commentNode['__ngt_renderer_add_comment__'](parentVcr.element.nativeElement);
2695
+ delete commentNode['__ngt_renderer_add_comment__'];
2696
+ }
2697
+ }
2698
+ }
2699
+ 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 });
2700
+ NgtPortalContent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.1", type: NgtPortalContent, isStandalone: true, selector: "ng-template[ngtPortalContent]", ngImport: i0 });
2701
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortalContent, decorators: [{
2702
+ type: Directive,
2703
+ args: [{ selector: 'ng-template[ngtPortalContent]', standalone: true }]
2704
+ }], ctorParameters: function () {
2705
+ return [{ type: i0.ViewContainerRef }, { type: i0.ViewContainerRef, decorators: [{
2706
+ type: SkipSelf
2707
+ }] }];
2708
+ } });
2709
+ class NgtPortal extends NgtRxStore {
2710
+ constructor() {
2711
+ super(...arguments);
2712
+ _NgtPortal_instances.add(this);
2713
+ this.autoRender = true;
2714
+ this.autoRenderPriority = 1;
2715
+ this.beforeRender = new EventEmitter();
2716
+ this.parentStore = inject(NgtStore, { skipSelf: true });
2717
+ this.parentScene = this.parentStore.get('scene');
2718
+ this.parentCamera = this.parentStore.get('camera');
2719
+ this.portalStore = inject(NgtStore, { self: true });
2720
+ this.raycaster = new THREE.Raycaster();
2721
+ this.pointer = new THREE.Vector2();
2722
+ this.portalContentRendered = false;
2723
+ }
2724
+ set container(container) {
2725
+ this.set({ container });
2726
+ }
2727
+ set state(state) {
2728
+ this.set({ state });
2729
+ }
2730
+ initialize() {
2731
+ super.initialize();
2732
+ this.set({ container: injectNgtRef(prepare(new THREE.Scene())) });
2733
+ }
2734
+ ngOnInit() {
2735
+ const previousState = this.parentStore.get();
2736
+ const inputsState = this.get();
2737
+ if (!inputsState.state && this.autoRender) {
2738
+ inputsState.state = { events: { priority: this.autoRenderPriority + 1 } };
2739
+ }
2740
+ const _a = inputsState.state || {}, { events, size } = _a, restInputsState = __rest(_a, ["events", "size"]);
2741
+ const containerState = inputsState.container;
2742
+ const container = is.ref(containerState) ? containerState.nativeElement : containerState;
2743
+ const localState = getLocalState(container);
2744
+ if (!localState.store) {
2745
+ localState.store = this.portalStore;
2746
+ }
2747
+ this.portalStore.set(Object.assign(Object.assign(Object.assign(Object.assign({}, previousState), { scene: container, raycaster: this.raycaster, pointer: this.pointer, previousStore: this.parentStore, events: Object.assign(Object.assign({}, previousState.events), (events || {})), size: Object.assign(Object.assign({}, previousState.size), (size || {})) }), restInputsState), { get: this.portalStore.get.bind(this.portalStore), set: this.portalStore.set.bind(this.portalStore), select: this.portalStore.select.bind(this.portalStore), setEvents: (events) => this.portalStore.set((state) => (Object.assign(Object.assign({}, state), { events: Object.assign(Object.assign({}, state.events), events) }))) }));
2748
+ this.hold(this.parentStore.select(), (previous) => this.portalStore.set((state) => __classPrivateFieldGet(this, _NgtPortal_instances, "m", _NgtPortal_inject).call(this, previous, state)));
2749
+ requestAnimationFrame(() => {
2750
+ this.portalStore.set((injectState) => __classPrivateFieldGet(this, _NgtPortal_instances, "m", _NgtPortal_inject).call(this, this.parentStore.get(), injectState));
2751
+ });
2752
+ this.portalContentView = this.portalContentAnchor.createEmbeddedView(this.portalContentTemplate);
2753
+ this.portalContentView.detectChanges();
2754
+ this.portalContentRendered = true;
2755
+ }
2756
+ onBeforeRender(portal) {
2757
+ this.beforeRender.emit({
2758
+ root: Object.assign(Object.assign({}, this.parentStore.get()), { delta: portal.delta, frame: portal.frame }),
2759
+ portal,
2760
+ });
2761
+ }
2762
+ ngOnDestroy() {
2763
+ if (this.portalContentView && !this.portalContentView.destroyed) {
2764
+ this.portalContentView.destroy();
2765
+ }
2766
+ super.ngOnDestroy();
2767
+ }
2768
+ }
2769
+ _NgtPortal_instances = new WeakSet(), _NgtPortal_inject = function _NgtPortal_inject(rootState, injectState) {
2770
+ const intersect = Object.assign({}, rootState);
2771
+ Object.keys(intersect).forEach((key) => {
2772
+ if (privateKeys.includes(key) ||
2773
+ rootState[key] !== injectState[key]) {
2774
+ delete intersect[key];
2775
+ }
2776
+ });
2777
+ const inputs = this.get();
2778
+ const _a = inputs.state || {}, { size, events } = _a, restInputsState = __rest(_a, ["size", "events"]);
2779
+ let viewport = undefined;
2780
+ if (injectState && size) {
2781
+ const camera = injectState.camera;
2782
+ viewport = rootState.viewport.getCurrentViewport(camera, new THREE.Vector3(), size);
2783
+ if (camera !== rootState.camera)
2784
+ updateCamera(camera, size);
2785
+ }
2786
+ return Object.assign(Object.assign(Object.assign({}, intersect), { scene: is.ref(inputs.container) ? inputs.container.nativeElement : inputs.container, raycaster: this.raycaster, pointer: this.pointer, previousStore: this.parentStore, events: Object.assign(Object.assign(Object.assign({}, rootState.events), ((injectState === null || injectState === void 0 ? void 0 : injectState.events) || {})), events), size: Object.assign(Object.assign({}, rootState.size), size), viewport: Object.assign(Object.assign({}, rootState.viewport), (viewport || {})) }), restInputsState);
2787
+ };
2788
+ NgtPortal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortal, deps: null, target: i0.ɵɵFactoryTarget.Component });
2789
+ 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: `
2790
+ <ng-container #portalContentAnchor>
2791
+ <ngt-portal-before-render
2792
+ *ngIf="autoRender && portalContentRendered"
2793
+ [renderPriority]="autoRenderPriority"
2794
+ [parentScene]="parentScene"
2795
+ [parentCamera]="parentCamera"
2796
+ (beforeRender)="onBeforeRender($event)"
2797
+ />
2798
+ </ng-container>
2799
+ `, 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"] }] });
2800
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.1", ngImport: i0, type: NgtPortal, decorators: [{
2801
+ type: Component,
2802
+ args: [{
2803
+ selector: 'ngt-portal',
2804
+ standalone: true,
2805
+ template: `
2806
+ <ng-container #portalContentAnchor>
2807
+ <ngt-portal-before-render
2808
+ *ngIf="autoRender && portalContentRendered"
2809
+ [renderPriority]="autoRenderPriority"
2810
+ [parentScene]="parentScene"
2811
+ [parentCamera]="parentCamera"
2812
+ (beforeRender)="onBeforeRender($event)"
2813
+ />
2814
+ </ng-container>
2815
+ `,
2816
+ imports: [NgIf, NgtPortalBeforeRender],
2817
+ providers: [NgtStore],
2818
+ }]
2819
+ }], propDecorators: { container: [{
2820
+ type: Input
2821
+ }], state: [{
2822
+ type: Input
2823
+ }], autoRender: [{
2824
+ type: Input
2825
+ }], autoRenderPriority: [{
2826
+ type: Input
2827
+ }], beforeRender: [{
2828
+ type: Output
2829
+ }], portalContentTemplate: [{
2830
+ type: ContentChild,
2831
+ args: [NgtPortalContent, { read: TemplateRef, static: true }]
2832
+ }], portalContentAnchor: [{
2833
+ type: ViewChild,
2834
+ args: ['portalContentAnchor', { read: ViewContainerRef, static: true }]
2835
+ }] } });
2836
+
2610
2837
  /**
2611
2838
  * Generated bundle index. Do not edit.
2612
2839
  */
2613
2840
 
2614
- export { NGT_CATALOGUE, NgtArgs, NgtCanvas, NgtPush, NgtRepeat, NgtRxStore, NgtStore, checkNeedsUpdate, checkUpdate, extend, getLocalState, injectBeforeRender, injectNgtDestroy, injectNgtLoader, injectNgtRef, invalidateInstance, is, prepare, rootStateMap, startWithUndefined, updateCamera };
2841
+ 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 };
2615
2842
  //# sourceMappingURL=angular-three.mjs.map