Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Bleigh committed Aug 16, 2008
0 parents commit 4584a02
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 0 deletions.
19 changes: 19 additions & 0 deletions MIT_LICENSE.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (c) 2008 Michael Bleigh and Intridea, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
21 changes: 21 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
= Colorist

Colorist is a library built to handle the conversion, comparison, and
manipulation of colors in Ruby projects with an emphasis on W3C standards
and CSS-style hex notation.

== Example

require 'colorist'
include Colorist

gray = Color.new(0x333333)
gray + gray # => #<Color #666666>
gray - "#333" # => #<Color #000000>

gray.invert # => #<Color #cccccc>
gray.brightness # => 0.2

gray.contrast_with("#f00")

Copyright (c) 2008 Michael Bleigh and Intridea, Inc. Released under the MIT open source license.
18 changes: 18 additions & 0 deletions colorist.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Gem::Specification.new do |s|
s.name = "colorist"
s.version = "0.0.1"
s.date = "2008-08-16"
s.summary = "A library built to handle the easy conversion and manipulation of colors."
s.email = "michael@intridea.com"
s.homepage = "http://github.com/mbleigh/colorist"
s.description = "Colorist is a library built to handle the easy conversion and manipulation of colors with a special emphasis on W3C standards and CSS-style hex color notation."
s.has_rdoc = true
s.authors = ["Michael Bleigh"]
s.files = [ "MIT_LICENSE.rdoc",
"README.rdoc",
"lib/colorist.rb",
"lib/colorist/color.rb",
"lib/colorist/core_extensions.rb" ]
s.rdoc_options = ["--main", "README.rdoc"]
s.extra_rdoc_files = ["MIT_LICENSE.rdoc", "README.rdoc"]
end
2 changes: 2 additions & 0 deletions lib/colorist.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require 'colorist/color'
require 'colorist/core_extensions'
229 changes: 229 additions & 0 deletions lib/colorist/color.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
module Colorist
class Color
attr_accessor :r, :g, :b

CSS_COLOR_NAMES = { "maroon" => 0x800000,
"red" => 0xff0000,
"orange" => 0xffa500,
"yellow" => 0xffff00,
"olive" => 0x808000,
"purple" => 0x800080,
"fuchsia" => 0xff00ff,
"white" => 0xffffff,
"lime" => 0x00ff00,
"green" => 0x008000,
"navy" => 0x000080,
"blue" => 0x0000ff,
"aqua" => 0x00ffff,
"teal" => 0x008080,
"black" => 0x000000,
"silver" => 0xc0c0c0,
"gray" => 0x808080 }

# Creates a new color with the hex color provided as a number (i.e. 0x112233)
def initialize(color=0x000000)
string = "%.6x" % color
@r = string[0..1].hex
@g = string[2..3].hex
@b = string[4..5].hex
end

# Initialize a color based on RGB values. By default, the values
# should be between 0 and 255. If you use the option <tt>:percent => true</tt>,
# the values should then be between 0.0 and 1.0.
def self.from_rgb(r,g,b,options={})
color = Colorist::Color.new
# convert from 0.0 to 1.0 to 0 to 255 if the :percent option is used
if options[:percent]
color.r, color.g, color.b = r * 255, g * 255, b * 255
end
color.r, color.g, color.b = r, g, b
color
end

# Converts a CSS hex string into a color. Works both with the
# full form (i.e. <tt>#ffffff</tt>) and the abbreviated form (<tt>#fff</tt>). Can
# also take any of the 16 named CSS colors.
def self.from_string(some_string)
if matched = some_string.match(/\A#([0-9a-f]{3})\z/i)
color = Colorist::Color.from_rgb(*matched[1].split(//).collect{|v| "#{v}#{v}".hex })
elsif matched = some_string.match(/\A#([0-9a-f]{6})\z/)
color = Colorist::Color.new
color.r = matched[1][0..1].hex
color.g = matched[1][2..3].hex
color.b = matched[1][4..5].hex
elsif CSS_COLOR_NAMES.key?(some_string)
color = Colorist::Color.new(CSS_COLOR_NAMES[some_string])
else
raise ArgumentError, "Must provide a valid CSS hex color or color name.", caller
end
color
end

# Create a new color from the provided object. Duplicates Color objects
# and attempts to call <tt>to_color</tt> on other objects. Will raise
# an ArgumentError if it is unable to coerce the color.
def self.from(some_entity)
case some_entity
when Colorist::Color
some_entity.dup
else
raise ArgumentError, "#{some_entity.class.to_s} cannot be coerced into a color.", caller unless some_entity.respond_to?(:to_color)
some_entity.to_color
end
end

# Create a duplicate of this color.
def dup
Colorist::Color.from_rgb(@r,@g,@b)
end

# Add the individual RGB values of two colors together. You
# may also use an equivalent numeric or string color representation.
#
# Examples:
#
# gray = Colorist::Color.new(0x333333)
# gray + "#300" # => <Color #663333>
# gray + 0x000000 # => <Color #333333>
# white = "white".to_color
# gray + white # => <Color #ffffff>
def +(other_color)
other_color = Colorist::Color.from(other_color)
color = self.dup
color.r += other_color.r
color.g += other_color.g
color.b += other_color.b
color
end

# Subtract the individual RGB values of the two colors together.
# You may also use an equivalent numeric or string color representation.
def -(other_color)
other_color = Colorist::Color.from(other_color)
color = self.dup
color.r -= other_color.r
color.g -= other_color.g
color.b -= other_color.b
color
end

# Compares colors based on brightness.
def <=>(other_color)
other_color = Colorist::Color.from(other_color)
brightness <=> other_color.brightness
end

# Compares colors based on brightness.
def < (other_color)
other_color = Colorist::Color.from(other_color)
brightness < other_color.brightness
end

# Compares colors based on brightness.
def > (other_color)
other_color = Colorist::Color.from(other_color)
brightness > other_color.brightness
end

# Equal if the red, green, and blue values are identical.
def ==(other_color)
other_color = Colorist::Color.from(other_color)
other_color.r == self.r && other_color.g == self.g && other_color.b == self.b
end

# Equal if the brightnesses of the two colors are identical.
def ===(other_color)
other_color = Colorist::Color.from(other_color)
other_color.brightness == brightness
end

def r=(value) #:nodoc:
@r = value; normalize; end
def g=(value) #:nodoc:
@g = value; normalize; end
def b=(value) #:nodoc:
@b = value; normalize; end

# Outputs a string representation of the color in the desired format.
# The available formats are:
#
# * +:css+ - As a CSS hex string (i.e. <tt>#ffffff</tt>) (default)
# * +:css_rgb+ - As a CSS RGB value string (i.e. <tt>rgb(255,255,255)</tt>)
# * +:rgb+ - As an RGB triplet (i.e. <tt>1.0, 1.0, 1.0</tt>)
def to_s(format=:css)
case format
when :css
"#%.2x%.2x%.2x" % [r, g, b]
when :css_rgb
"rgb(%.2f,%.2f,%.2f)" % [r, g, b]
when :rgb
"%.3f, %.3f, %.3f" % [r / 255, g / 255, b / 255]
end
end

def inspect
"#<Color #{to_s(:css)}>"
end

# Returns the perceived brightness of the provided color on a
# scale of 0.0 to 1.0 based on the formula provided. The formulas
# available are:
#
# * +:w3c+ - <tt>((r * 299 + g * 587 + b * 114) / 1000 / 255</tt>
# * +:standard+ - <tt>sqrt(0.241 * r^2 + 0.691 * g^2 + 0.068 * b^2) / 255</tt>
def brightness(formula=:w3c)
case formula
when :standard
Math.sqrt(0.241 * r**2 + 0.691 * g**2 + 0.068 * b**2) / 255
when :w3c
((r * 299 + g * 587 + b * 114) / 255000.0)
end
end

# Contrast this color with another color using the provided formula. The
# available formulas are:
#
# * +:w3c+ - <tt>(max(r1 r2) - min(r1 r2)) + (max(g1 g2) - min(g1 g2)) + (max(b1 b2) - min(b1 b2))</tt>
def contrast_with(other_color, formula=:w3c)
other_color = Color.from(other_color)
case formula
when :w3c
(([self.r, other_color.r].max - [self.r, other_color.r].min) +
([self.g, other_color.g].max - [self.g, other_color.g].min) +
([self.b, other_color.b].max - [self.b, other_color.b].min)) / 765.0
end
end

# Returns the opposite of the current color.
def invert
Color.from_rgb(255 - r, 255 - g, 255 - b)
end

# Converts the current color to grayscale using the brightness
# formula provided. See #brightness for a description of the
# available formulas.
def to_grayscale(formula=:w3c)
b = brightness(formula)
Color.from_rgb(255 * b, 255 * b, 255 * b)
end

# Returns an appropriate text color (either black or white) based on
# the brightness of this color. The +threshold+ specifies the brightness
# cutoff point.
def text_color(threshold=0.6, formula=:standard)
brightness(formula) > threshold ? Colorist::Color.new(0x000000) : Colorist::Color.new(0xffffff)
end

protected

def normalize #:nodoc:
@r = 255 if @r > 255
@g = 255 if @g > 255
@b = 255 if @b > 255
@r = 0 if @r < 0
@g = 0 if @g < 0
@b = 0 if @b < 0
end
end
end
26 changes: 26 additions & 0 deletions lib/colorist/core_extensions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
class Integer
# Converts a hexadecimal number into a Color. Must be
# the equivalent of the full hexadecimal form (for example,
# <tt>0x123456</tt>).
def to_color
Colorist::Color.new(self)
end
end

class Float
# Converts a number from 0.0 to 1.0 to the grayscale equivalent
# of that brightness value. Especially useful for adding percentages
# to a color.
def to_color
Colorist::Color.from_rgb(self * 255, self * 255, self * 255)
end
end

class String
# Converts a CSS-style color string to a Color. Can be
# in the full form (<tt>#112233</tt>), the abbreviated form
# (<tt>#123</tt>) or a CSS named color (<tt>"black"</tt> or <tt>"maroon"</tt>).
def to_color
Colorist::Color.from_string(self)
end
end

0 comments on commit 4584a02

Please sign in to comment.