11'use client' ;
22
3- import { useEffect , useRef , useState } from 'react' ;
3+ import { useCallback , useEffect , useRef , useState } from 'react' ;
44import { type VariantProps , cva } from 'class-variance-authority' ;
55import {
66 type AnimationPlaybackControlsWithThen ,
7+ type KeyframesTarget ,
78 type ValueAnimationTransition ,
89 animate ,
910 useMotionValue ,
@@ -19,32 +20,28 @@ import {
1920import { AuroraShaders , type AuroraShadersProps } from '@/components/ui/shadcn-io/aurora-shaders' ;
2021import { cn } from '@/lib/utils' ;
2122
22- // const PRESETS = [
23- // (volume: number) => ({
24- // amplitude: 0.3,
25- // scale: 0.35 - 0.05 * volume,
26- // frequency: 0.25,
27- // brightness: 1.5 + 2.5 * volume,
28- // }),
29- // (volume: number) => ({
30- // amplitude: 0.2 + 1 * volume,
31- // scale: 0.35 - 0.05 * volume,
32- // frequency: 0.25 + 5 * volume,
33- // brightness: 1.5 + 2.5 * volume,
34- // }),
35- // (volume: number) => ({
36- // amplitude: 0.5 + 0.05 * volume,
37- // scale: 0.35 + 0.05 * volume,
38- // frequency: 2 - 2 * volume,
39- // brightness: 1.5 + 2.5 * volume,
40- // }),
41- // (volume: number) => ({
42- // amplitude: 0.5 + 0.2 * volume,
43- // scale: 0.35 - 0.05 * volume,
44- // frequency: 1 - 1 * volume,
45- // brightness: 1.5 + 2.5 * volume,
46- // }),
47- // ];
23+ const DEFAULT_SPEED = 10 ;
24+ const DEFAULT_AMPLITUDE = 2 ;
25+ const DEFAULT_FREQUENCY = 0.5 ;
26+ const DEFAULT_SCALE = 0.2 ;
27+ const DEFAULT_BRIGHTNESS = 1.5 ;
28+ const DEFAULT_TRANSITION : ValueAnimationTransition = { duration : 0.5 , ease : 'easeOut' } ;
29+
30+ function useAnimatedValue < T > ( initialValue : T ) {
31+ const [ value , setValue ] = useState ( initialValue ) ;
32+ const motionValue = useMotionValue ( initialValue ) ;
33+ const controlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
34+ useMotionValueEvent ( motionValue , 'change' , ( value ) => setValue ( value as T ) ) ;
35+
36+ const animateFn = useCallback (
37+ ( targetValue : T | KeyframesTarget , transition : ValueAnimationTransition ) => {
38+ controlsRef . current = animate ( motionValue , targetValue , transition ) ;
39+ } ,
40+ [ motionValue ]
41+ ) ;
42+
43+ return { value, controls : controlsRef , animate : animateFn } ;
44+ }
4845
4946export const audioShaderVisualizerVariants = cva ( [ 'aspect-square' ] , {
5047 variants : {
@@ -77,133 +74,82 @@ export function AudioShaderVisualizer({
7774} : AudioShaderVisualizerProps &
7875 AuroraShadersProps &
7976 VariantProps < typeof audioShaderVisualizerVariants > ) {
80- const [ speed , setSpeed ] = useState ( 10 ) ;
81- const [ amplitude , setAmplitude ] = useState ( 0.5 ) ;
82- const [ frequency , setFrequency ] = useState ( 1.0 ) ;
83- const [ scale , setScale ] = useState ( 0.2 ) ;
84- const [ brightness , setBrightness ] = useState ( 1.5 ) ;
85-
86- const amplitudeValue = useMotionValue ( 0.5 ) ;
87- const frequencyValue = useMotionValue ( 0.5 ) ;
88- const scaleValue = useMotionValue ( 0.3 ) ;
89- const brightnessValue = useMotionValue ( 0 ) ;
90-
91- const amplitudeControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
92- const frequencyControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
93- const scaleControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
94- const brightnessControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
95-
96- useMotionValueEvent ( amplitudeValue , 'change' , ( value ) => setAmplitude ( value ) ) ;
97- useMotionValueEvent ( frequencyValue , 'change' , ( value ) => setFrequency ( value ) ) ;
98- useMotionValueEvent ( scaleValue , 'change' , ( value ) => setScale ( value ) ) ;
99- useMotionValueEvent ( brightnessValue , 'change' , ( value ) => setBrightness ( value ) ) ;
77+ const [ speed , setSpeed ] = useState ( DEFAULT_SPEED ) ;
78+ const { value : amplitude , animate : animateAmplitude } = useAnimatedValue ( DEFAULT_AMPLITUDE ) ;
79+ const { value : frequency , animate : animateFrequency } = useAnimatedValue ( DEFAULT_FREQUENCY ) ;
80+ const { value : scale , animate : animateScale } = useAnimatedValue ( DEFAULT_SCALE ) ;
81+ const { value : brightness , animate : animateBrightness } = useAnimatedValue ( DEFAULT_BRIGHTNESS ) ;
10082
10183 const volume = useTrackVolume ( audioTrack as TrackReference , {
10284 fftSize : 512 ,
103- smoothingTimeConstant : 0.5 ,
85+ smoothingTimeConstant : 0.55 ,
10486 } ) ;
10587
10688 useEffect ( ( ) => {
107- const DEFAULT_TRANSITION : ValueAnimationTransition = { duration : 0.5 , ease : 'easeOut' } ;
108-
10989 switch ( state ) {
11090 case 'disconnected' :
11191 setSpeed ( 5 ) ;
112- scaleControlsRef . current = animate ( scaleValue , 0.2 , DEFAULT_TRANSITION ) ;
113- amplitudeControlsRef . current = animate ( amplitudeValue , 1.2 , DEFAULT_TRANSITION ) ;
114- frequencyControlsRef . current = animate ( frequencyValue , 0.4 , DEFAULT_TRANSITION ) ;
115- brightnessControlsRef . current = animate ( brightnessValue , 1.0 , DEFAULT_TRANSITION ) ;
92+ animateScale ( 0.2 , DEFAULT_TRANSITION ) ;
93+ animateAmplitude ( 1.2 , DEFAULT_TRANSITION ) ;
94+ animateFrequency ( 0.4 , DEFAULT_TRANSITION ) ;
95+ animateBrightness ( 1.0 , DEFAULT_TRANSITION ) ;
11696 return ;
97+ case 'listening' :
11798 case 'connecting' :
118- setSpeed ( 50 ) ;
119- scaleControlsRef . current = animate ( scaleValue , 0.3 , DEFAULT_TRANSITION ) ;
120- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
121- frequencyControlsRef . current = animate ( frequencyValue , 1 , DEFAULT_TRANSITION ) ;
122- brightnessControlsRef . current = animate ( brightnessValue , [ 0.5 , 2.5 ] , {
123- duration : 1 ,
124- repeat : Infinity ,
125- repeatType : 'mirror' ,
126- } ) ;
99+ setSpeed ( 20 ) ;
100+ animateScale ( 0.35 , DEFAULT_TRANSITION ) ;
101+ animateAmplitude ( 1 , DEFAULT_TRANSITION ) ;
102+ animateFrequency ( 0.7 , DEFAULT_TRANSITION ) ;
103+ animateBrightness ( 2.0 , DEFAULT_TRANSITION ) ;
127104 return ;
128105 case 'initializing' :
129106 setSpeed ( 30 ) ;
130- scaleControlsRef . current = animate ( scaleValue , 0.3 , DEFAULT_TRANSITION ) ;
131- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
132- frequencyControlsRef . current = animate ( frequencyValue , 1 , DEFAULT_TRANSITION ) ;
133- brightnessControlsRef . current = animate ( brightnessValue , [ 0.5 , 2.5 ] , {
107+ animateScale ( 0.3 , DEFAULT_TRANSITION ) ;
108+ animateAmplitude ( 0.5 , DEFAULT_TRANSITION ) ;
109+ animateFrequency ( 1 , DEFAULT_TRANSITION ) ;
110+ animateBrightness ( [ 0.5 , 2.5 ] , {
134111 duration : 0.2 ,
135112 repeat : Infinity ,
136113 repeatType : 'mirror' ,
137114 } ) ;
138115 return ;
139- case 'listening' :
140- setSpeed ( 20 ) ;
141- scaleControlsRef . current = animate ( scaleValue , [ 0.3 , 0.35 ] , {
142- duration : 1.5 ,
143- repeat : Infinity ,
144- repeatType : 'mirror' ,
145- } ) ;
146- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
147- frequencyControlsRef . current = animate ( frequencyValue , 1.0 , DEFAULT_TRANSITION ) ;
148- brightnessControlsRef . current = animate ( brightnessValue , [ 1.5 , 2.5 ] , {
149- duration : 1.5 ,
150- repeat : Infinity ,
151- repeatType : 'mirror' ,
152- } ) ;
153- return ;
154116 case 'thinking' :
155- setSpeed ( 50 ) ;
156- scaleControlsRef . current = animate ( scaleValue , [ 0.35 , 0.3 ] , {
157- duration : 0.5 ,
117+ setSpeed ( 30 ) ;
118+ animateScale ( [ 0.15 , 0.13 ] , {
119+ duration : 0.3 ,
158120 repeat : Infinity ,
159121 repeatType : 'mirror' ,
160122 } ) ;
161- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , {
162- ...DEFAULT_TRANSITION ,
163- duration : 0.2 ,
164- } ) ;
165- frequencyControlsRef . current = animate ( frequencyValue , 2.5 , {
166- ...DEFAULT_TRANSITION ,
167- duration : 0.2 ,
168- } ) ;
169- brightnessControlsRef . current = animate ( brightnessValue , [ 0.5 , 2.5 ] , {
170- duration : 0.2 ,
123+ animateAmplitude ( 1.0 , DEFAULT_TRANSITION ) ;
124+ animateFrequency ( 3.0 , DEFAULT_TRANSITION ) ;
125+ animateBrightness ( [ 1.5 , 2.5 ] , {
126+ duration : 0.3 ,
171127 repeat : Infinity ,
172128 repeatType : 'mirror' ,
173129 } ) ;
174130 return ;
175131 case 'speaking' :
176132 setSpeed ( 50 ) ;
177- scaleControlsRef . current = animate ( scaleValue , 0.35 , DEFAULT_TRANSITION ) ;
178- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
179- frequencyControlsRef . current = animate ( frequencyValue , 1.0 , DEFAULT_TRANSITION ) ;
180- brightnessControlsRef . current = animate ( brightnessValue , 0.5 , DEFAULT_TRANSITION ) ;
181133 return ;
182134 }
183135 } , [
184136 state ,
185137 shape ,
186138 colorScale ,
187- scaleValue ,
188- colorPosition ,
189- amplitudeValue ,
190- frequencyValue ,
191- brightnessValue ,
139+ animateScale ,
140+ animateAmplitude ,
141+ animateFrequency ,
142+ animateBrightness ,
192143 ] ) ;
193144
194145 useEffect ( ( ) => {
195146 if ( state === 'speaking' && volume > 0 ) {
196- scaleControlsRef . current ?. stop ( ) ;
197- amplitudeControlsRef . current ?. stop ( ) ;
198- frequencyControlsRef . current ?. stop ( ) ;
199- brightnessControlsRef . current ?. stop ( ) ;
200-
201- scaleValue . set ( 0.3 - 0.05 * volume ) ;
202- amplitudeValue . set ( 0.5 + 0.2 * volume ) ;
203- frequencyValue . set ( 1 - 1 * volume ) ;
204- brightnessValue . set ( 1.0 + 2.0 * volume ) ;
147+ animateScale ( 0.3 - 0.1 * volume , { duration : 0 } ) ;
148+ animateAmplitude ( 1.0 + 0.2 * volume , { duration : 0 } ) ;
149+ animateFrequency ( 0.7 - 0.3 * volume , { duration : 0 } ) ;
150+ animateBrightness ( 1.5 + 1.0 * volume , { duration : 0 } ) ;
205151 }
206- } , [ state , volume , scaleValue , amplitudeValue , frequencyValue , brightnessValue ] ) ;
152+ } , [ state , volume , animateScale , animateAmplitude , animateFrequency , animateBrightness ] ) ;
207153
208154 return (
209155 < AuroraShaders
0 commit comments