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