4

I'm trying to animate the following ASCII art. (I have two files right now and may add more later for more fine grained animation.)

$ cat ~/aks1.txt
        \            RTX            /
         \                         /
          \       WAZUH LAB       /
           ]                     [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (A) [ [  [  [ :===='
           ]  ]  ]_].nRn.[_[  [  [
           ]  ]  ]  HHUHH. [  [  [
           ]  ] /   `HN("N  \ [  [
           ]__]/     HNH  "  \[__[
           ]         NNN         [
           ]       / N/" \       [
           ]      /  N H  \      [
          /          N            \
         /           q,            \
        /                           \
$ cat ~/aks2.txt
        \            RTX            /
         \                         /
          \       WAZUH LAB       /
           ]                     [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (A) [ [  [  [ :===='
           ]  ]  ]_].nRn.[_[  [  [
           ]  ]  ] .HHUHH  [  [  [
           ]  ] /  #")NH`   \ [  [
           ]__]/   " HNH     \[__[
           ]         NNN         [
           ]       / "\N         [
           ]         H N  \      [
          /      /     N   \      \
         /      /     ,p    \      \
        /                           \

Here's my code so far:

if [[ -t 0 ]]; then
    old_tty=$(stty --save)
    stty raw -echo min 0
fi
while IFS= read -r REPLY; [[ -z "$REPLY" ]]; do
    clear
    cat ~/aks1.txt
    usleep 500000
    clear
    cat ~/aks2.txt
    ((c++)) && usleep 500000
done
if [[ -t 0 ]]; then
    stty "$old_tty"
fi
echo

Pros:

  1. Simple approach/solution
  2. No complex variable substitution required (at tput cup screen locations)
  3. Works well until ANY key is pressed so no hard-coded COUNTER variable is required for running the life of the animation.
  4. Animation is kind of working (animation is happening, but the output is not rendering perfectly).

Cons:

  1. Animation output is GARBLED/SHITTY.

How can I fix the output?

AKS
  • 16,482
  • 43
  • 166
  • 258

4 Answers4

3

When you switch into raw mode newlines (\n) no longer move the cursor back to the first column. They only move it down a line. You have to print carriage returns (\r) to reset the column.

You could do that by disabling adding them to the end of every line with sed:

sed 's/$/\r/g' ~/aks1.txt

Alternatively, you could skip switching into raw mode and leave the terminal in its default state. To prevent the read command from blocking use read -t 0 to add a 0-second timeout. If the user hasn't pressed a key it'll return immediately instead of waiting for them to press something.

until read -t 0; do
    ...
done
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
1

This version works fine for me on debian/xterm :

function animate {
    local aks1="$(cat ~/aks1.txt)"
    local aks2="$(cat ~/aks2.txt)"
    local c
    for (( c=0; c < 5; c++ )); do
        read -rsn1 -t .001 && return
        clear; printf "%s\n" "$aks1"; sleep .5
        clear; printf "%s\n" "$aks2"; sleep .5
    done
    echo
}
setterm -cursor off
animate
setterm -cursor on
Philippe
  • 20,025
  • 2
  • 23
  • 32
0

This is "my theme") try this.

#!/bin/bash

sprites=( "$(cat aks1.txt)" "$(cat aks2.txt)" )

XY () { printf "\e[$2;${1}H$3"; }
animation () {
    for sprite in "${sprites[@]}"; {
        sleep 0.5
        XY 1 1 "$sprite"
    }    
    animation
}

animation

And check this and this projects to get more ideas about animation)

Ivan
  • 6,188
  • 1
  • 16
  • 23
-1

The solution to Animate ASCII ART, break as soon as any Key is pressed (using alias way):

alias animate_arun='until read -t 0; do clear && cat ~/aks1.txt && sleep .5 && clear && cat ~/aks2.txt && sleep .5; done; echo;'

Putting the above alias in ~/.bash_profile and calling the alias animate_arun did the trick for any new interactive login shell.

Reference post: Animate ASCII art with tput cup until user presses a key

AKS
  • 16,482
  • 43
  • 166
  • 258
  • Arun -1 your own answer appears to address the core issue which was the lack of `\r` at the end of each line, but this was already answered earlier by @JohnKugelman. Why not accept his answer? Additional references to creating an alias appear unrelated to your original question. – rtx13 Apr 16 '20 at 02:54
  • @rtx13 My original post was using alias so I included this one too. I did accept his reply as an answer and upvoted it. `until` didn't work. – AKS Apr 16 '20 at 14:09