diff --git a/packages/controls/src/lib/controls.ts b/packages/controls/src/lib/controls.ts index 9e0d84f3c..0f8c7cd9c 100644 --- a/packages/controls/src/lib/controls.ts +++ b/packages/controls/src/lib/controls.ts @@ -2,6 +2,7 @@ import { AnimationStore, CanvasStore, DestroyedService, + distinctKeyMap, NgtAnimationParticipant, NgtCamera, UnknownRecord, @@ -39,8 +40,8 @@ export abstract class NgtControls ngOnInit() { this.ngZone.runOutsideAngular(() => { this.canvasStore.selectors.internal$ - .pipe(takeUntil(this.destroyed)) - .subscribe(({ active }) => { + .pipe(distinctKeyMap('active'), takeUntil(this.destroyed)) + .subscribe((active) => { this.ngZone.runOutsideAngular(() => { const { camera, renderer, scene } = this.canvasStore.getImperativeState(); diff --git a/packages/core/audios/src/lib/audio-listener/audio-listener.directive.ts b/packages/core/audios/src/lib/audio-listener/audio-listener.directive.ts index 6f3b433f9..96afc84a5 100644 --- a/packages/core/audios/src/lib/audio-listener/audio-listener.directive.ts +++ b/packages/core/audios/src/lib/audio-listener/audio-listener.directive.ts @@ -1,4 +1,8 @@ -import { CanvasStore, DestroyedService } from '@angular-three/core'; +import { + CanvasStore, + DestroyedService, + distinctKeyMap, +} from '@angular-three/core'; import { Directive, EventEmitter, @@ -44,8 +48,8 @@ export class NgtAudioListener implements OnInit { } this.canvasStore.selectors.internal$ - .pipe(takeUntil(this.destroyed)) - .subscribe(({ active }) => { + .pipe(distinctKeyMap('active'), takeUntil(this.destroyed)) + .subscribe((active) => { this.ngZone.runOutsideAngular(() => { const { camera } = this.canvasStore.getImperativeState(); if (active && camera) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index fe5d650c4..0f1e1fa30 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -28,6 +28,7 @@ export * from './lib/three/texture'; export * from './lib/utils/apply-props.util'; export * from './lib/utils/build-graph.util'; +export * from './lib/utils/distinct-key-map.operator'; export * from './lib/utils/controller'; export * from './lib/services/loader.service'; diff --git a/packages/core/src/lib/canvas.component.ts b/packages/core/src/lib/canvas.component.ts index 905daccc4..a854ab3ef 100644 --- a/packages/core/src/lib/canvas.component.ts +++ b/packages/core/src/lib/canvas.component.ts @@ -28,6 +28,7 @@ import { AnimationStore } from './stores/animation.store'; import { CanvasStore } from './stores/canvas.store'; import { EventsStore } from './stores/events.store'; import { InstancesStore } from './stores/instances.store'; +import { distinctKeyMap } from './utils/distinct-key-map.operator'; @Component({ selector: 'ngt-canvas', @@ -140,8 +141,12 @@ export class NgtCanvasComponent implements OnInit { private initActiveListener() { this.canvasStore.selectors.internal$ - .pipe(takeUntil(this.destroyed), observeOn(asapScheduler)) - .subscribe(({ active }) => { + .pipe( + distinctKeyMap('active'), + takeUntil(this.destroyed), + observeOn(asapScheduler) + ) + .subscribe((active) => { this.ngZone.runOutsideAngular(() => { if (active) { const { renderer, camera, scene } = diff --git a/packages/core/src/lib/utils/distinct-key-map.operator.ts b/packages/core/src/lib/utils/distinct-key-map.operator.ts new file mode 100644 index 000000000..697a79166 --- /dev/null +++ b/packages/core/src/lib/utils/distinct-key-map.operator.ts @@ -0,0 +1,16 @@ +import { + distinctUntilKeyChanged, + map, + Observable, + OperatorFunction, + pipe, +} from 'rxjs'; + +export function distinctKeyMap( + key: TKey +): OperatorFunction { + return pipe, Observable, Observable>( + distinctUntilKeyChanged(key), + map((data) => data[key]) + ); +} diff --git a/packages/postprocessing/src/lib/effect-composer.directive.ts b/packages/postprocessing/src/lib/effect-composer.directive.ts index 41149ebef..ab55b0499 100644 --- a/packages/postprocessing/src/lib/effect-composer.directive.ts +++ b/packages/postprocessing/src/lib/effect-composer.directive.ts @@ -1,4 +1,4 @@ -import { CanvasStore } from '@angular-three/core'; +import { CanvasStore, distinctKeyMap } from '@angular-three/core'; import { Directive, EventEmitter, @@ -9,14 +9,7 @@ import { SkipSelf, } from '@angular/core'; import { ComponentStore } from '@ngrx/component-store'; -import { - distinctUntilKeyChanged, - EMPTY, - map, - switchMap, - tap, - withLatestFrom, -} from 'rxjs'; +import { EMPTY, switchMap, tap, withLatestFrom } from 'rxjs'; import * as THREE from 'three'; import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'; @@ -45,10 +38,7 @@ export class NgtEffectComposer extends ComponentStore<{}> implements OnInit { ngOnInit() { this.ngZone.runOutsideAngular(() => { this.initComposer( - this.canvasStore.selectors.internal$.pipe( - distinctUntilKeyChanged('active'), - map((internal) => internal.active) - ) + this.canvasStore.selectors.internal$.pipe(distinctKeyMap('active')) ); }); } @@ -63,8 +53,7 @@ export class NgtEffectComposer extends ComponentStore<{}> implements OnInit { if (this.watchSizeChanged) { return this.canvasStore.selectors.internal$.pipe( - distinctUntilKeyChanged('size'), - map((internal) => internal.size), + distinctKeyMap('size'), tap(({ width, height }) => { this.ngZone.runOutsideAngular(() => { this._composer.setSize(width, height); diff --git a/packages/soba/abstractions/src/lib/billboard/billboard.stories.ts b/packages/soba/abstractions/src/lib/billboard/billboard.stories.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/soba/cameras/src/lib/orthographic-camera/orthographic-camera.store.ts b/packages/soba/cameras/src/lib/orthographic-camera/orthographic-camera.store.ts index 376694afd..08a68c79a 100644 --- a/packages/soba/cameras/src/lib/orthographic-camera/orthographic-camera.store.ts +++ b/packages/soba/cameras/src/lib/orthographic-camera/orthographic-camera.store.ts @@ -1,19 +1,13 @@ import { CanvasStore, + distinctKeyMap, EnhancedComponentStore, NGT_OBJECT_3D_WATCHED_CONTROLLER, NgtObject3dController, NgtSize, } from '@angular-three/core'; import { Inject, Injectable, NgZone, SimpleChanges } from '@angular/core'; -import { - distinctUntilKeyChanged, - map, - Observable, - of, - tap, - withLatestFrom, -} from 'rxjs'; +import { Observable, of, tap, withLatestFrom } from 'rxjs'; import * as THREE from 'three'; export interface SobaOrthographicCameraState { @@ -44,8 +38,7 @@ export const initialSobaOrthographicCameraState: SobaOrthographicCameraState = @Injectable() export class SobaOrthographicCameraStore extends EnhancedComponentStore { readonly size$ = this.canvasStore.selectors.internal$.pipe( - distinctUntilKeyChanged('size'), - map((internal) => internal.size) + distinctKeyMap('size') ); readonly projectMatrixParams$ = this.select( diff --git a/packages/storybook/.storybook/preview-body.html b/packages/storybook/.storybook/preview-body.html new file mode 100644 index 000000000..95fb3a24b --- /dev/null +++ b/packages/storybook/.storybook/preview-body.html @@ -0,0 +1,7 @@ + +