@@ -66,12 +66,17 @@ pub fn text_animation_state(
6666 return TextAnimationState :: IDLE ;
6767 }
6868 let region_ms = region_ms. max ( 0.0 ) ;
69- let share = ( region_ms / ( TEXT_ANIMATION_DURATION_MS + TEXT_EXIT_DURATION_MS ) ) . min ( 1.0 ) ;
7069 let ramp = |t : f32 , len : f32 | if len > 0.0 { clamp01 ( t / len) } else { 1.0 } ;
71- let enter = ramp ( elapsed_ms. max ( 0.0 ) , TEXT_ANIMATION_DURATION_MS * share) ;
72- let exit = ramp ( region_ms - elapsed_ms, TEXT_EXIT_DURATION_MS * share) ;
73- // Les deux rampes valent 1 à la jonction : prendre la plus petite suffit à les enchaîner.
74- let progress = if name == "pulse" { enter } else { enter. min ( exit) } ;
70+ let progress = if name == "pulse" {
71+ // Pas de sortie à qui céder du temps : le pulse garde sa durée pleine, comme avant.
72+ ramp ( elapsed_ms. max ( 0.0 ) , TEXT_ANIMATION_DURATION_MS )
73+ } else {
74+ let share = ( region_ms / ( TEXT_ANIMATION_DURATION_MS + TEXT_EXIT_DURATION_MS ) ) . min ( 1.0 ) ;
75+ let enter = ramp ( elapsed_ms. max ( 0.0 ) , TEXT_ANIMATION_DURATION_MS * share) ;
76+ let exit = ramp ( region_ms - elapsed_ms, TEXT_EXIT_DURATION_MS * share) ;
77+ // Les deux rampes valent 1 à la jonction : prendre la plus petite suffit à les enchaîner.
78+ enter. min ( exit)
79+ } ;
7580 let eased = ease_out_cubic ( progress) ;
7681 match name {
7782 "fade" => TextAnimationState { opacity : eased, ..TextAnimationState :: IDLE } ,
@@ -228,6 +233,14 @@ mod tests {
228233 assert_eq ! ( s, TextAnimationState :: IDLE ) ;
229234 }
230235
236+ #[ test]
237+ fn a_short_region_does_not_speed_up_pulse ( ) {
238+ // Sans sortie, rien à partager : dans 500 ms, le pulse culmine toujours à 350 ms
239+ // (mi-course de ses 700 ms) au lieu de s'achever là.
240+ let mid = text_animation_state ( Some ( "pulse" ) , TEXT_ANIMATION_DURATION_MS * 0.5 , 500.0 ) ;
241+ assert ! ( ( mid. scale - 1.06 ) . abs( ) < 1e-3 , "échelle {}" , mid. scale) ;
242+ }
243+
231244 #[ test]
232245 fn an_empty_region_does_not_divide_by_zero ( ) {
233246 assert ! ( text_animation_state( Some ( "fade" ) , 0.0 , 0.0 ) . opacity. is_finite( ) ) ;
0 commit comments