class Pixelart::Gradient

Public Class Methods

new( *stops ) click to toggle source
# File lib/pixelart/gradient.rb, line 13
def initialize( *stops )
  ## note:  convert stop colors to rgb triplets e.g.
  ##         from #ffffff to [255,255,255]
  ##              #000000 to [0,0,0]  etc.
  @stops = stops.map do |stop|
             stop = Color.parse( stop )
             [Color.r(stop), Color.g(stop), Color.b(stop)]
           end
end

Public Instance Methods

colors( steps ) click to toggle source
# File lib/pixelart/gradient.rb, line 24
 def colors( steps )
   segments = @stops.size - 1

   ## note: gradient will include start (first)
   ##   AND stop color (last) - stop color is NOT excluded for now!!
   if segments == 1
      start = @stops[0]
      stop  = @stops[1]

      gradient = linear_gradient( start, stop, steps,
                                  include_stop: true )
   else
     steps_per_segment, mod = steps.divmod( segments )
     raise ArgumentError, "steps (#{steps}) must be divisible by # of segments (#{segments}); expected mod of 0 but got #{mod}"   if mod != 0

     gradient = []
     segments.times do |segment|
       start = @stops[segment]
       stop  = @stops[segment+1]
       include_stop =  (segment == segments-1)  ## note: only include stop if last segment!!

       # print "  segment #{segment+1}/#{segments} #{steps_per_segment} color(s) - "
       # print "  start: #{start.inspect}  "
       # print  include_stop ? 'include' : 'exclude'
       # print " stop:  #{stop.inspect}"
       # print "\n"

       gradient += linear_gradient( start, stop, steps_per_segment,
                                    include_stop: include_stop )
     end
   end

   ## convert to color (Integer)
   gradient.map do |color|
     Color.rgb( *color )
   end
end
interpolate( start, stop, steps, n ) click to toggle source
# File lib/pixelart/gradient.rb, line 64
def interpolate( start, stop, steps, n )
  ## note: n - expected to start with 1,2,3,etc.
  color = []
  3.times do |i|
    stepize = Float(stop[i] - start[i]) / Float(steps-1)
    value = stepize * n
    ## convert back to Integer from Float
    ##   add 0.5 for rounding up (starting with 0.5) - why? why not?
    value = (value+0.5).to_i
    value = start[i] + value

    color << value
  end
  color
end
linear_gradient( start, stop, steps, include_stop: true ) click to toggle source
# File lib/pixelart/gradient.rb, line 81
 def linear_gradient( start, stop, steps,
                      include_stop: true )

  gradient = [start]  ## auto-add start color (first color in gradient)

  if include_stop
    1.upto( steps-2 ).each do |n|  ## sub two (-2), that is, start and stop color
      gradient << interpolate( start, stop, steps, n )
    end
    # note: use original passed in stop color (should match calculated)
    gradient << stop
  else
    1.upto( steps-1 ).each do |n|  ## sub one (-1), that is, start color only
      ## note: add one (+1) to steps because stop color gets excluded (not included)!!
      gradient << interpolate( start, stop, steps+1, n )
    end
  end

  gradient
end