Skip to content

Commit

Permalink
This adds a new executable called term_plasma
Browse files Browse the repository at this point in the history
that draws a plasma effect on the console. The program accepts an
optional parameter `-n`, which specifies the refresh interval in
seconds. If this parameter is not provided, the program will exit after
one iteration.
  • Loading branch information
flori committed Jul 17, 2024
1 parent 146ed6b commit 22b47dc
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
.rvmrc
Gemfile.lock
coverage
cscope.out
errors.lst
pkg
tags
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ The following executables are provided with Term::ANSIColor:
* `term_mandel`: displays the mandelbrot set in the terminal
* `term_snow`: displays falling snow in the terminal using ANSI movement
sequences.
* `term_plasma`: draws a plasma effect on the console, possibly animated and
refreshed every `-n seconds`.


Additionally the file examples/example.rb in the source/gem-distribution shows
how this library can be used.
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ GemHadar do

test_dir 'tests'
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.rvmrc', 'coverage',
'tags', '.bundle', '.byebug_history', 'errors.lst'
'tags', '.bundle', '.byebug_history', 'errors.lst', 'cscope.out'

readme 'README.md'
executables.merge Dir['bin/*'].map { |x| File.basename(x) }
Expand Down
97 changes: 97 additions & 0 deletions bin/term_plasma
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env ruby

require 'tins/go'
include Tins::GO
require 'term/ansicolor'
include Term::ANSIColor
Term::ANSIColor.true_coloring = ENV['COLORTERM'] =~ /\A(truecolor|24bit)\z/
include Math

# Generates a palette of 256 colors based on sine waves
#
# @return [Array<Array<Integer>>] An array of arrays, each containing
# three integers representing the RGB values of a color.
def generate_palette
(0..255).map { |i|
[
128 + 128 * sin(PI * i / 32.0),
128 + 128 * sin(PI * i / 64.0),
128 + 128 * sin(PI * i / 128.0),
].map { _1.clamp(0, 255).round }
}
end

# Resets the terminal to its original state, and assigns width $w and height
# $h.
def full_reset
$w, $h = Tins::Terminal.cols, Tins::Terminal.lines
$h *= 2
print reset, clear_screen, move_home, hide_cursor
end

# Generates a screen based on a plasma.
#
# @param plasma [Array<Array<Integer>>] An array of arrays, each containing
# three integers representing the RGB values of a color.
# @return [String] The string representation of the screen, each character
# representing a pixel on the screen with the corresponding color.
def generate_screen(plasma)
screen = ''
0.step($h - 1, 2) do |y|
0.upto($w - 1) do |x|
screen << color(plasma[y][x]) + on_color(plasma[y + 1][x]) + ?▀
end
end
screen
end

# Generates a plasma generated based on sine waves
#
# @param now [Float] A value based on the current time in seconds
# @return [Array<Array<Integer>>] An array of arrays, each containing
# three integers representing the RGB values of a color.
def generate_plasma(now)
plasma = Array.new($h) { [ nil ] * $w }
0.upto($h - 1) do |y|
0.upto($w - 1) do |x|
x, y = x.to_f, y.to_f
color = (
128.0 + (128.0 * sin((x / 7.0) - 3.0 * cos(now / 2.0))) +
128.0 + (128.0 * sin((y / 13.0) - 2.0 * sin(now))) +
128.0 + (128.0 * sin(hypot((x - $w / 3.0), (y - $h / 2.0)) / 5.0)) +
128.0 + (128.0 * sin((hypot(x, y) / 5.0) - sin(now / 3.0)))
) / 4.0
plasma[y][x] = $palette[(color + now).round % $palette.size]
end
end
plasma
end

$opts = go('n:')

$palette = generate_palette

begin
$full_reset = true
trap(:SIGWINCH) { $full_reset = true }

loop do
if $full_reset
$full_reset = false
full_reset
end

now = Time.now.to_f / ($opts[?n]&.to_f || 1)
plasma = generate_plasma(now)
print move_home, generate_screen(plasma), reset

if n = $opts[?n]&.to_f
sleep n
else
print move_to_column(1), erase_in_line, show_cursor
exit
end
end
rescue Interrupt
print reset, clear_screen, move_home, show_cursor
end
6 changes: 3 additions & 3 deletions term-ansicolor.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Florian Frank".freeze]
s.date = "2024-07-15"
s.date = "2024-07-16"
s.description = "This library uses ANSI escape sequences to control the attributes of terminal output".freeze
s.email = "[email protected]".freeze
s.executables = ["term_cdiff".freeze, "term_colortab".freeze, "term_decolor".freeze, "term_display".freeze, "term_mandel".freeze, "term_snow".freeze]
s.executables = ["term_cdiff".freeze, "term_colortab".freeze, "term_decolor".freeze, "term_display".freeze, "term_mandel".freeze, "term_plasma".freeze, "term_snow".freeze]
s.extra_rdoc_files = ["README.md".freeze, "lib/term/ansicolor.rb".freeze, "lib/term/ansicolor/attribute.rb".freeze, "lib/term/ansicolor/attribute/color256.rb".freeze, "lib/term/ansicolor/attribute/color8.rb".freeze, "lib/term/ansicolor/attribute/intense_color8.rb".freeze, "lib/term/ansicolor/attribute/text.rb".freeze, "lib/term/ansicolor/attribute/underline.rb".freeze, "lib/term/ansicolor/hsl_triple.rb".freeze, "lib/term/ansicolor/hyperlink.rb".freeze, "lib/term/ansicolor/movement.rb".freeze, "lib/term/ansicolor/ppm_reader.rb".freeze, "lib/term/ansicolor/rgb_color_metrics.rb".freeze, "lib/term/ansicolor/rgb_triple.rb".freeze, "lib/term/ansicolor/version.rb".freeze]
s.files = [".all_images.yml".freeze, ".gitignore".freeze, ".utilsrc".freeze, "CHANGES".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/term_cdiff".freeze, "bin/term_colortab".freeze, "bin/term_decolor".freeze, "bin/term_display".freeze, "bin/term_mandel".freeze, "bin/term_snow".freeze, "examples/example.rb".freeze, "examples/lambda-red-plain.ppm".freeze, "examples/lambda-red.png".freeze, "examples/lambda-red.ppm".freeze, "lib/term/ansicolor.rb".freeze, "lib/term/ansicolor/.keep".freeze, "lib/term/ansicolor/attribute.rb".freeze, "lib/term/ansicolor/attribute/color256.rb".freeze, "lib/term/ansicolor/attribute/color8.rb".freeze, "lib/term/ansicolor/attribute/intense_color8.rb".freeze, "lib/term/ansicolor/attribute/text.rb".freeze, "lib/term/ansicolor/attribute/underline.rb".freeze, "lib/term/ansicolor/hsl_triple.rb".freeze, "lib/term/ansicolor/hyperlink.rb".freeze, "lib/term/ansicolor/movement.rb".freeze, "lib/term/ansicolor/ppm_reader.rb".freeze, "lib/term/ansicolor/rgb_color_metrics.rb".freeze, "lib/term/ansicolor/rgb_triple.rb".freeze, "lib/term/ansicolor/version.rb".freeze, "term-ansicolor.gemspec".freeze, "tests/ansicolor_test.rb".freeze, "tests/attribute_test.rb".freeze, "tests/hsl_triple_test.rb".freeze, "tests/hyperlink_test.rb".freeze, "tests/ppm_reader_test.rb".freeze, "tests/rgb_color_metrics_test.rb".freeze, "tests/rgb_triple_test.rb".freeze, "tests/test_helper.rb".freeze]
s.files = [".all_images.yml".freeze, ".gitignore".freeze, ".utilsrc".freeze, "CHANGES".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/term_cdiff".freeze, "bin/term_colortab".freeze, "bin/term_decolor".freeze, "bin/term_display".freeze, "bin/term_mandel".freeze, "bin/term_plasma".freeze, "bin/term_snow".freeze, "examples/example.rb".freeze, "examples/lambda-red-plain.ppm".freeze, "examples/lambda-red.png".freeze, "examples/lambda-red.ppm".freeze, "lib/term/ansicolor.rb".freeze, "lib/term/ansicolor/.keep".freeze, "lib/term/ansicolor/attribute.rb".freeze, "lib/term/ansicolor/attribute/color256.rb".freeze, "lib/term/ansicolor/attribute/color8.rb".freeze, "lib/term/ansicolor/attribute/intense_color8.rb".freeze, "lib/term/ansicolor/attribute/text.rb".freeze, "lib/term/ansicolor/attribute/underline.rb".freeze, "lib/term/ansicolor/hsl_triple.rb".freeze, "lib/term/ansicolor/hyperlink.rb".freeze, "lib/term/ansicolor/movement.rb".freeze, "lib/term/ansicolor/ppm_reader.rb".freeze, "lib/term/ansicolor/rgb_color_metrics.rb".freeze, "lib/term/ansicolor/rgb_triple.rb".freeze, "lib/term/ansicolor/version.rb".freeze, "term-ansicolor.gemspec".freeze, "tests/ansicolor_test.rb".freeze, "tests/attribute_test.rb".freeze, "tests/hsl_triple_test.rb".freeze, "tests/hyperlink_test.rb".freeze, "tests/ppm_reader_test.rb".freeze, "tests/rgb_color_metrics_test.rb".freeze, "tests/rgb_triple_test.rb".freeze, "tests/test_helper.rb".freeze]
s.homepage = "https://github.com/flori/term-ansicolor".freeze
s.licenses = ["Apache-2.0".freeze]
s.rdoc_options = ["--title".freeze, "Term-ansicolor - Ruby library that colors strings using ANSI escape sequences".freeze, "--main".freeze, "README.md".freeze]
Expand Down

0 comments on commit 22b47dc

Please sign in to comment.