@@ -29,8 +29,6 @@ export interface AnimatedStatusIconProps {
2929 isTyping ?: boolean ;
3030 /** Whether there's an error */
3131 isError ?: boolean ;
32- /** Volume level (0-1) for volume-responsive animations */
33- volumeLevel ?: number ;
3432 /** Base color for inactive bars */
3533 baseColor ?: string ;
3634 /** Override animation type */
@@ -63,7 +61,6 @@ const AnimatedStatusIcon: React.FC<AnimatedStatusIconProps> = ({
6361 isSpeaking,
6462 isTyping,
6563 isError,
66- volumeLevel = 0 ,
6764 baseColor = '#9CA3AF' ,
6865 animationType : overrideAnimationType ,
6966 animationSpeed : overrideAnimationSpeed ,
@@ -229,97 +226,30 @@ const AnimatedStatusIcon: React.FC<AnimatedStatusIconProps> = ({
229226 }
230227
231228 case 'scale' : {
232- // Speech pattern animation - each bar reacts differently to volume
229+ // Scale animation for line layout
233230 if ( useLineLayout && 'delay' in bar ) {
234231 const lineBar = bar as LineBar ;
232+ const cycleTime = ( time + lineBar . delay ) % 1 ;
233+ const scaleTime = cycleTime < 0.5 ? cycleTime * 2 : 2 - cycleTime * 2 ;
235234
236- // Use volume level to determine overall activity
237- const volumeIntensity = Math . max ( 0 , Math . min ( 1 , volumeLevel ) ) ;
238-
239- // Each bar has different sensitivity and frequency response
240- const barCharacteristics = [
241- { sensitivity : 0.8 , frequency : 1.2 , baseActivity : 0.3 } , // Bar 0 - Low freq, less sensitive
242- { sensitivity : 1.0 , frequency : 1.8 , baseActivity : 0.4 } , // Bar 1 - Mid-low freq
243- { sensitivity : 1.2 , frequency : 2.5 , baseActivity : 0.5 } , // Bar 2 - Center, most responsive
244- { sensitivity : 1.0 , frequency : 2.0 , baseActivity : 0.4 } , // Bar 3 - Mid-high freq
245- { sensitivity : 0.9 , frequency : 1.5 , baseActivity : 0.35 } , // Bar 4 - High freq
246- ] ;
247-
248- const barChar = barCharacteristics [ index ] || barCharacteristics [ 2 ] ;
249-
250- // Create dynamic time-based variation for each bar
251- const time = animationTime % 1 ;
252- const barTime = ( time * barChar . frequency ) % 1 ;
253-
254- // Generate pseudo-random speech-like pattern
255- const speechPattern =
256- Math . sin ( barTime * 2 * Math . PI ) * 0.3 +
257- Math . sin ( barTime * 6 * Math . PI ) * 0.2 +
258- Math . sin ( barTime * 12 * Math . PI ) * 0.1 ;
259-
260- // Each bar responds differently based on volume and its characteristics
261- const barResponse = volumeIntensity * barChar . sensitivity ;
262-
263- // Combine base activity, volume response, and speech pattern
264- const activity = Math . max (
265- 0 ,
266- Math . min (
267- 1 ,
268- barChar . baseActivity +
269- barResponse * 0.6 +
270- speechPattern * volumeIntensity * 0.4
271- )
272- ) ;
273-
274- // Scale the bar height based on activity
275- const heightScale = 0.7 + activity * 1.1 ; // Range from 0.7x to 1.8x
276- const height = lineBar . baseHeight * heightScale ;
277- const y = 12 - height / 2 ;
278-
279- // Opacity varies with activity
280- const opacity = 0.4 + activity * 0.6 ;
235+ // Ease in-out cubic
236+ const easeInOutCubic = ( t : number ) => {
237+ return t < 0.5 ? 4 * t * t * t : 1 - Math . pow ( - 2 * t + 2 , 3 ) / 2 ;
238+ } ;
239+
240+ const easedTime = easeInOutCubic ( scaleTime ) ;
241+ // Scale from base height to max height while maintaining the relative proportions
242+ const scaleFactor = 1 + easedTime * 0.5 ; // Scale up to 1.5x
243+ const height = lineBar . baseHeight * scaleFactor ;
244+ const y = 12 - height / 2 ; // Keep bars centered vertically
281245
282246 return {
283- opacity,
247+ opacity : 1 ,
284248 height,
285249 y,
286250 transform : '' ,
287251 } ;
288252 }
289-
290- // For circular layout, create a wave-like speech pattern
291- if ( ! useLineLayout ) {
292- const volumeIntensity = Math . max ( 0 , Math . min ( 1 , volumeLevel ) ) ;
293- const time = animationTime % 1 ;
294-
295- // Create different wave patterns for each bar
296- const barAngle = ( index / actualBarCount ) * 2 * Math . PI ;
297- const wavePattern =
298- Math . sin ( time * 4 * Math . PI + barAngle ) * 0.3 +
299- Math . sin ( time * 8 * Math . PI + barAngle * 2 ) * 0.2 +
300- Math . sin ( time * 16 * Math . PI + barAngle * 3 ) * 0.1 ;
301-
302- // Each bar has different sensitivity based on position
303- const positionSensitivity =
304- 0.7 + 0.3 * Math . sin ( barAngle + Math . PI / 4 ) ;
305-
306- const activity = Math . max (
307- 0 ,
308- Math . min (
309- 1 ,
310- 0.3 +
311- volumeIntensity * positionSensitivity * 0.5 +
312- wavePattern * volumeIntensity * 0.2
313- )
314- ) ;
315-
316- return {
317- opacity : 0.4 + activity * 0.6 ,
318- transform :
319- activity > 0.5 ? `scale(${ 1 + ( activity - 0.5 ) * 0.4 } )` : '' ,
320- } ;
321- }
322-
323253 return { opacity : 1 , transform : '' } ;
324254 }
325255
0 commit comments