AKS
AKS

Reputation: 17336

BASH Shell Interactive Session - How to fix ASCII art animation output?

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?

Upvotes: 4

Views: 1490

Answers (4)

AKS
AKS

Reputation: 17336

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

Upvotes: -1

Ivan
Ivan

Reputation: 7287

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)

Upvotes: 0

Philippe
Philippe

Reputation: 26697

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

Upvotes: 1

John Kugelman
John Kugelman

Reputation: 361849

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

Upvotes: 3

Related Questions