scripts

random scripts
git clone https://git.parazyd.org/scripts
Log | Files | Refs

rain (2550B)


      1 #!/bin/bash
      2 RAINS=("|" "│" "┃" "┆" "┇" "┊" "┋" "╽" "╿")
      3 COLORS=("\e[37m" "\e[37;1m")
      4 # More from 256 color mode
      5 for i in {244..255}; do
      6   COLORS=("${COLORS[@]}" "\e[38;5;${i}m")
      7 done
      8 NRAINS=${#RAINS[@]}
      9 NCOLORS=${#COLORS[@]}
     10 NUM_RAIN_METADATA=5
     11 
     12 
     13 sigwinch() {
     14   TERM_WIDTH=$(tput cols)
     15   TERM_HEIGHT=$(tput lines)
     16   STEP_DURATION=0.025
     17   ((MAX_RAINS = TERM_WIDTH * TERM_HEIGHT / 4))
     18   ((MAX_RAIN_LENGTH = TERM_HEIGHT < 10 ? 1 : TERM_HEIGHT / 10))
     19   # In percentage
     20   ((NEW_RAIN_ODD = TERM_HEIGHT > 50 ? 100 : TERM_HEIGHT * 2))
     21   ((NEW_RAIN_ODD = NEW_RAIN_ODD * 75 / 100))
     22   ((FALLING_ODD = TERM_HEIGHT > 25 ? 100 : TERM_HEIGHT * 4))
     23   ((FALLING_ODD = FALLING_ODD * 90 / 100))
     24   }
     25 
     26 do_exit() {
     27   echo -ne "\e[${TERM_HEIGHT};1H\e[0K"
     28 
     29   # Show cursor and echo stdin
     30   echo -ne "\e[?25h"
     31   stty echo
     32   exit 0
     33   }
     34 
     35 do_render() {
     36   # Clean screen first
     37   for ((idx = 0; idx < num_rains * NUM_RAIN_METADATA; idx += NUM_RAIN_METADATA)); do
     38     X=${rains[idx]}
     39     Y=${rains[idx + 1]}
     40     LENGTH=${rains[idx + 4]}
     41     for ((y = Y; y < Y + LENGTH; y++)); do
     42       (( y < 1 || y > TERM_HEIGHT )) && continue
     43       echo -ne "\e[${y};${X}H "
     44     done
     45   done
     46 
     47   for ((idx = 0; idx < num_rains * NUM_RAIN_METADATA; idx += NUM_RAIN_METADATA)); do
     48     if ((100 * RANDOM / 32768 < FALLING_ODD)); then
     49       # Falling
     50       if ((++rains[idx + 1] > TERM_HEIGHT)); then
     51         # Out of screen, bye sweet <3
     52         rains=("${rains[@]:0:idx}"
     53                "${rains[@]:idx+NUM_RAIN_METADATA:num_rains*NUM_RAIN_METADATA}")
     54         ((num_rains--))
     55         continue
     56       fi
     57     fi
     58     X=${rains[idx]}
     59     Y=${rains[idx + 1]}
     60     RAIN=${rains[idx + 2]}
     61     COLOR=${rains[idx + 3]}
     62     LENGTH=${rains[idx + 4]}
     63     for ((y = Y; y < Y + LENGTH; y++)); do
     64       (( y < 1 || y > TERM_HEIGHT )) && continue
     65       echo -ne "\e[${y};${X}H${COLOR}${RAIN}"
     66     done
     67   done
     68   }
     69 
     70 trap do_exit TERM INT
     71 trap sigwinch WINCH
     72 # no echo stdin and hide the cursor
     73 stty -echo
     74 echo -ne "\e[?25l"
     75 
     76 echo -ne "\e[2J"
     77 rains=()
     78 sigwinch
     79 while :; do
     80   read -n 1 -t $STEP_DURATION ch
     81   case "$ch" in
     82     q|Q)
     83       do_exit
     84       ;;
     85   esac
     86 
     87   if ((num_rains < MAX_RAINS)) && ((100 * RANDOM / 32768 < NEW_RAIN_ODD)); then
     88     # Need new |, 1-based
     89     RAIN="${RAINS[NRAINS * RANDOM / 32768]}"
     90     COLOR="${COLORS[NCOLORS * RANDOM / 32768]}"
     91     LENGTH=$((MAX_RAIN_LENGTH * RANDOM / 32768 + 1))
     92     X=$((TERM_WIDTH * RANDOM / 32768 + 1))
     93     Y=$((1 - LENGTH))
     94     rains=("${rains[@]}" "$X" "$Y" "$RAIN" "$COLOR" "$LENGTH")
     95     ((num_rains++))
     96   fi
     97 
     98   # let rain fall!
     99   do_render
    100 done