gradient 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c198e094a820d5824d667fc1c32ab3c6e5521d4
4
- data.tar.gz: 7e7571355ef7e64e10ffa6ff6b0fab6440fde133
3
+ metadata.gz: 89ea4e065588742732ec1adee2b95bbee71e80e6
4
+ data.tar.gz: 64aff1fdd843d4aae818c65b44ccfe88cc0d4f06
5
5
  SHA512:
6
- metadata.gz: eb0e346f524916b6110a60b143f49b53654eda7b7e8b10e5272c937096daa44df2c6ad4d3192204a8b8145a837a162e3ae941bf5b90b97cc1d32940e8078d003
7
- data.tar.gz: a06de11eafc91cfa4f7d2ba0261dcbbc66a95e1c3aa3c6b4c917ae81be2697ee730b6044ced303037fd17e529c682bb6f94b79f2382ba2544fb3b26fb1a81f79
6
+ metadata.gz: 529165c3d1ae1890d664b593cf2a830ef05c01465e7f6a3831aaa35400ef34eb1855047d2cb719e541c93c6f1e820f41d7514d12ffae9c46ce1962a2b2b68891
7
+ data.tar.gz: 652bf1bf09cb2d368370dda36be71286e4400222419d74579823da7b579539c1469bbed2580d65576325e86d4d00d8914b86dcb32bf6a953ac9b42e060e199e6
data/README.md CHANGED
@@ -2,26 +2,17 @@
2
2
  Library for dealing with color gradients in ruby
3
3
 
4
4
  ## Usage
5
- Gradient works by placing points along two one dimensional planes.
6
- One for color and one for opacity.
7
- Start by creating a few points and use them to create a gradient map.
5
+ Gradient works by placing point vectors along a one dimensional plane.
6
+ Start by creating a few points and pass them to a gradient map.
8
7
 
9
8
  ```ruby
10
- color_points = [
11
- Gradient::ColorPoint.new(0, Color::RGB.new(30, 87, 153)),
12
- Gradient::ColorPoint.new(0.49, Color::RGB.new(41, 137, 216)),
13
- Gradient::ColorPoint.new(0.51, Color::RGB.new(32, 124, 202)),
14
- Gradient::ColorPoint.new(1, Color::RGB.new(125, 185, 232)),
15
- ]
16
-
17
- opacity_points = [
18
- Gradient::OpacityPoint.new(0, 1),
19
- Gradient::OpacityPoint.new(0.5, 0),
20
- Gradient::OpacityPoint.new(1, 1)
21
- ]
22
-
23
- gradient = Gradient::Map.new(color_points, opacity_points)
24
- # => #<Gradient Map #<Point 0 #1e5799ff> #<Point 49.0 #2989d805> #<Point 50.0 #2583d100> #<Point 51.0 #207cca05> #<Point 100 #7db9e8ff>>
9
+ gradient = Gradient::Map.new(
10
+ Gradient::Point.new(0, Color::RGB.new(32, 36, 196), 1.0),
11
+ Gradient::Point.new(0.49, Color::RGB.new(14, 250, 211), 0.1),
12
+ Gradient::Point.new(0.50, Color::RGB.new(171, 25, 12), 0.7),
13
+ Gradient::Point.new(1, Color::RGB.new(15, 212, 162), 0.3)
14
+ )
15
+ # => #<Gradient Map #<Point 0 #2024c4ff> #<Point 49.0 #0efad31a> #<Point 50.0 #ab190cb3> #<Point 100 #0fd4a24d>>
25
16
  ```
26
17
 
27
18
  ### Convert to CSS
@@ -60,6 +51,29 @@ Gradient::GRD.read("./kiwi.grd")
60
51
  # }
61
52
  ```
62
53
 
54
+ ### Separate point vectors for opacity and color
55
+ You're able to control the point vectors for color and opacity separately by using a point merger.
56
+
57
+ ```ruby
58
+ color_points = [
59
+ Gradient::ColorPoint.new(0, Color::RGB.new(30, 87, 153)),
60
+ Gradient::ColorPoint.new(0.49, Color::RGB.new(41, 137, 216)),
61
+ Gradient::ColorPoint.new(0.51, Color::RGB.new(32, 124, 202)),
62
+ Gradient::ColorPoint.new(1, Color::RGB.new(125, 185, 232)),
63
+ ]
64
+
65
+ opacity_points = [
66
+ Gradient::OpacityPoint.new(0, 1),
67
+ Gradient::OpacityPoint.new(0.5, 0),
68
+ Gradient::OpacityPoint.new(1, 1)
69
+ ]
70
+
71
+ points = Gradient::PointMerger.new(color_points, opacity_points).call
72
+
73
+ gradient = Gradient::Map.new(points)
74
+ # => #<Gradient Map #<Point 0 #1e5799ff> #<Point 49.0 #2989d805> #<Point 50.0 #2583d100> #<Point 51.0 #207cca05> #<Point 100 #7db9e8ff>>
75
+ ```
76
+
63
77
  ## Installation
64
78
  Add this line to your application's Gemfile:
65
79
 
@@ -2,6 +2,7 @@ require "gradient/version"
2
2
  require "gradient/color_point"
3
3
  require "gradient/opacity_point"
4
4
  require "gradient/point"
5
+ require "gradient/point_merger"
5
6
  require "gradient/map"
6
7
  require "gradient/grd"
7
8
  require "gradient/css_printer"
@@ -4,5 +4,8 @@ module Gradient
4
4
  def initialize(location, color)
5
5
  @color, @location = color, location
6
6
  end
7
+ def <=>(other)
8
+ self.location <=> other.location
9
+ end
7
10
  end
8
11
  end
@@ -75,7 +75,7 @@ module Gradient
75
75
  end
76
76
 
77
77
  gradients = color_gradients.zip(transparency_gradients).map do |color_points|
78
- Gradient::Map.new(*color_points)
78
+ Gradient::Map.new(Gradient::PointMerger.new(*color_points).call)
79
79
  end
80
80
 
81
81
  @maps = Hash[ @gradient_names.zip(gradients) ]
@@ -1,16 +1,11 @@
1
1
  module Gradient
2
2
  class Map
3
3
 
4
- attr_reader :color_points, :opacity_points, :points
4
+ attr_reader :points, :locations
5
5
 
6
- def initialize(color_points=[], opacity_points=[])
7
- color_points << Gradient::ColorPoint.new(0, Color::RGB.new(255, 255, 255)) if color_points.empty?
8
- opacity_points << Gradient::OpacityPoint.new(0, 1) if opacity_points.empty?
9
- @color_points = sort_points(Array(color_points))
10
- @opacity_points = sort_points(Array(opacity_points))
11
- @all_points = sort_points(@color_points + @opacity_points)
12
- @locations = @all_points.map { |point| point.location }.uniq
13
- @points ||= merge_color_and_opacity_points
6
+ def initialize(*points)
7
+ @points = points.flatten.sort
8
+ @locations = @points.map { |point| point.location }
14
9
  end
15
10
 
16
11
  def inspect
@@ -22,58 +17,5 @@ module Gradient
22
17
  @css_printer.css(**args)
23
18
  end
24
19
 
25
- private def merge_color_and_opacity_points
26
- @locations.map do |location|
27
- selected_points = @all_points.select { |point| point.location == location }
28
- colored, opaque = selected_points.group_by(&:class).values_at(ColorPoint, OpacityPoint)
29
- rgba = if colored && opaque
30
- [colored.first.color, opaque.first.opacity]
31
- elsif colored
32
- point = colored.first
33
- a, b = adjacent_points(@opacity_points, point)
34
- fraction = location_fraction(a, b, point)
35
- [point.color, opacity_difference(fraction, a, b)]
36
- elsif opaque
37
- point = opaque.first
38
- a, b = adjacent_points(@color_points, point)
39
- fraction = location_fraction(a, b, point)
40
- [color_difference(fraction, a, b), point.opacity]
41
- end
42
-
43
- Gradient::Point.new(location, *rgba)
44
- end
45
- end
46
-
47
- private def adjacent_points(bucket, point)
48
- groups = bucket.group_by { |p| triage_point(p, point) }
49
- a = groups.fetch(:same) { groups.fetch(:less) { groups.fetch(:more) } }.max { |p| p.location }
50
- b = groups.fetch(:same) { groups.fetch(:more) { groups.fetch(:less) } }.min { |p| p.location }
51
- return a, b
52
- end
53
-
54
- private def triage_point(a, b)
55
- a.location < b.location ? :less : (a.location > b.location ? :more : :same)
56
- end
57
-
58
- private def color_difference(fraction, a, b)
59
- red = a.color.red + fraction * (b.color.red - a.color.red)
60
- green = a.color.green + fraction * (b.color.green - a.color.green)
61
- blue = a.color.blue + fraction * (b.color.blue - a.color.blue)
62
- Color::RGB.new(red, green, blue)
63
- end
64
-
65
- private def opacity_difference(fraction, a, b)
66
- a.opacity + fraction * (b.opacity - a.opacity)
67
- end
68
-
69
- private def location_fraction(a, b, x)
70
- return 0 if a.location == b.location
71
- (x.location - a.location) / (b.location - a.location)
72
- end
73
-
74
- private def sort_points(points)
75
- points.sort { |a, b| a.location <=> b.location }
76
- end
77
-
78
20
  end
79
21
  end
@@ -4,5 +4,8 @@ module Gradient
4
4
  def initialize(location, opacity)
5
5
  @location, @opacity = location, opacity
6
6
  end
7
+ def <=>(other)
8
+ self.location <=> other.location
9
+ end
7
10
  end
8
11
  end
@@ -11,5 +11,9 @@ module Gradient
11
11
  "#<Point #{location * 100} ##{color.hex}#{"%02x" % (opacity * 255).round}>"
12
12
  end
13
13
 
14
+ def <=>(other)
15
+ self.location <=> other.location
16
+ end
17
+
14
18
  end
15
19
  end
@@ -0,0 +1,70 @@
1
+ module Gradient
2
+ class PointMerger
3
+
4
+ attr_accessor :color_points, :opacity_points
5
+
6
+ def initialize(color_points=[], opacity_points=[])
7
+ color_points << Gradient::ColorPoint.new(0, Color::RGB.new(255, 255, 255)) if color_points.empty?
8
+ opacity_points << Gradient::OpacityPoint.new(0, 1) if opacity_points.empty?
9
+
10
+ @color_points = sort_points(Array(color_points))
11
+ @opacity_points = sort_points(Array(opacity_points))
12
+ @all_points = sort_points(@color_points + @opacity_points)
13
+ @locations = @all_points.map { |point| point.location }.uniq
14
+ end
15
+
16
+ def call
17
+ @locations.map do |location|
18
+ selected_points = @all_points.select { |point| point.location == location }
19
+ colored, opaque = selected_points.group_by(&:class).values_at(ColorPoint, OpacityPoint)
20
+ rgba = if colored && opaque
21
+ [colored.first.color, opaque.first.opacity]
22
+ elsif colored
23
+ point = colored.first
24
+ a, b = adjacent_points(@opacity_points, point)
25
+ fraction = location_fraction(a, b, point)
26
+ [point.color, opacity_difference(fraction, a, b)]
27
+ elsif opaque
28
+ point = opaque.first
29
+ a, b = adjacent_points(@color_points, point)
30
+ fraction = location_fraction(a, b, point)
31
+ [color_difference(fraction, a, b), point.opacity]
32
+ end
33
+
34
+ Gradient::Point.new(location, *rgba)
35
+ end
36
+ end
37
+
38
+ private def adjacent_points(bucket, point)
39
+ groups = bucket.group_by { |p| triage_point(p, point) }
40
+ a = groups.fetch(:same) { groups.fetch(:less) { groups.fetch(:more) } }.max { |p| p.location }
41
+ b = groups.fetch(:same) { groups.fetch(:more) { groups.fetch(:less) } }.min { |p| p.location }
42
+ return a, b
43
+ end
44
+
45
+ private def triage_point(a, b)
46
+ a.location < b.location ? :less : (a.location > b.location ? :more : :same)
47
+ end
48
+
49
+ private def color_difference(fraction, a, b)
50
+ red = a.color.red + fraction * (b.color.red - a.color.red)
51
+ green = a.color.green + fraction * (b.color.green - a.color.green)
52
+ blue = a.color.blue + fraction * (b.color.blue - a.color.blue)
53
+ Color::RGB.new(red, green, blue)
54
+ end
55
+
56
+ private def opacity_difference(fraction, a, b)
57
+ a.opacity + fraction * (b.opacity - a.opacity)
58
+ end
59
+
60
+ private def location_fraction(a, b, x)
61
+ return 0 if a.location == b.location
62
+ (x.location - a.location) / (b.location - a.location)
63
+ end
64
+
65
+ private def sort_points(points)
66
+ points.sort { |a, b| a.location <=> b.location }
67
+ end
68
+
69
+ end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module Gradient
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gradient
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Vieira
@@ -118,6 +118,7 @@ files:
118
118
  - lib/gradient/map.rb
119
119
  - lib/gradient/opacity_point.rb
120
120
  - lib/gradient/point.rb
121
+ - lib/gradient/point_merger.rb
121
122
  - lib/gradient/version.rb
122
123
  homepage: https://github.com/zeeraw/gradient
123
124
  licenses: