BASH Shell Interactive Session - 如何修复 ASCII 艺术动画输出?

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

我正在尝试为以下 ASCII 艺术制作动画。 (我现在有两个文件,以后可能会添加更多文件以获得更精细的动画效果。)

$ 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    \      \
        /                           \

到目前为止,这是我的代码:

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

优点:

  1. 简单approach/solution
  2. 不需要复杂的变量替换(在 tput cup 屏幕位置)
  3. 在按下任何键之前效果很好,因此 运行 动画的生命周期不需要硬编码的 COUNTER 变量。
  4. 动画有点工作(动画正在发生,但输出渲染不完美)。

缺点:

  1. 动画输出为GARBLED/SHITTY。

如何修复输出?

当您切换到原始模式换行符 (\n) 时,不再将光标移回第一列。他们只会将它向下移动一条线。您必须打印回车 returns (\r) 才能重置列。

您可以通过使用 sed 禁用将它们添加到每一行的末尾来做到这一点:

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

或者,您可以跳过切换到原始模式的步骤,让终端保持默认状态。要防止 read 命令阻塞,请使用 read -t 0 添加 0 秒超时。如果用户没有按下某个键,它会立即 return 而不是等待他们按下某些东西。

until read -t 0; do
    ...
done

这个版本在 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

Animate ASCII ART的解决方法,一按任意键就中断(使用alias方式):

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

将上述别名放入 ~/.bash_profile 并调用别名 animate_arun 对任何新的交互式登录都有效 shell.

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

这是 "my theme") 试试这个。

#!/bin/bash

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

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

animation

并检查 this and this 个项目以获得更多关于动画的想法)