Class: CMYKClass::CMYK

Inherits:
Sass::Script::Value::Base
  • Object
show all
Defined in:
lib/sass-cmyk.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cmyk_attrs) ⇒ CMYK

Attributes specified as a hash, representing CMYK percentages, i.e. Sass::Script::Value::CMYK.new(:magenta=>20, :yellow=>30, :black=>40) is equivalent to cmyk(10%,20%,30%,40%)

Raises:

  • (ArgumentError)


11
12
13
14
15
16
# File 'lib/sass-cmyk.rb', line 11

def initialize(cmyk_attrs)
  # Reject all attribute values that are not numbers between 0 and 100
  cmyk_attrs.reject! {|k, v| !(v.class == Fixnum and v.between?(0, 100))}
  raise ArgumentError.new("CMYK Object must be initialized with hash values between 0 and 100 for :cyan, :magenta, :yellow, and :black") unless [:cyan, :magenta, :yellow, :black].all? {|k| cmyk_attrs.key? k}
  @attrs = cmyk_attrs        
end

Instance Attribute Details

#attrsObject (readonly)

Returns the value of attribute attrs.



7
8
9
# File 'lib/sass-cmyk.rb', line 7

def attrs
  @attrs
end

Instance Method Details

#_normalizeObject



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/sass-cmyk.rb', line 46

def _normalize
  # Normalize color components via the following algorithm, per SO (http://stackoverflow.com/a/1530158)
  # C = C - min(C, M, Y)
  # M = M - min(C, M, Y)
  # Y = Y - min(C, M, Y)
  # K = min(100, K + min(C, M, Y))
  cmy_min = [@attrs[:cyan], @attrs[:magenta], @attrs[:yellow]].min
  new_attrs = {:cyan => @attrs[:cyan] - cmy_min,
               :magenta => @attrs[:magenta] - cmy_min,
 :yellow => @attrs[:yellow] - cmy_min,
 :black => [100, @attrs[:black] + cmy_min].min}
end

#blackObject



30
31
32
# File 'lib/sass-cmyk.rb', line 30

def black
  @attrs[:black]
end

#cyanObject



18
19
20
# File 'lib/sass-cmyk.rb', line 18

def cyan
  @attrs[:cyan]
end

#div(other) ⇒ Object

Raises:

  • (ArgumentError)


102
103
104
105
106
107
# File 'lib/sass-cmyk.rb', line 102

def div(other)
  raise ArgumentError.new("Cannot divide #{self} by #{other}. CMYK colors can only be divided by numbers") if !other.is_a?(Sass::Script::Value::Number)
  raise ArgumentError.new("Cannot divide CMYK color #{self} by zero") if other.value == 0
  reciprocal = Sass::Script::Value::Number.new(1.0/other.value)
  self.times(reciprocal)
end

#magentaObject



22
23
24
# File 'lib/sass-cmyk.rb', line 22

def magenta
  @attrs[:magenta]
end

#minus(other) ⇒ Object

Raises:

  • (NoMethodError)


76
77
78
# File 'lib/sass-cmyk.rb', line 76

def minus(other)
  raise NoMethodError.new("Cannot apply subtraction to #{self}. Subtraction not supported for CMYK colors.")
end

#normalizeObject



34
35
36
37
38
# File 'lib/sass-cmyk.rb', line 34

def normalize
  # Return new CMYK object with normalized color components
  new_color_attrs = @attrs.merge(_normalize)
  Sass::Script::Value::CMYK.new(new_color_attrs)
end

#normalize!Object



40
41
42
43
44
# File 'lib/sass-cmyk.rb', line 40

def normalize!
  # Normalize color components in place
  @attrs.merge!(_normalize)
  self
end

#plus(other) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sass-cmyk.rb', line 59

def plus(other)
  if other.is_a?(Sass::Script::Value::CMYK)
    new_color_attrs = {}
    [:cyan, :magenta, :yellow, :black].each do |component|
	  # Add corresponding components of each color, limiting to a max of 100
	  component_sum = [self.attrs[component] + other.attrs[component], 100].min
	  new_color_attrs[component] = component_sum
	end
	# Make new color from summed componenets
	new_color = Sass::Script::Value::CMYK.new(new_color_attrs)
	# Normalize component values
	new_color.normalize!
  else
    raise ArgumentError.new("Cannot add object of class #{other.class} to CMYK color #{self}. Only CMYK colors can be added to CMYK colors")
  end
end

#times(other) ⇒ Object

TODO: This does not work commutatively yet; only works for CMYK * scalar, and not scalar * CMYK To add support for scalar * CMYK, need to override “times” instance method on Sass::Script::Value::Number

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/sass-cmyk.rb', line 82

def times(other)
  raise ArgumentError.new("Cannot multiply #{self} by #{other}. CMYK colors can only be multiplied by numbers") if !other.is_a?(Sass::Script::Value::Number)
  if other.is_unit?('%')
    scale_factor = other.value.to_f / 100
  else
    scale_factor = other.value
  end
  new_color_attrs = {}
  [:cyan, :magenta, :yellow, :black].each do |component|
	# Scale corresponding components of each color by "scale_factor"
	new_color_attrs[component] = (self.attrs[component] * scale_factor).round
  end
  # Raise error if any resulting component attribute is over 100%, as that would mean it's not possible to scale proportionally
  raise ArgumentError.new("Cannot scale #{self} proportionally by #{other}, as that would result in at least one component over 100%") if new_color_attrs.map {|k, v| v}.max > 100
  # Make new color from scaled components
  new_color = Sass::Script::Value::CMYK.new(new_color_attrs)
  # Normalize component values
  new_color.normalize!
end

#to_s(opts = {}) ⇒ Object



109
110
111
# File 'lib/sass-cmyk.rb', line 109

def to_s(opts = {})
  "cmyk(#{@attrs[:cyan]}%,#{@attrs[:magenta]}%,#{@attrs[:yellow]}%,#{@attrs[:black]}%)" 
end

#yellowObject



26
27
28
# File 'lib/sass-cmyk.rb', line 26

def yellow
  @attrs[:yellow]
end