Here’s a little something pulled out of one of my personal projects. It’s a class to help with single line animations on the command line. You construct it with an output device (something supporting <<, like STDOUT) and a list of objects (components). When you tell it to draw, it blanks out the current line and then draws it by converting the list of components to a string and writing it to the display. ...

Here’s a little something pulled out of one of my personal projects. It’s a class to help with single line animations on the command line. You construct it with an output device (something supporting <<, like STDOUT) and a list of objects (components). When you tell it to draw, it blanks out the current line and then draws it by converting the list of components to a string and writing it to the display.


  class LineDisplay
    def initialize(out, components)
      @out, @components = out, components
    end

    def draw
      @out << "\r" << " " * @current_length << "\r" if @current_length
      string = @components.join
      @current_length = string.length
      @out << string
      @out.flush
    end
  end

If you combine altering the components that the line display holds references to with calling draw repeatedly from a loop, you can perform a nice little animation, such as this


  class Spinner
    STATES = ["|", "/", "-", "\\"]

    def initialize(state, direction)
      @state, @direction = state, direction
    end

    def step
      @state = (@state + (1 * @direction)) % STATES.length
    end

    def to_s
      STATES[@state]
    end
  end

  components = []
  0.upto(3) do |starting_state|
    components << " " 
    components << Spinner.new(starting_state, 1)
  end

  components << " Weee!!!!" 

  3.downto(0) do |starting_state|
    components << " " 
    components << Spinner.new(starting_state, -1)
  end
  spinners = components.select {|o| Spinner === o}

  display = LineDisplay.new(STDOUT, components)

  loop do
    display.draw
    sleep 0.15
    spinners.each {|s| s.step}
  end

The last 5 lines of the code above are where the real magic happens. display.draw redraws the line, sleep pauses to control the animation framerate, and spinners.each {|s| s.step} makes the spinners spin! Put it all together and it looks something like this


   - \ | / Weee!!!! / | \ -

but more, well, animated. Try it for yourself!

Sorry, comments are closed for this article.