gradient 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: