animations.go
1 // Package utils provides terminal animation utilities 2 package utils 3 4 import ( 5 "fmt" 6 "os" 7 "time" 8 ) 9 10 // AnimationStyle defines supported animation types 11 type AnimationStyle int 12 13 const ( 14 AnimationStyleSpinner AnimationStyle = iota 15 AnimationStyleProgress 16 ) 17 18 // AnimationConfig contains animation parameters 19 type AnimationConfig struct { 20 Style AnimationStyle 21 Message string 22 Delay time.Duration 23 } 24 25 // DefaultConfig provides sensible defaults 26 func DefaultConfig() AnimationConfig { 27 return AnimationConfig{ 28 Style: AnimationStyleSpinner, 29 Message: "Processing", 30 Delay: 100 * time.Millisecond, 31 } 32 } 33 34 // ThinkingAnimation manages animation rendering 35 type ThinkingAnimation struct { 36 frames []string 37 config AnimationConfig 38 } 39 40 // NewThinkingAnimation creates an animation instance 41 func NewThinkingAnimation(config AnimationConfig) *ThinkingAnimation { 42 var frames []string 43 switch config.Style { 44 case AnimationStyleSpinner: 45 frames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} 46 case AnimationStyleProgress: 47 frames = []string{"[ ]", "[= ]", "[== ]", "[=== ]", "[====]"} 48 } 49 50 return &ThinkingAnimation{ 51 frames: frames, 52 config: config, 53 } 54 } 55 56 // Update renders a single animation frame 57 func (ta *ThinkingAnimation) Update(frame int) { 58 frameIdx := frame % len(ta.frames) 59 fmt.Printf("\r\x1b[36m%s %s\x1b[0m", ta.frames[frameIdx], ta.config.Message) 60 os.Stdout.Sync() 61 } 62 63 // Run executes the full animation sequence 64 func (ta *ThinkingAnimation) Run() { 65 go func() { 66 for i := 0; i < 50; i++ { 67 ta.Update(i) 68 time.Sleep(ta.config.Delay) 69 } 70 fmt.Printf("\r\x1b[K") // Clear line 71 }() 72 } 73 74 // Stop clears the animation and stops rendering 75 func (ta *ThinkingAnimation) Stop() { 76 fmt.Printf("\r\x1b[K") // Clear line 77 } 78 79 // UpdateThinkingAnimation provides quick default animation 80 func UpdateThinkingAnimation(frame int) { 81 config := AnimationConfig{ 82 Style: AnimationStyleSpinner, 83 Message: "Thinking", 84 Delay: 100 * time.Millisecond, 85 } 86 animation := NewThinkingAnimation(config) 87 animation.Update(frame) 88 }