Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions gallery/tunnel/tunnel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,46 +32,60 @@ animate() {
height=$(tput lines)
local center_x=$((width / 2))
local center_y=$((height / 2))
local max_radius=$(( (height > width ? height : width) / 2 + 1 ))
local max_radius=$(( (height > width ? height : width) / 2 + 2 ))
local ribbon_spacing=7
local -a radii=()
local frame_counter=0

while true; do
for ((r=1; r < max_radius; r++)); do
local frame_buffer=""
local color=${COLORS[$((r % ${#COLORS[@]}))]}
local char=${CHARS[$((r % ${#CHARS[@]}))]}
local frame_buffer=""
# Add a new ribbon every few frames
if (( frame_counter % ribbon_spacing == 0 )); then
radii+=(1)
fi

# Erase the previous shape
if [ $r -gt 1 ]; then
local -a next_radii=()
for r in "${radii[@]}"; do
if [ $r -gt 0 ]; then
local prev_r=$((r-1))
# Erase the previous shape
for ((i=0; i < prev_r; i++)); do
x1=$((center_x + i)); y1=$((center_y - prev_r + i))
x2=$((center_x + prev_r - i)); y2=$((center_y + i))
x3=$((center_x - i)); y3=$((center_y + prev_r - i))
x4=$((center_x - prev_r + i)); y4=$((center_y - i))
if (( y1 >= 0 && y1 < height && x1 >= 0 && x1 < width )); then frame_buffer+="\e[$((y1 + 1));$((x1 + 1))H "; fi
if (( y2 >= 0 && y2 < height && x2 >= 0 && x2 < width )); then frame_buffer+="\e[$((y2 + 1));$((x2 + 1))H "; fi
if (( y3 >= 0 && y3 < height && x3 >= 0 && x3 < width )); then frame_buffer+="\e[$((y3 + 1));$((x3 + 1))H "; fi
if (( y4 >= 0 && y4 < height && x4 >= 0 && x4 < width )); then frame_buffer+="\e[$((y4 + 1));$((x4 + 1))H "; fi
frame_buffer+="\e[$((y1 + 1));$((x1 + 1))H "
frame_buffer+="\e[$((y2 + 1));$((x2 + 1))H "
frame_buffer+="\e[$((y3 + 1));$((x3 + 1))H "
frame_buffer+="\e[$((y4 + 1));$((x4 + 1))H "
done
fi

local color=${COLORS[$((r % ${#COLORS[@]}))]}
local char=${CHARS[$((r % ${#CHARS[@]}))]}
# Draw a square/diamond shape
for ((i=0; i < r; i++)); do
x1=$((center_x + i)); y1=$((center_y - r + i))
x2=$((center_x + r - i)); y2=$((center_y + i))
x3=$((center_x - i)); y3=$((center_y + r - i))
x4=$((center_x - r + i)); y4=$((center_y - i))
if (( y1 >= 0 && y1 < height && x1 >= 0 && x1 < width )); then frame_buffer+="\e[$((y1 + 1));$((x1 + 1))H${color}${char}"; fi
if (( y2 >= 0 && y2 < height && x2 >= 0 && x2 < width )); then frame_buffer+="\e[$((y2 + 1));$((x2 + 1))H${color}${char}"; fi
if (( y3 >= 0 && y3 < height && x3 >= 0 && x3 < width )); then frame_buffer+="\e[$((y3 + 1));$((x3 + 1))H${color}${char}"; fi
if (( y4 >= 0 && y4 < height && x4 >= 0 && x4 < width )); then frame_buffer+="\e[$((y4 + 1));$((x4 + 1))H${color}${char}"; fi
frame_buffer+="\e[$((y1 + 1));$((x1 + 1))H${color}${char}"
frame_buffer+="\e[$((y2 + 1));$((x2 + 1))H${color}${char}"
frame_buffer+="\e[$((y3 + 1));$((x3 + 1))H${color}${char}"
frame_buffer+="\e[$((y4 + 1));$((x4 + 1))H${color}${char}"
done

printf '%b' "$frame_buffer"
sleep $DELAY
# Increment radius for the next frame, and keep it if it's not too large
local next_r=$((r + 1))
if (( next_r < max_radius )); then
next_radii+=($next_r)
fi
done
# Clear the center after a full cycle
printf "\e[$((center_y + 1));$((center_x + 1))H "

radii=("${next_radii[@]}")
printf '%b' "$frame_buffer"
sleep $DELAY
((frame_counter++))
done
}

Expand Down
1 change: 1 addition & 0 deletions tunnel_output.log

Large diffs are not rendered by default.

Loading