From ec34683555d2ce3d9f95827e27440900fc5b93bc Mon Sep 17 00:00:00 2001 From: Chau Tran Date: Tue, 7 Mar 2023 21:44:40 -0600 Subject: [PATCH] fix: adjust animations API --- .../misc/src/lib/animations/animations.ts | 93 ++++++++++--------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/libs/angular-three-soba/misc/src/lib/animations/animations.ts b/libs/angular-three-soba/misc/src/lib/animations/animations.ts index 6969c0a..c41c15e 100644 --- a/libs/angular-three-soba/misc/src/lib/animations/animations.ts +++ b/libs/angular-three-soba/misc/src/lib/animations/animations.ts @@ -1,8 +1,8 @@ import { injectBeforeRender, injectNgtDestroy, injectNgtRef, is, NgtInjectedRef } from 'angular-three'; -import { isObservable, Observable, Subscription } from 'rxjs'; import { AnimationMixer } from 'three'; type Api = { + (clips: T[], object?: THREE.Object3D | NgtInjectedRef): void; ref: NgtInjectedRef; clips: THREE.AnimationClip[]; mixer: THREE.AnimationMixer; @@ -10,59 +10,64 @@ type Api = { actions: { [key in T['name']]: THREE.AnimationAction | null }; }; -export function injectNgtsAnimations( - clips: T[], - object?: Observable | THREE.Object3D | NgtInjectedRef -): Api { +export function injectNgtsAnimations() { let ref = injectNgtRef(); - let sub: Subscription; + const mixer = new AnimationMixer(null!); + const cleanUps = [] as (() => void)[]; - if (object) { - if (isObservable(object)) { - sub = object.subscribe((val) => { - ref.nativeElement = val; - }); - } else if (is.ref(object)) { - ref = object; - } else { - ref.nativeElement = object; - } - } + injectNgtDestroy(() => { + cleanUps.forEach((cleanUp) => cleanUp()); + }); - const mixer = new AnimationMixer(ref.nativeElement); + injectBeforeRender(({ delta }) => mixer.update(delta)); + + const api = ( + clips: T[], + object?: THREE.Object3D | NgtInjectedRef + ) => { + let cached = {} as { [key in T['name']]: THREE.AnimationAction | null }; + const actions = {} as { [key in T['name']]: THREE.AnimationAction | null }; + const names = [] as T['name'][]; + + if (object) { + if (is.ref(object)) { + ref = object; + } else { + ref.nativeElement = object; + } + } - let cached = {} as { [key in T['name']]: THREE.AnimationAction | null }; - const actions = {} as { [key in T['name']]: THREE.AnimationAction | null }; - const names = [] as T['name'][]; + for (const clip of clips) { + names.push(clip.name); + Object.defineProperty(actions, clip.name, { + enumerable: true, + get: () => { + if (ref.nativeElement) { + const name = clip.name as keyof typeof cached; + return cached[name] || (cached[name] = mixer.clipAction(clip, ref.nativeElement)); + } + }, + }); + } - for (const clip of clips) { - names.push(clip.name); - Object.defineProperty(actions, clip.name, { - enumerable: true, - get: () => { + cleanUps.push(() => { + cached = {} as { [key in T['name']]: THREE.AnimationAction | null }; + Object.values(actions).forEach((action) => { if (ref.nativeElement) { - const name = clip.name as keyof typeof cached; - return cached[name] || (cached[name] = mixer.clipAction(clip, ref.nativeElement)); + mixer.uncacheAction(action as THREE.AnimationClip, ref.nativeElement); } - }, + }); + mixer.stopAllAction(); }); - } - const api = { ref, clips, actions, names, mixer }; + (api as Api).clips = clips; + (api as Api).actions = actions; + (api as Api).names = names; + }; - injectNgtDestroy(() => { - if (sub) sub.unsubscribe(); - cached = {} as { [key in T['name']]: THREE.AnimationAction | null }; - Object.values(api.actions).forEach((action) => { - if (ref.nativeElement) { - mixer.uncacheAction(action as THREE.AnimationClip, ref.nativeElement); - } - }); - mixer.stopAllAction(); - }); - - injectBeforeRender(({ delta }) => mixer.update(delta)); + api.ref = ref; + api.mixer = mixer; - return api; + return api as Api; }