1- import { Directive , effect , input , untracked } from '@angular/core' ;
1+ import { computed , Directive , effect , input } from '@angular/core' ;
22import { beforeRender , injectStore } from 'angular-three' ;
3+ import { CameraShake } from 'angular-three-soba/vanilla-exports' ;
34import { mergeInputs } from 'ngxtension/inject-inputs' ;
45import * as THREE from 'three' ;
5- import { SimplexNoise } from 'three-stdlib' ;
66
77interface ControlsProto {
88 update ( ) : void ;
@@ -11,19 +11,7 @@ interface ControlsProto {
1111 removeEventListener : ( event : string , callback : ( event : any ) => void ) => void ;
1212}
1313
14- export interface NgtsCameraShakeOptions {
15- intensity : number ;
16- decay ?: boolean ;
17- decayRate : number ;
18- maxYaw : number ;
19- maxPitch : number ;
20- maxRoll : number ;
21- yawFrequency : number ;
22- pitchFrequency : number ;
23- rollFrequency : number ;
24- }
25-
26- const defaultOptions : NgtsCameraShakeOptions = {
14+ const defaultOptions : Partial < Omit < CameraShake , 'object' | 'initialRotation' | 'updateInitialRotation' | 'update' > > = {
2715 intensity : 1 ,
2816 decayRate : 0.65 ,
2917 maxYaw : 0.1 ,
@@ -34,59 +22,38 @@ const defaultOptions: NgtsCameraShakeOptions = {
3422 rollFrequency : 0.1 ,
3523} ;
3624
37- @Directive ( { selector : 'ngts-camera-shake' } )
25+ @Directive ( {
26+ selector : 'ngts-camera-shake' ,
27+ exportAs : 'cameraShake' ,
28+ } )
3829export class NgtsCameraShake {
3930 options = input ( defaultOptions , { transform : mergeInputs ( defaultOptions ) } ) ;
4031
4132 private store = injectStore ( ) ;
4233
43- private initialRotation = this . store . snapshot . camera . rotation . clone ( ) ;
44- private intensityOption = untracked ( this . options ) . intensity ;
45-
46- get intensity ( ) {
47- return this . intensityOption ;
48- }
49-
50- set intensity ( val : number ) {
51- this . intensityOption = Math . min ( 1 , Math . max ( 0 , val ) ) ;
52- }
53-
54- private yawNoise = new SimplexNoise ( ) ;
55- private pitchNoise = new SimplexNoise ( ) ;
56- private rollNoise = new SimplexNoise ( ) ;
34+ cameraShaker = computed ( ( ) => new CameraShake ( this . store . camera ( ) ) ) ;
5735
5836 constructor ( ) {
5937 effect ( ( onCleanup ) => {
6038 const defaultControls = this . store . controls ( ) as unknown as ControlsProto ;
6139 if ( ! defaultControls ) return ;
62- const camera = this . store . camera ( ) ;
6340
64- const callback = ( ) => void ( this . initialRotation = camera . rotation . clone ( ) ) ;
41+ const cameraShaker = this . cameraShaker ( ) ;
42+ const callback = ( ) => void cameraShaker . updateInitialRotation ( ) ;
43+
6544 defaultControls . addEventListener ( 'change' , callback ) ;
6645 callback ( ) ;
6746
6847 onCleanup ( ( ) => void defaultControls . removeEventListener ( 'change' , callback ) ) ;
6948 } ) ;
7049
71- beforeRender ( ( { delta, clock } ) => {
72- const [
73- { maxYaw, yawFrequency, maxPitch, pitchFrequency, maxRoll, rollFrequency, decay, decayRate } ,
74- camera ,
75- ] = [ this . options ( ) , this . store . snapshot . camera ] ;
76- const shake = Math . pow ( this . intensity , 2 ) ;
77- const yaw = maxYaw * shake * this . yawNoise . noise ( clock . elapsedTime * yawFrequency , 1 ) ;
78- const pitch = maxPitch * shake * this . pitchNoise . noise ( clock . elapsedTime * pitchFrequency , 1 ) ;
79- const roll = maxRoll * shake * this . rollNoise . noise ( clock . elapsedTime * rollFrequency , 1 ) ;
80-
81- camera . rotation . set (
82- this . initialRotation . x + pitch ,
83- this . initialRotation . y + yaw ,
84- this . initialRotation . z + roll ,
85- ) ;
50+ effect ( ( ) => {
51+ Object . assign ( this . cameraShaker ( ) , this . options ( ) ) ;
52+ } ) ;
8653
87- if ( decay && this . intensity > 0 ) {
88- this . intensity -= decayRate * delta ;
89- }
54+ beforeRender ( ( { delta , clock } ) => {
55+ const cameraShaker = this . cameraShaker ( ) ;
56+ cameraShaker . update ( delta , clock . elapsedTime ) ;
9057 } ) ;
9158 }
9259}
0 commit comments