问题
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:
- Simple approach/solution
- No complex variable substitution required (at tput cup screen locations)
- Works well until ANY key is pressed so no hard-coded COUNTER variable is required for running the life of the animation.
- Animation is kind of working (animation is happening, but the output is not rendering perfectly).
Cons:
- Animation output is GARBLED/SHITTY.
How can I fix the output?
回答1:
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
回答2:
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
回答3:
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)
回答4:
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
来源:https://stackoverflow.com/questions/61239780/bash-shell-interactive-session-how-to-fix-ascii-art-animation-output