How does a terminal "ASCII animation" work?

Viewed 1640

I am calling it an ASCII animation for lack of a better word. What I am referring to is for example a loading bar, let's say like in pacman (arch package manager) ,that starts like this...

[          ]

and turns over time to this...

[####      ]

From my understanding of stdout I can't seem to wrap my head around this seemingly simple feature.I expect...

[          ]
[#         ]
[###       ]
...

What I'm not understanding is how is it able to print on top of stdout ,(if it's even doing that).

1 Answers

We sometimes think of terminals as just showing text, but they're actually more like browsers, rendering their own little markup in the form of control characters and ANSI terminal escape codes.

Simple, single-line animations are typically done using the Carriage Return control character. By writing a carriage return, the cursor returns to the left-most margin, and you can therefore write over the line again as many times as you'd like.

You'd obviously use a loop but here's an example written out for clarity:

{
  printf '[##    ]'
  sleep 1
  printf '\r[###   ]'
  sleep 1
  printf '\r[####  ]'
}

For more advanced animations, you can e.g. arbitrarily position the cursor by writing special ANSI escape sequences as text. The tput tool is helpful for this in shell scripts, and tput cup 4 50 will output an ANSI sequence to move the cursor to line 4 column 50. This is equivalent to printf '\x1B[4;50H' and just writes a snippet of magic text to the terminal.

Here's this functionality used for a starfield animation (ctrl-c to exit):

while sleep 0.1
do
  tput cup $((RANDOM%LINES)) $((RANDOM%COLUMNS))
  printf "*"
done

Even tools like top and nano show what they show by carefully writing text and control characters to create color, lines, refreshing lists, etc.

Related