Prevent Animation from clearing the screen
vegidio opened this issue ยท 5 comments
Hey,
I'm using Terminal.textAnimation
in my application, but it when the animation starts it clears all text that I printed before. Is there a way to prevent this from happening?
Thanks!
Animations don't clear the screen when they start. Can you share a minimized version of the code you're trying?
What terminal, os, and target are you using?
Yes, I can give you the entire source code actually since it's in my open source project ๐
- The entry point of the project is here Main.kt
- On line 24 I call the method
getSubmissions
. - In the
getSubmissions
function I print some things on lines 20, 33 and 38.
This is just to give you some context; the code above is the one that will disappear when the animations start:
- Now back in the
Main.kt
file, I call the functiondownloadMedia
on line 30. - The function
downloadMedia
prints two things on the screen: aprogressAnimation
and atextAnimation
. You can see the code where I update the text animation on line 45 and where I stop it on line 81.
But the problem begins already on step 4 above. As soon as the animation is updated, all the content that I printed on steps 1-3 disappear from the screen. But if I comment out the animation (steps 4-5 above), then the texts that I printed on steps 1-3 are not cleared.
I confirmed that if I comment out the textAnimation
code, but I leave the progressAnimation
, the progressAnimation
does NOT clear the screen. What is clearing the screen seems to be only textAnimation
.
I even created a video on asciinema to show what's happening:
- In the video above you will notice in the 00:00:06 mark that I print the message
๐ Collecting 100 posts from user atomicbrunette18
- But in the 00:00:09 mark, when the
progressAnimation
and thetextAnimation
are executed, the text๐ Collecting 100 posts from user atomicbrunette18
that I printed before is gone.
In the example above my code is running inside a Docker container, but this problem also occurs if I run my program outside Docker, from my Mac terminal (I'm using iTerm2).
I hope this helps you identify the problem. Thanks for helping.
Sorry! After I shared my entire project I realized that it's much simpler to do what you originally asked, which is to share a minimal reproducible code. Here is an example that I just created:
package io.vinicius.rmd
import com.github.ajalt.mordant.animation.Animation
import com.github.ajalt.mordant.animation.progressAnimation
import com.github.ajalt.mordant.animation.textAnimation
import com.github.ajalt.mordant.rendering.TextStyles
import com.github.ajalt.mordant.terminal.Terminal
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlin.random.Random
import kotlin.time.Duration.Companion.seconds
val t = Terminal()
fun main() {
t.print("\n๐ Test ${TextStyles.bold("Test")} Test")
runBlocking { delay(5.seconds) }
val words = List(100) {
(1..100).map { Random.nextInt(97, 123).toChar() }.joinToString("")
}
val anim = printMostRecent()
val progress = t.progressAnimation {
text("Downloading")
percentage()
progressBar(width = 50)
completed()
speed(" posts/sec")
timeRemaining()
}
progress.updateTotal(words.size.toLong())
val current = mutableListOf<String>()
words.forEachIndexed { index, s ->
current.add(s)
progress.update(index + 1)
anim.update(current.takeLast(5))
}
progress.stop()
anim.stop()
}
fun printMostRecent(): Animation<List<String>> {
return t.textAnimation { list ->
list.joinToString("\n", "\n") { it }
}
}
With this code you will see that Test Test Test
string that I print in the very beginning is cleared when the animation starts.
Ok, now I'm feeling stupid, but despite what I've said before, it seems that progressAnimation
is also clearing any text printed before. I could swear it was not doing this before ๐ค
In any case, it seems that both progressAnimation
and textAnimation
are clearing the screen.
Also, sorry for spamming your mailbox with multiple updates on this issue.
Here's a fully minimized repro:
t.println("xxxxxxx")
val b = t.textAnimation<String> { it }
b.update("foo")
b.update("foo\nbar")
The issue was that you were changing the size of the animation while it was running and mordant was trying to move the cursor to clear a space the size of the new frame, not the previous frame.
BTW, animations assume the cursor is on the start of a line before they draw for the first time, so you should use t.println
instead of t.print
to avoid the first frame of the animation drawing incorrectly.