colour 0.3 → 0.4.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.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+ group :development do
3
+ gem "bundler", "~> 1.0.0"
4
+ gem "jeweler", "~> 1.6.4"
5
+ gem "rspec", "~> 2.6"
6
+ gem "rcov", ">= 0"
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.4)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.9.2)
11
+ rcov (0.9.9)
12
+ rspec (2.6.0)
13
+ rspec-core (~> 2.6.0)
14
+ rspec-expectations (~> 2.6.0)
15
+ rspec-mocks (~> 2.6.0)
16
+ rspec-core (2.6.4)
17
+ rspec-expectations (2.6.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.6.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1.0.0)
26
+ jeweler (~> 1.6.4)
27
+ rcov
28
+ rspec (~> 2.6)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Wes Devauld
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,18 +1,40 @@
1
- # Look in the tasks/setup.rb file for the various options that can be
2
- # configured in this Rakefile. The .rake files in the tasks directory
3
- # are where the options are used.
1
+ # encoding: utf-8
4
2
 
5
- load 'tasks/setup.rb'
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ require 'rspec'
6
+ require 'rspec/core/rake_task'
7
+ require 'rake'
8
+ require 'jeweler'
6
9
 
7
- ensure_in_path 'lib'
8
- require 'colour'
10
+ begin
11
+ Bundler.setup(:default, :development)
12
+ rescue Bundler::BundlerError => e
13
+ $stderr.puts e.message
14
+ $stderr.puts "Run `bundle install` to install missing gems"
15
+ exit e.status_code
16
+ end
9
17
 
10
- task :default => 'spec:run'
18
+ Jeweler::Tasks.new do |gem|
19
+ gem.name = "colour"
20
+ gem.homepage = "http://github.com/wdevauld/colour"
21
+ gem.license = "MIT"
22
+ gem.summary = %Q{Colour manipulation library supporting RGB and HSV representations}
23
+ gem.description = %Q{Support for computation of colour swatches in both the RGB and HSV colour representations}
24
+ gem.email = "wes@devauld.ca"
25
+ gem.authors = ["Wes Devauld"]
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
11
28
 
12
- PROJ.name = 'colour'
13
- PROJ.authors = 'Wes Devauld'
14
- PROJ.email = 'wes@devauld.ca'
15
- PROJ.url = 'http://code.devauld.ca/git/colour/'
16
- PROJ.rubyforge_name = 'colour'
17
- PROJ.version = '0.3'
18
- PROJ.exclude = %w(.git)
29
+ desc "Run all specs"
30
+ RSpec::Core::RakeTask.new(:spec) do |t|
31
+ t.verbose = false
32
+ end
33
+
34
+ desc "Run all specs with rcov"
35
+ RSpec::Core::RakeTask.new(:coverage) do |t|
36
+ t.rcov = true
37
+ t.rcov_opts = %w{--exclude gems\/,spec\/}
38
+ t.verbose = true
39
+ end
40
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.4.0
data/colour.gemspec CHANGED
Binary file
data/lib/colour.rb CHANGED
@@ -1,165 +1,123 @@
1
- # $Id$
2
-
3
- # Equivalent to a header guard in C/C++
4
- # Used to prevent the class/module from being loaded more than once
5
- unless defined? Colour
6
-
1
+ # Colour is intended to be a mixin for all representations of colour. It is not intended
2
+ # to be initialized on its own
7
3
  module Colour
8
- def to_rgb
9
- self
10
- end
4
+ def to_rgb
5
+ self
6
+ end
11
7
 
12
- def to_hsv
13
- self
14
- end
15
-
16
- def web_hex
17
- self.to_rgb.web_hex
18
- end
8
+ def to_hsv
9
+ self
10
+ end
11
+
12
+ def web_hex
13
+ self.to_rgb.web_hex
14
+ end
19
15
 
20
- def hex
21
- self.to_rgb.hex
22
- end
16
+ def hex
17
+ self.to_rgb.hex
18
+ end
23
19
 
24
- def web_safe(depth=1)
25
- self.to_rgb.web_safe(depth)
26
- end
27
-
28
- def to_s
29
- self.to_rgb.web_hex
30
- end
31
-
32
- # Return the complementary colour
33
- def complementary
34
- rotate_hue(180)
35
- end
36
-
37
- # Return two colours spread distance apart opposite
38
- # the colour wheel
39
- def split_complementary(spread=60)
40
- c = self.class.name.downcase
41
- hsv = self.to_hsv
42
- v = [HSV.new(((hsv.h + 540 - spread / 2) % 360),hsv.s,hsv.v).send("to_" + c),
43
- HSV.new(((hsv.h + 540 + spread / 2) % 360),hsv.s,hsv.v).send("to_" + c)]
44
- if block_given? then
45
- v.each do |color| yield color end
46
- end
47
- v
48
- end
20
+ def web_safe(depth=1)
21
+ self.to_rgb.web_safe(depth)
22
+ end
23
+
24
+ def to_s
25
+ self.to_rgb.web_hex
26
+ end
27
+
28
+ # Return the complementary colour
29
+ def complementary
30
+ rotate_hue(180)[0]
31
+ end
32
+
33
+ # Return two colours spread distance apart opposite
34
+ # the colour wheel
35
+ def split_complementary(spread=60)
36
+ c = self.class.name.downcase
37
+ hsv = self.to_hsv
38
+ v = [HSV.new(((hsv.h + 540 - spread / 2) % 360),hsv.s,hsv.v).send("to_" + c),
39
+ HSV.new(((hsv.h + 540 + spread / 2) % 360),hsv.s,hsv.v).send("to_" + c)]
40
+ if block_given? then
41
+ v.each do |color| yield color end
42
+ end
43
+ v
44
+ end
49
45
 
50
- # Move the specified number of degrees, for the
51
- # specified number of steps
52
- def rotate_hue(degrees=180, steps=1)
53
- c = self.class.name.downcase
54
- hsv = self.to_hsv
55
- v = []
56
- (1..steps).each do |i|
57
- v << HSV.new((hsv.h + (degrees * i) + 360 * i) % 360, hsv.s, hsv.v).send("to_" + c)
58
- end
59
- if block_given? then
60
- v.each do |color| yield color end
61
- end
62
- v
63
- end
46
+ # Move the specified number of degrees, for the
47
+ # specified number of steps
48
+ def rotate_hue(degrees=180, steps=1)
49
+ c = self.class.name.downcase
50
+ hsv = self.to_hsv
51
+ v = []
52
+ (1..steps).each do |i|
53
+ v << HSV.new((hsv.h + (degrees * i) + 360 * i) % 360, hsv.s, hsv.v).send("to_" + c)
54
+ end
55
+ if block_given? then
56
+ v.each do |color| yield color end
57
+ end
58
+ v
59
+ end
64
60
 
65
- def analogous(degrees=30, steps=5, &block)
66
- if block_given? then
67
- rotate_hue(degrees, steps) do |c|
68
- block.call(c)
69
- end
70
- else
71
- rotate_hue(degrees, steps)
72
- end
73
- end
61
+ def analogous(degrees=30, steps=5, &block)
62
+ if block_given? then
63
+ rotate_hue(degrees, steps) do |c|
64
+ block.call(c)
65
+ end
66
+ else
67
+ rotate_hue(degrees, steps)
68
+ end
69
+ end
74
70
 
75
- def triadic(&block)
76
- if block_given? then
77
- rotate_hue(120, 2) do |c|
78
- block.call(c)
79
- end
80
- else
81
- rotate_hue(120,2)
82
- end
83
- end
84
-
85
-
86
- def gradient_to(colour, steps=10)
87
- c = self.class.name.downcase
88
- origin = self.to_rgb
89
- destination = colour.to_rgb
90
- gradient = []
91
-
92
- #TODO: *_range isn't really being used
93
- red_range = destination.r - origin.r
94
- red_increment = red_range / steps
95
- green_range = destination.g - origin.g
96
- green_increment = green_range / steps
97
- blue_range = destination.b - origin.b
98
- blue_increment = blue_range / steps
99
-
100
- steps.times do |i|
101
- intermediate = RGB.new(
102
- origin.r + red_increment * i,
103
- origin.g + green_increment * i,
104
- origin.b + blue_increment * i
105
- )
106
- gradient << intermediate.send("to_" + c)
107
- if block_given? then
108
- yield intermediate.send("to_" + c)
109
- end
110
- end
111
- gradient
112
- end
113
-
114
- #Bones specific stuff
115
-
116
- # :stopdoc:
117
- VERSION = '0.2.1'
118
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
119
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
120
- # :startdoc:
121
-
122
- # Returns the version string for the library.
123
- #
124
- def self.version
125
- VERSION
126
- end
127
-
128
- # Returns the library path for the module. If any arguments are given,
129
- # they will be joined to the end of the libray path using
130
- # <tt>File.join</tt>.
131
- #
132
- def self.libpath( *args )
133
- args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
134
- end
135
-
136
- # Returns the lpath for the module. If any arguments are given,
137
- # they will be joined to the end of the path using
138
- # <tt>File.join</tt>.
139
- #
140
- def self.path( *args )
141
- args.empty? ? PATH : ::File.join(PATH, *args)
142
- end
143
-
144
- # Utility method used to rquire all files ending in .rb that lie in the
145
- # directory below this file that has the same name as the filename passed
146
- # in. Optionally, a specific _directory_ name can be passed in such that
147
- # the _filename_ does not have to be equivalent to the directory.
148
- #
149
- def self.require_all_libs_relative_to( fname, dir = nil )
150
- dir ||= ::File.basename(fname, '.*')
151
- search_me = ::File.expand_path(
152
- ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
153
-
154
- Dir.glob(search_me).sort.each {|rb| require rb}
155
- end
156
- end # module Colour
157
-
158
- Colour.require_all_libs_relative_to __FILE__
159
- require 'rgb'
160
- require 'standard_colours'
161
- require 'hsv'
162
-
163
- end # unless defined?
164
-
165
- # EOF
71
+ def triadic(&block)
72
+ if block_given? then
73
+ rotate_hue(120, 2) do |c|
74
+ block.call(c)
75
+ end
76
+ else
77
+ rotate_hue(120,2)
78
+ end
79
+ end
80
+
81
+
82
+ def gradient_to(colour, steps=10)
83
+ c = self.class.name.downcase
84
+ origin = self.to_rgb
85
+ destination = colour.to_rgb
86
+ gradient = []
87
+
88
+ #Special Case, if some joker asks for a gradient of one step
89
+ # the range calculation will result in NaN
90
+ if steps == 1 then
91
+ if block_given? then
92
+ yield self
93
+ end
94
+ return [self]
95
+ end
96
+
97
+ #TODO: *_range isn't really being used
98
+ red_range = destination.r - origin.r
99
+ red_increment = red_range / (steps - 1)
100
+ green_range = destination.g - origin.g
101
+ green_increment = green_range / (steps - 1)
102
+ blue_range = destination.b - origin.b
103
+ blue_increment = blue_range / (steps - 1)
104
+
105
+ steps.times do |i|
106
+ intermediate = RGB.new(
107
+ origin.r + red_increment * i,
108
+ origin.g + green_increment * i,
109
+ origin.b + blue_increment * i
110
+ )
111
+ gradient << intermediate.send("to_" + c)
112
+ if block_given? then
113
+ yield intermediate.send("to_" + c)
114
+ end
115
+ end
116
+ gradient
117
+ end
118
+ end
119
+
120
+ require_relative 'rgb'
121
+ require_relative 'hsv'
122
+ require_relative 'standard_colours'
123
+ require_relative 'gradient'
data/lib/gradient.rb ADDED
@@ -0,0 +1,23 @@
1
+ class Gradient
2
+ def initialize(origin, destination)
3
+ @origin = origin
4
+ @destination = destination
5
+ end
6
+
7
+ def colour_at(distance_percent)
8
+ c = @origin.class.to_s.downcase
9
+
10
+ origin_rgb = @origin.to_rgb
11
+ destination_rgb = @destination.to_rgb
12
+
13
+ delta_r = destination_rgb.r - origin_rgb.r
14
+ delta_g = destination_rgb.g - origin_rgb.g
15
+ delta_b = destination_rgb.b - origin_rgb.b
16
+
17
+ approximation = RGB.new(delta_r * distance_percent + origin_rgb.r,
18
+ delta_g * distance_percent + origin_rgb.g,
19
+ delta_b * distance_percent + origin_rgb.b)
20
+ approximation.send("to_" + c)
21
+ end
22
+
23
+ end
data/lib/hsv.rb CHANGED
@@ -22,15 +22,15 @@ class HSV
22
22
  q = @v * (1 - @s * f)
23
23
  t = @v * (1 - @s * (1 - f))
24
24
  case i
25
- when 0:
25
+ when 0 then
26
26
  RGB.new(v,t,p)
27
- when 1:
27
+ when 1 then
28
28
  RGB.new(q,v,p)
29
- when 2:
29
+ when 2 then
30
30
  RGB.new(p,v,t)
31
- when 3:
31
+ when 3 then
32
32
  RGB.new(p,q,v)
33
- when 4:
33
+ when 4 then
34
34
  RGB.new(t,p,v)
35
35
  else
36
36
  RGB.new(v,p,q)