Reputation: 709
I want to create animation in console, when program waits. There are a lot of simple ways to do this, usually, we just draw symbols in iterations of some cycle. Let our code be:
func Spinner(delay time.Duration) {
for !StopSpinner{
for _, r := range `-\|/` {
fmt.Printf("\r%c", r)
time.Sleep(delay)
}
}
}
The problem is - how to remove animation, when there is no need in it from the console screen. I tried escape sequences like fmt.Print("\b") or fmt.Printf("\r%s", "") but no result. I can not remove last symbol from screen and it concatenates with next text. How do you erase characters already printed to the console?
Upvotes: 5
Views: 4917
Reputation: 11626
All you need to do is print a space (0x20) when you are done and that will overwrite the spinner.
ie: fmt.Fprint(os.Stdout, "\r \r")
to put the cursor back to beginning of line after the space.
Upvotes: 9
Reputation: 709
All you need to do is print a space (0x20) when you are done and that will overwrite the spinner.
ie: fmt.Fprint("\r \r") to put the cursor back to beginning of line after the space.
This answer is helpful, thank you! But, there is an important detail! Because the spinner function has a delay, it cannot stop exactly when StopSpinner boolean flag is set to true. So, I have added a channel for synchronization.
func Spinner(delay time.Duration) {
for !StopSpinner {
for _, r := range `-\|/` {
fmt.Printf("\r%c", r)
time.Sleep(delay)
}
}
fmt.Fprint("\r \r")
c <- struct{}{}
}
Now, calling function waits, while my spinner stop.
var c chan struct{} = make(chan struct{}) // event marker
func callingFunc(){
StopSpinner = false
go Spinner(100 * time.Millisecond)
// do something...
StopSpinner = true
<-c // wait spinner stop
//do something else
}
In my opinion, this is the complete solution!
Upvotes: 4
Reputation: 3394
fmt.Print("\033[H\033[2J")
This will put the cursor in the top left then clear the console as per this document of useful terminal commands:
https://www.student.cs.uwaterloo.ca/~cs452/terminal.html
Upvotes: 2