class Gradient::PointMerger
Attributes
color_points[RW]
opacity_points[RW]
Public Class Methods
new(color_points=[], opacity_points=[])
click to toggle source
# File lib/gradient/point_merger.rb, line 6 def initialize(color_points=[], opacity_points=[]) color_points << Gradient::ColorPoint.new(0, Color::RGB.new(255, 255, 255)) if color_points.empty? opacity_points << Gradient::OpacityPoint.new(0, 1) if opacity_points.empty? @color_points = sort_points(Array(color_points)) @opacity_points = sort_points(Array(opacity_points)) @all_points = sort_points(@color_points + @opacity_points) @locations = @all_points.map { |point| point.location }.uniq end
Public Instance Methods
call()
click to toggle source
# File lib/gradient/point_merger.rb, line 16 def call @locations.map do |location| selected_points = @all_points.select { |point| point.location == location } colored, opaque = selected_points.group_by(&:class).values_at(ColorPoint, OpacityPoint) rgba = if colored && opaque [colored.first.color, opaque.first.opacity] elsif colored point = colored.first a, b = adjacent_points(@opacity_points, point) fraction = location_fraction(a, b, point) [point.color, opacity_difference(fraction, a, b)] elsif opaque point = opaque.first a, b = adjacent_points(@color_points, point) fraction = location_fraction(a, b, point) [color_difference(fraction, a, b), point.opacity] end Gradient::Point.new(location, *rgba) end end
Private Instance Methods
adjacent_points(bucket, point)
click to toggle source
# File lib/gradient/point_merger.rb, line 38 def adjacent_points(bucket, point) groups = bucket.group_by { |p| triage_point(p, point) } a = groups.fetch(:same) { groups.fetch(:less) { groups.fetch(:more) } }.max { |p| p.location } b = groups.fetch(:same) { groups.fetch(:more) { groups.fetch(:less) } }.min { |p| p.location } return a, b end
color_difference(fraction, a, b)
click to toggle source
# File lib/gradient/point_merger.rb, line 49 def color_difference(fraction, a, b) red = a.color.red + fraction * (b.color.red - a.color.red) green = a.color.green + fraction * (b.color.green - a.color.green) blue = a.color.blue + fraction * (b.color.blue - a.color.blue) Color::RGB.new(red, green, blue) end
location_fraction(a, b, x)
click to toggle source
# File lib/gradient/point_merger.rb, line 60 def location_fraction(a, b, x) return 0 if a.location == b.location (x.location - a.location) / (b.location - a.location) end
opacity_difference(fraction, a, b)
click to toggle source
# File lib/gradient/point_merger.rb, line 56 def opacity_difference(fraction, a, b) a.opacity + fraction * (b.opacity - a.opacity) end
sort_points(points)
click to toggle source
# File lib/gradient/point_merger.rb, line 65 def sort_points(points) points.sort { |a, b| a.location <=> b.location } end
triage_point(a, b)
click to toggle source
# File lib/gradient/point_merger.rb, line 45 def triage_point(a, b) a.location < b.location ? :less : (a.location > b.location ? :more : :same) end