diff --git a/doc-src/content/reference/compass/helpers.haml b/doc-src/content/reference/compass/helpers.haml
index 9b926219..13d8837a 100644
--- a/doc-src/content/reference/compass/helpers.haml
+++ b/doc-src/content/reference/compass/helpers.haml
@@ -18,6 +18,8 @@ layout: core
All Helpers:
+ * [adjust-lightness()](/docs/reference/compass/helpers/colors/#adjust-lightness)
+ * [adjust-saturation()](/docs/reference/compass/helpers/colors/#adjust-saturation)
* [append-selector()](/docs/reference/compass/helpers/selectors/#append-selector)
* [color-stops()](/docs/reference/compass/helpers/color-stops/)
* [elements-of-type()](/docs/reference/compass/helpers/display/)
@@ -32,4 +34,6 @@ layout: core
* [inline-image()](/docs/reference/compass/helpers/inline-data/#inline-image)
* [nest()](/docs/reference/compass/helpers/selectors/#nest)
* [stylesheet-url()](/docs/reference/compass/helpers/urls/#stylesheet-url)
+ * [scale-lightness()](/docs/reference/compass/helpers/colors/#scale-lightness)
+ * [scale-saturation()](/docs/reference/compass/helpers/colors/#scale-saturation)
diff --git a/doc-src/content/reference/compass/helpers/colors.haml b/doc-src/content/reference/compass/helpers/colors.haml
new file mode 100644
index 00000000..ddf0754d
--- /dev/null
+++ b/doc-src/content/reference/compass/helpers/colors.haml
@@ -0,0 +1,53 @@
+---
+title: Compass Color Helpers
+crumb: Colors
+framework: compass
+meta_description: Helper function for colors.
+layout: core
+classnames:
+ - reference
+ - core
+ - helpers
+---
+%h1 Compass Color Helpers
+%p
+ These color functions are useful for creating generic libraries that have to accept a
+ range of inputs. For more color functions see
+ the sass reference
+ documentation
+
+#adjust-lightness.helper
+ %h3
+ %a(href="#adjust-lightness")
+ adjust-lightness($color, $amount)
+ .details
+ %p
+ Adds $amount
to $color
's lightness value. $amount
+ can be negative.
+
+#adjust-saturation.helper
+ %h3
+ %a(href="#adjust-saturation")
+ adjust-saturation($color, $amount)
+ .details
+ %p
+ Adds $amount
to $color
's saturation value. $amount
+ can be negative.
+
+#scale-lightness.helper
+ %h3
+ %a(href="#scale-lightness")
+ scale-lightness($color, $amount)
+ .details
+ %p
+ Scales $color
's lightness value by $amount
.
+ $amount
can be negative.
+
+#scale-saturation.helper
+ %h3
+ %a(href="#scale-saturation")
+ scale-saturation($color, $amount)
+ .details
+ %p
+ Scales $color
's saturation value by $amount
.
+ $amount
can be negative.
diff --git a/lib/compass/sass_extensions/functions.rb b/lib/compass/sass_extensions/functions.rb
index 007cfc92..083ea6da 100644
--- a/lib/compass/sass_extensions/functions.rb
+++ b/lib/compass/sass_extensions/functions.rb
@@ -4,7 +4,7 @@ end
%w(
selectors enumerate urls display
inline_image image_size gradient_support
- font_files constants lists
+ font_files constants lists colors
).each do |func|
require "compass/sass_extensions/functions/#{func}"
end
@@ -20,6 +20,7 @@ module Sass::Script::Functions
include Compass::SassExtensions::Functions::FontFiles
include Compass::SassExtensions::Functions::Constants
include Compass::SassExtensions::Functions::Lists
+ include Compass::SassExtensions::Functions::Colors
end
# Wierd that this has to be re-included to pick up sub-modules. Ruby bug?
diff --git a/lib/compass/sass_extensions/functions/colors.rb b/lib/compass/sass_extensions/functions/colors.rb
new file mode 100644
index 00000000..29e9d9ee
--- /dev/null
+++ b/lib/compass/sass_extensions/functions/colors.rb
@@ -0,0 +1,44 @@
+module Compass::SassExtensions::Functions::Colors
+
+ # a genericized version of lighten/darken so that negative values can be used.
+ def adjust_lightness(color, amount)
+ assert_type color, :Color
+ assert_type amount, :Number
+ color.with(:lightness => Sass::Util.restrict(color.lightness + amount.value, 0..100))
+ end
+
+ # Scales a color's lightness by some percentage.
+ # If the amount is negative, the color is scaled darker, if positive, it is scaled lighter.
+ # This will never return a pure light or dark color unless the amount is 100%.
+ def scale_lightness(color, amount)
+ assert_type color, :Color
+ assert_type amount, :Number
+ color.with(:lightness => scale_color_value(color.lightness, amount.value))
+ end
+
+ # a genericized version of saturation/desaturate so that negative values can be used.
+ def adjust_saturation(color, amount)
+ assert_type color, :Color
+ assert_type amount, :Number
+ color.with(:saturation => Sass::Util.restrict(color.saturation + amount.value, 0..100))
+ end
+
+ # Scales a color's saturation by some percentage.
+ # If the amount is negative, the color is desaturated, if positive, it is saturated.
+ # This will never return a pure saturated or desaturated color unless the amount is 100%.
+ def scale_saturation(color, amount)
+ assert_type color, :Color
+ assert_type amount, :Number
+ color.with(:saturation => scale_color_value(color.saturation, amount.value))
+ end
+
+ private
+ def scale_color_value(value, amount)
+ if amount > 0
+ value += (100 - value) * (amount / 100.0)
+ elsif amount < 0
+ value += value * amount / 100.0
+ end
+ value
+ end
+end
diff --git a/test/sass_extensions_test.rb b/test/sass_extensions_test.rb
index 52833f70..7d8e018a 100644
--- a/test/sass_extensions_test.rb
+++ b/test/sass_extensions_test.rb
@@ -37,6 +37,28 @@ class SassExtensionsTest < Test::Unit::TestCase
assert_equal "h4, h5, h6", evaluate("headers(4,6)")
end
+ def test_scale_lightness
+ assert_equal "75%", evaluate("lightness(scale-lightness(hsl(50deg, 50%, 50%), 50%))")
+ assert_equal "25%", evaluate("lightness(scale-lightness(hsl(50deg, 50%, 50%), -50%))")
+ end
+
+ def test_adjust_lightness
+ assert_equal "75%", evaluate("lightness(adjust-lightness(hsl(50deg, 50%, 50%), 25%))")
+ assert_equal "25%", evaluate("lightness(adjust-lightness(hsl(50deg, 50%, 50%), -25%))")
+ assert_equal "100%", evaluate("lightness(adjust-lightness(hsl(50deg, 50%, 50%), 500%))")
+ assert_equal "0%", evaluate("lightness(adjust-lightness(hsl(50deg, 50%, 50%), -500%))")
+ end
+
+ def test_scale_saturation
+ assert_equal "75%", evaluate("saturation(scale-saturation(hsl(50deg, 50%, 50%), 50%))")
+ assert_equal "25%", evaluate("saturation(scale-saturation(hsl(50deg, 50%, 50%), -50%))")
+ end
+
+ def test_adjust_saturation
+ assert_equal "75%", evaluate("saturation(adjust-saturation(hsl(50deg, 50%, 50%), 25%))")
+ assert_equal "25%", evaluate("saturation(adjust-saturation(hsl(50deg, 50%, 50%), -25%))")
+ end
+
protected
def evaluate(value)
Sass::Script::Parser.parse(value, 0, 0).perform(Sass::Environment.new).to_s