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 ,
@@ -20,12 +21,28 @@ import { cn } from '@/lib/utils';
2021import { AuroraShaders , type AuroraShadersProps } from './aurora-shaders' ;
2122
2223const DEFAULT_SPEED = 10 ;
23- const DEFAULT_AMPLITUDE = 0.5 ;
24+ const DEFAULT_AMPLITUDE = 2 ;
2425const DEFAULT_FREQUENCY = 0.5 ;
2526const DEFAULT_SCALE = 0.2 ;
2627const DEFAULT_BRIGHTNESS = 1.5 ;
2728const DEFAULT_TRANSITION : ValueAnimationTransition = { duration : 0.5 , ease : 'easeOut' } ;
2829
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+ }
45+
2946export const audioShaderVisualizerVariants = cva ( [ 'aspect-square' ] , {
3047 variants : {
3148 size : {
@@ -58,25 +75,10 @@ export function AudioShaderVisualizer({
5875 AuroraShadersProps &
5976 VariantProps < typeof audioShaderVisualizerVariants > ) {
6077 const [ speed , setSpeed ] = useState ( DEFAULT_SPEED ) ;
61- const [ amplitude , setAmplitude ] = useState ( DEFAULT_AMPLITUDE ) ;
62- const [ frequency , setFrequency ] = useState ( DEFAULT_FREQUENCY ) ;
63- const [ scale , setScale ] = useState ( DEFAULT_SCALE ) ;
64- const [ brightness , setBrightness ] = useState ( DEFAULT_BRIGHTNESS ) ;
65-
66- const amplitudeValue = useMotionValue ( DEFAULT_AMPLITUDE ) ;
67- const frequencyValue = useMotionValue ( DEFAULT_FREQUENCY ) ;
68- const scaleValue = useMotionValue ( DEFAULT_SCALE ) ;
69- const brightnessValue = useMotionValue ( DEFAULT_BRIGHTNESS ) ;
70-
71- const amplitudeControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
72- const frequencyControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
73- const scaleControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
74- const brightnessControlsRef = useRef < AnimationPlaybackControlsWithThen | null > ( null ) ;
75-
76- useMotionValueEvent ( amplitudeValue , 'change' , ( value ) => setAmplitude ( value ) ) ;
77- useMotionValueEvent ( frequencyValue , 'change' , ( value ) => setFrequency ( value ) ) ;
78- useMotionValueEvent ( scaleValue , 'change' , ( value ) => setScale ( value ) ) ;
79- useMotionValueEvent ( brightnessValue , 'change' , ( value ) => setBrightness ( value ) ) ;
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 ) ;
8082
8183 const volume = useTrackVolume ( audioTrack as TrackReference , {
8284 fftSize : 512 ,
@@ -87,101 +89,67 @@ export function AudioShaderVisualizer({
8789 switch ( state ) {
8890 case 'disconnected' :
8991 setSpeed ( 5 ) ;
90- scaleControlsRef . current = animate ( scaleValue , 0.2 , DEFAULT_TRANSITION ) ;
91- amplitudeControlsRef . current = animate ( amplitudeValue , 1.2 , DEFAULT_TRANSITION ) ;
92- frequencyControlsRef . current = animate ( frequencyValue , 0.4 , DEFAULT_TRANSITION ) ;
93- 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 ) ;
9496 return ;
97+ case 'listening' :
9598 case 'connecting' :
96- setSpeed ( 50 ) ;
97- scaleControlsRef . current = animate ( scaleValue , 0.3 , DEFAULT_TRANSITION ) ;
98- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
99- frequencyControlsRef . current = animate ( frequencyValue , 1 , DEFAULT_TRANSITION ) ;
100- brightnessControlsRef . current = animate ( brightnessValue , [ 0.5 , 2.5 ] , {
101- duration : 1 ,
102- repeat : Infinity ,
103- repeatType : 'mirror' ,
104- } ) ;
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 ) ;
105104 return ;
106105 case 'initializing' :
107106 setSpeed ( 30 ) ;
108- scaleControlsRef . current = animate ( scaleValue , 0.3 , DEFAULT_TRANSITION ) ;
109- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
110- frequencyControlsRef . current = animate ( frequencyValue , 1 , DEFAULT_TRANSITION ) ;
111- 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 ] , {
112111 duration : 0.2 ,
113112 repeat : Infinity ,
114113 repeatType : 'mirror' ,
115114 } ) ;
116115 return ;
117- case 'listening' :
118- setSpeed ( 20 ) ;
119- scaleControlsRef . current = animate ( scaleValue , [ 0.3 , 0.35 ] , {
120- duration : 1.5 ,
121- repeat : Infinity ,
122- repeatType : 'mirror' ,
123- } ) ;
124- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
125- frequencyControlsRef . current = animate ( frequencyValue , 1.0 , DEFAULT_TRANSITION ) ;
126- brightnessControlsRef . current = animate ( brightnessValue , [ 1.5 , 2.5 ] , {
127- duration : 1.5 ,
128- repeat : Infinity ,
129- repeatType : 'mirror' ,
130- } ) ;
131- return ;
132116 case 'thinking' :
133- setSpeed ( 50 ) ;
134- scaleControlsRef . current = animate ( scaleValue , [ 0.35 , 0.3 ] , {
135- duration : 0.5 ,
117+ setSpeed ( 30 ) ;
118+ animateScale ( [ 0.15 , 0.13 ] , {
119+ duration : 0.3 ,
136120 repeat : Infinity ,
137121 repeatType : 'mirror' ,
138122 } ) ;
139- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , {
140- ...DEFAULT_TRANSITION ,
141- duration : 0.2 ,
142- } ) ;
143- frequencyControlsRef . current = animate ( frequencyValue , 2.5 , {
144- ...DEFAULT_TRANSITION ,
145- duration : 0.2 ,
146- } ) ;
147- brightnessControlsRef . current = animate ( brightnessValue , [ 0.5 , 2.5 ] , {
148- 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 ,
149127 repeat : Infinity ,
150128 repeatType : 'mirror' ,
151129 } ) ;
152130 return ;
153131 case 'speaking' :
154132 setSpeed ( 50 ) ;
155- scaleControlsRef . current = animate ( scaleValue , 0.35 , DEFAULT_TRANSITION ) ;
156- amplitudeControlsRef . current = animate ( amplitudeValue , 0.5 , DEFAULT_TRANSITION ) ;
157- frequencyControlsRef . current = animate ( frequencyValue , 1.0 , DEFAULT_TRANSITION ) ;
158- brightnessControlsRef . current = animate ( brightnessValue , 0.5 , DEFAULT_TRANSITION ) ;
159133 return ;
160134 }
161135 } , [
162136 state ,
163137 shape ,
164138 colorScale ,
165- scaleValue ,
166- colorPosition ,
167- amplitudeValue ,
168- frequencyValue ,
169- brightnessValue ,
139+ animateScale ,
140+ animateAmplitude ,
141+ animateFrequency ,
142+ animateBrightness ,
170143 ] ) ;
171144
172145 useEffect ( ( ) => {
173146 if ( state === 'speaking' && volume > 0 ) {
174- scaleControlsRef . current ?. stop ( ) ;
175- amplitudeControlsRef . current ?. stop ( ) ;
176- frequencyControlsRef . current ?. stop ( ) ;
177- brightnessControlsRef . current ?. stop ( ) ;
178-
179- scaleValue . set ( 0.35 - 0.05 * volume ) ;
180- amplitudeValue . set ( 0.5 + 0.2 * volume ) ;
181- frequencyValue . set ( 1 - 0.3 * volume ) ;
182- brightnessValue . set ( 1.5 + 1.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 } ) ;
183151 }
184- } , [ state , volume , scaleValue , amplitudeValue , frequencyValue , brightnessValue ] ) ;
152+ } , [ state , volume , animateScale , animateAmplitude , animateFrequency , animateBrightness ] ) ;
185153
186154 return (
187155 < AuroraShaders
0 commit comments