Module: Sass::Script::Functions
- Included in:
- EvaluationContext
- Defined in:
- lib/sass/script/functions.rb
Overview
Methods in this module are accessible from the SassScript context. For example, you can write
$color = hsl(120deg, 100%, 50%)
and it will call #hsl.
The following functions are provided:
Note: These functions are described in more detail below.
RGB Functions
rgb($red, $green, $blue)
: Converts an rgb(red, green, blue)
triplet into a color.
rgba($red, $green, $blue, $alpha)
: Converts an rgba(red, green, blue, alpha)
quadruplet into a color.
rgba($color, $alpha) : Adds an alpha layer to any color value.
red($color) : Gets the red component of a color.
green($color) : Gets the green component of a color.
blue($color) : Gets the blue component of a color.
mix($color-1, $color-2, [$weight]) : Mixes two colors together.
HSL Functions
hsl($hue, $saturation, $lightness)
: Converts an hsl(hue, saturation, lightness)
triplet into a color.
hsla($hue, $saturation, $lightness, $alpha)
: Converts an hsla(hue, saturation, lightness, alpha)
quadruplet into a color.
hue($color) : Gets the hue component of a color.
saturation($color) : Gets the saturation component of a color.
lightness($color) : Gets the lightness component of a color.
adjust-hue($color, $degrees) : Changes the hue of a color.
lighten($color, $amount) : Makes a color lighter.
darken($color, $amount) : Makes a color darker.
saturate($color, $amount) : Makes a color more saturated.
desaturate($color, $amount) : Makes a color less saturated.
grayscale($color) : Converts a color to grayscale.
complement($color) : Returns the complement of a color.
invert($color) : Returns the inverse of a color.
Opacity Functions
alpha($color) / opacity($color) : Gets the alpha component (opacity) of a color.
rgba($color, $alpha) : Add or change an alpha layer for any color value.
opacify($color, $amount) / fade-in($color, $amount) : Makes a color more opaque.
transparentize($color, $amount) / fade-out($color, $amount) : Makes a color more transparent.
Other Color Functions
adjust-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha]) : Increase or decrease any of the components of a color.
scale-color($color, [$red], [$green], [$blue], [$saturation], [$lightness], [$alpha]) : Fluidly scale one or more components of a color.
change-color($color, [$red], [$green], [$blue], [$hue], [$saturation], [$lightness], [$alpha]) : Changes one or more properties of a color.
ie-hex-str($color) : Converts a color into the format understood by IE filters.
String Functions
unquote($string) : Removes the quotes from a string.
quote($string) : Adds quotes to a string.
Number Functions
percentage($value) : Converts a unitless number to a percentage.
round($value) : Rounds a number to the nearest whole number.
ceil($value) : Rounds a number up to the nearest whole number.
floor($value) : Rounds a number down to the nearest whole number.
abs($value) : Returns the absolute value of a number.
min($x1, $x2, ...) : Finds the minimum of several values.
max($x1, $x2, ...) : Finds the maximum of several values.
List Functions #list-functions
length($list) : Returns the length of a list.
nth($list, $n) : Returns a specific item in a list.
join($list1, $list2, [$separator]) : Joins together two lists into one.
append($list1, $val, [$separator]) : Appends a single value onto the end of a list.
Introspection Functions
type-of($value) : Returns the type of a value.
unit($number) : Returns the units associated with a number.
unitless($number) : Returns whether a number has units or not.
comparable($number-1, $number-2) : Returns whether two numbers can be added or compared.
Miscellaneous Functions
if($condition, $if-true, $if-false) : Returns one of two values, depending on whether or not a condition is true.
Adding Custom Functions
New Sass functions can be added by adding Ruby methods to this module. For example:
module Sass::Script::Functions
def reverse(string)
assert_type string, :String
Sass::Script::String.new(string.value.reverse)
end
declare :reverse, :args => [:string]
end
Calling Functions.declare tells Sass the argument names for your function. If omitted, the function will still work, but will not be able to accept keyword arguments. Functions.declare can also allow your function to take arbitrary keyword arguments.
There are a few things to keep in mind when modifying this module. First of all, the arguments passed are Literal objects. Literal objects are also expected to be returned. This means that Ruby values must be unwrapped and wrapped.
Most Literal objects support the value accessor for getting their Ruby values. Color objects, though, must be accessed using rgb, red, green, or blue.
Second, making Ruby functions accessible from Sass introduces the temptation to do things like database access within stylesheets. This is generally a bad idea; since Sass files are by default only compiled once, dynamic code is not a great fit.
If you really, really need to compile Sass on each request,
first make sure you have adequate caching set up.
Then you can use Engine to render the code,
using the options
parameter
to pass in data that can be accessed
from your Sass functions.
Within one of the functions in this module, methods of EvaluationContext can be used.
Caveats
When creating new Literal objects within functions, be aware that it's not safe to call #to_s (or other methods that use the string representation) on those objects without first setting the #options attribute.
Defined Under Namespace
Classes: EvaluationContext, Signature
Class Method Summary collapse
-
.declare(method_name, args, options = {})
Declare a Sass signature for a Ruby-defined function.
-
.signature(method_name, arg_arity, kwarg_arity) ⇒ {Symbol => Object}?
Determine the correct signature for the number of arguments passed in for a given function.
Instance Method Summary collapse
-
#abs(value) ⇒ Number
Finds the absolute value of a number.
-
#adjust_color(color, kwargs) ⇒ Color
Adjusts one or more properties of a color.
-
#adjust_hue(color, degrees) ⇒ Color
Changes the hue of a color while retaining the lightness and saturation.
-
#alpha(color) ⇒ Number
Returns the alpha component (opacity) of a color.
-
#append(list, val, separator: auto)
Appends a single value onto the end of a list.
-
#blue(color) ⇒ Number
Returns the blue component of a color.
-
#ceil(value) ⇒ Number
Rounds a number up to the nearest whole number.
-
#change_color(color, kwargs) ⇒ Color
Changes one or more properties of a color.
-
#comparable(number_1, number_2) ⇒ Bool
Returns true if two numbers are similar enough to be added, subtracted, or compared.
-
#complement(color) ⇒ Color
Returns the complement of a color.
-
#darken(color, amount) ⇒ Color
Makes a color darker.
-
#desaturate(color, amount) ⇒ Color
Makes a color less saturated.
-
#floor(value) ⇒ Number
Rounds down to the nearest whole number.
-
#grayscale(color) ⇒ Color
Converts a color to grayscale.
-
#green(color) ⇒ Number
Returns the green component of a color.
-
#hsl(hue, saturation, lightness) ⇒ Color
Creates a Color object from hue, saturation, and lightness.
-
#hsla(hue, saturation, lightness, alpha) ⇒ Color
Creates a Color object from hue, saturation, and lightness, as well as an alpha channel indicating opacity.
-
#hue(color) ⇒ Number
Returns the hue component of a color.
-
#ie_hex_str(color) ⇒ String
Returns an IE hex string for a color with an alpha channel suitable for passing to IE filters.
-
#if(condition, if_true, if_false)
Returns one of two values based on the truth value of the first argument.
-
#index(list, value)
Returns the position of the given value within the given list.
-
#invert(color) ⇒ Color
Returns the inverse (negative) of a color.
-
#join(list1, list2, separator: auto)
Joins together two lists into a new list.
-
#length(list) ⇒ Number
Return the length of a list.
-
#lighten(color, amount) ⇒ Color
Makes a color lighter.
-
#lightness(color) ⇒ Number
Returns the hue component of a color.
-
#max(*values) ⇒ Number
Finds the maximum of several values.
-
#min(*values) ⇒ Number
Finds the minimum of several values.
-
#mix(color1, color2, weight: 50%) ⇒ Color
Mixes together two colors.
-
#nth(list, n) ⇒ Literal
Gets the nth item in a list.
-
#opacify(color, amount) ⇒ Color
(also: #fade_in)
Makes a color more opaque.
-
#opacity(color) ⇒ Number
Returns the alpha component (opacity) of a color.
-
#percentage(value) ⇒ Number
Converts a decimal number to a percentage.
-
#quote(string) ⇒ String
Add quotes to a string if the string isn't quoted, or returns the same string if it is.
-
#red(color) ⇒ Number
Returns the red component of a color.
-
#rgb(red, green, blue) ⇒ Color
Creates a Color object from red, green, and blue values.
- #rgba(*args)
-
#round(value) ⇒ Number
Rounds a number to the nearest whole number.
-
#saturate(color, amount) ⇒ Color
Makes a color more saturated.
-
#saturation(color) ⇒ Number
Returns the saturation component of a color.
-
#scale_color(color, kwargs) ⇒ Color
Scales one or more properties of a color by a percentage value.
-
#transparentize(color, amount) ⇒ Color
(also: #fade_out)
Makes a color more transparent.
-
#type_of(value) ⇒ String
Inspects the type of the argument, returning it as an unquoted string.
-
#unit(number) ⇒ String
Inspects the unit of the number, returning it as a quoted string.
-
#unitless(number) ⇒ Bool
Inspects the unit of the number, returning a boolean indicating if it is unitless.
-
#unquote(string) ⇒ String
Removes quotes from a string if the string is quoted, or returns the same string if it's not.
-
#zip(*lists)
Combines several lists into a single comma separated list space separated lists.
Class Method Details
.declare(method_name, args, options = {})
Declare a Sass signature for a Ruby-defined function. This includes the names of the arguments, whether the function takes a variable number of arguments, and whether the function takes an arbitrary set of keyword arguments.
It's not necessary to declare a signature for a function. However, without a signature it won't support keyword arguments.
A single function can have multiple signatures declared as long as each one takes a different number of arguments. It's also possible to declare multiple signatures that all take the same number of arguments, but none of them but the first will be used unless the user uses keyword arguments.
262 263 264 265 266 267 268 |
# File 'lib/sass/script/functions.rb', line 262
def self.declare(method_name, args, options = {})
@signatures[method_name] ||= []
@signatures[method_name] << Signature.new(
args.map {|s| s.to_s},
options[:var_args],
options[:var_kwargs])
end
|
.signature(method_name, arg_arity, kwarg_arity) ⇒ {Symbol => Object}?
Determine the correct signature for the number of arguments passed in for a given function. If no signatures match, the first signature is returned for error messaging.
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/sass/script/functions.rb', line 281
def self.signature(method_name, arg_arity, kwarg_arity)
return unless @signatures[method_name]
@signatures[method_name].each do |signature|
return signature if signature.args.size == arg_arity + kwarg_arity
next unless signature.args.size < arg_arity + kwarg_arity
# We have enough args.
# Now we need to figure out which args are varargs
# and if the signature allows them.
t_arg_arity, t_kwarg_arity = arg_arity, kwarg_arity
if signature.args.size > t_arg_arity
# we transfer some kwargs arity to args arity
# if it does not have enough args -- assuming the names will work out.
t_kwarg_arity -= (signature.args.size - t_arg_arity)
t_arg_arity = signature.args.size
end
if ( t_arg_arity == signature.args.size || t_arg_arity > signature.args.size && signature.var_args ) &&
(t_kwarg_arity == 0 || t_kwarg_arity > 0 && signature.var_kwargs)
return signature
end
end
@signatures[method_name].first
end
|
Instance Method Details
#abs(value) ⇒ Number
Finds the absolute value of a number.
1213 1214 1215 |
# File 'lib/sass/script/functions.rb', line 1213
def abs(value)
numeric_transformation(value) {|n| n.abs}
end
|
#adjust_color(color, kwargs) ⇒ Color
Adjusts one or more properties of a color. This can change the red, green, blue, hue, saturation, value, and alpha properties. The properties are specified as keyword arguments, and are added to or subtracted from the color's current value for that property.
$red
, $green
, and $blue
properties should be between 0 and 255.
$saturation
and $lightness
should be between 0% and 100%.
$alpha
should be between 0 and 1.
All properties are optional.
You can't specify both RGB properties ($red
, $green
, $blue
)
and HSL properties ($hue
, $saturation
, $value
) at the same time.
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 |
# File 'lib/sass/script/functions.rb', line 796
def adjust_color(color, kwargs)
assert_type color, :Color
with = Sass::Util.map_hash({
"red" => [-255..255, ""],
"green" => [-255..255, ""],
"blue" => [-255..255, ""],
"hue" => nil,
"saturation" => [-100..100, "%"],
"lightness" => [-100..100, "%"],
"alpha" => [-1..1, ""]
}) do |name, (range, units)|
next unless val = kwargs.delete(name)
assert_type val, :Number, name
Sass::Util.check_range("$#{name}: Amount", range, val, units) if range
adjusted = color.send(name) + val.value
adjusted = [0, Sass::Util.restrict(adjusted, range)].max if range
[name.to_sym, adjusted]
end
unless kwargs.empty?
name, val = kwargs.to_a.first
raise ArgumentError.new("Unknown argument $#{name} (#{val})")
end
color.with(with)
end
|
#adjust_hue(color, degrees) ⇒ Color
Changes the hue of a color while retaining the lightness and saturation. Takes a color and a number of degrees (usually between -360deg and 360deg), and returns a color with the hue rotated by that value.
741 742 743 744 745 |
# File 'lib/sass/script/functions.rb', line 741
def adjust_hue(color, degrees)
assert_type color, :Color
assert_type degrees, :Number
color.with(:hue => color.hue + degrees.value)
end
|
#alpha(color) ⇒ Number
Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.
This function also supports the proprietary Microsoft
alpha(opacity=20)
syntax.
579 580 581 582 583 584 585 586 587 588 589 590 591 592 |
# File 'lib/sass/script/functions.rb', line 579
def alpha(*args)
if args.all? do |a|
a.is_a?(Sass::Script::String) && a.type == :identifier &&
a.value =~ /^[a-zA-Z]+\s*=/
end
# Support the proprietary MS alpha() function
return Sass::Script::String.new("alpha(#{args.map {|a| a.to_s}.join(", ")})")
end
raise ArgumentError.new("wrong number of arguments (#{args.size} for 1)") if args.size != 1
assert_type args.first, :Color
Sass::Script::Number.new(args.first.alpha)
end
|
#append(list, val, separator: auto)
Appends a single value onto the end of a list.
Unless the $separator
argument is passed,
if the list has only one item,
the resulting list will be space-separated.
1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 |
# File 'lib/sass/script/functions.rb', line 1344
def append(list, val, separator = Sass::Script::String.new("auto"))
assert_type separator, :String
unless %w[auto space comma].include?(separator.value)
raise ArgumentError.new("Separator name must be space, comma, or auto")
end
sep = list.separator if list.is_a?(Sass::Script::List)
Sass::Script::List.new(
list.to_a + [val],
if separator.value == 'auto'
sep || :space
else
separator.value.to_sym
end)
end
|
#blue(color) ⇒ Number
Returns the blue component of a color.
511 512 513 514 |
# File 'lib/sass/script/functions.rb', line 511
def blue(color)
assert_type color, :Color
Sass::Script::Number.new(color.blue)
end
|
#ceil(value) ⇒ Number
Rounds a number up to the nearest whole number.
1187 1188 1189 |
# File 'lib/sass/script/functions.rb', line 1187
def ceil(value)
numeric_transformation(value) {|n| n.ceil}
end
|
#change_color(color, kwargs) ⇒ Color
Changes one or more properties of a color. This can change the red, green, blue, hue, saturation, value, and alpha properties. The properties are specified as keyword arguments, and replace the color's current value for that property.
$red
, $green
, and $blue
properties should be between 0 and 255.
$saturation
and $lightness
should be between 0% and 100%.
$alpha
should be between 0 and 1.
All properties are optional.
You can't specify both RGB properties ($red
, $green
, $blue
)
and HSL properties ($hue
, $saturation
, $value
) at the same time.
929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 |
# File 'lib/sass/script/functions.rb', line 929
def change_color(color, kwargs)
assert_type color, :Color
with = Sass::Util.map_hash(%w[red green blue hue saturation lightness alpha]) do |name, max|
next unless val = kwargs.delete(name)
assert_type val, :Number, name
[name.to_sym, val.value]
end
unless kwargs.empty?
name, val = kwargs.to_a.first
raise ArgumentError.new("Unknown argument $#{name} (#{val})")
end
color.with(with)
end
|
#comparable(number_1, number_2) ⇒ Bool
Returns true if two numbers are similar enough to be added, subtracted, or compared.
1144 1145 1146 1147 1148 |
# File 'lib/sass/script/functions.rb', line 1144
def comparable(number_1, number_2)
assert_type number_1, :Number
assert_type number_2, :Number
Sass::Script::Bool.new(number_1.comparable_to?(number_2))
end
|
#complement(color) ⇒ Color
Returns the complement of a color.
This is identical to adjust-hue(color, 180deg)
.
1029 1030 1031 |
# File 'lib/sass/script/functions.rb', line 1029
def complement(color)
adjust_hue color, Number.new(180)
end
|
#darken(color, amount) ⇒ Color
Makes a color darker. Takes a color and an amount between 0% and 100%, and returns a color with the lightness decreased by that value.
683 684 685 |
# File 'lib/sass/script/functions.rb', line 683
def darken(color, amount)
_adjust(color, amount, :lightness, 0..100, :-, "%")
end
|
#desaturate(color, amount) ⇒ Color
Makes a color less saturated. Takes a color and an amount between 0% and 100%, and returns a color with the saturation decreased by that value.
724 725 726 |
# File 'lib/sass/script/functions.rb', line 724
def desaturate(color, amount)
_adjust(color, amount, :saturation, 0..100, :-, "%")
end
|
#floor(value) ⇒ Number
Rounds down to the nearest whole number.
1200 1201 1202 |
# File 'lib/sass/script/functions.rb', line 1200
def floor(value)
numeric_transformation(value) {|n| n.floor}
end
|
#grayscale(color) ⇒ Color
Converts a color to grayscale.
This is identical to desaturate(color, 100%)
.
1016 1017 1018 1019 |
# File 'lib/sass/script/functions.rb', line 1016
def grayscale(color)
return Sass::Script::String.new("grayscale(#{color})") if color.is_a?(Sass::Script::Number)
desaturate color, Number.new(100)
end
|
#green(color) ⇒ Number
Returns the green component of a color.
500 501 502 503 |
# File 'lib/sass/script/functions.rb', line 500
def green(color)
assert_type color, :Color
Sass::Script::Number.new(color.green)
end
|
#hsl(hue, saturation, lightness) ⇒ Color
448 449 450 |
# File 'lib/sass/script/functions.rb', line 448
def hsl(hue, saturation, lightness)
hsla(hue, saturation, lightness, Number.new(1))
end
|
#hsla(hue, saturation, lightness, alpha) ⇒ Color
468 469 470 471 472 473 474 475 476 477 478 479 480 481 |
# File 'lib/sass/script/functions.rb', line 468
def hsla(hue, saturation, lightness, alpha)
assert_type hue, :Number
assert_type saturation, :Number
assert_type lightness, :Number
assert_type alpha, :Number
Sass::Util.check_range('Alpha channel', 0..1, alpha)
h = hue.value
s = Sass::Util.check_range('Saturation', 0..100, saturation, '%')
l = Sass::Util.check_range('Lightness', 0..100, lightness, '%')
Color.new(:hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
end
|
#hue(color) ⇒ Number
Returns the hue component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
527 528 529 530 |
# File 'lib/sass/script/functions.rb', line 527
def hue(color)
assert_type color, :Color
Sass::Script::Number.new(color.hue, ["deg"])
end
|
#ie_hex_str(color) ⇒ String
Returns an IE hex string for a color with an alpha channel suitable for passing to IE filters.
758 759 760 761 762 |
# File 'lib/sass/script/functions.rb', line 758
def ie_hex_str(color)
assert_type color, :Color
alpha = (color.alpha * 255).round.to_s(16).rjust(2, '0')
Sass::Script::String.new("##{alpha}#{color.send(:hex_str)[1..-1]}".upcase)
end
|
#if(condition, if_true, if_false)
Returns one of two values based on the truth value of the first argument.
1412 1413 1414 1415 1416 1417 1418 |
# File 'lib/sass/script/functions.rb', line 1412
def if(condition, if_true, if_false)
if condition.to_bool
if_true
else
if_false
end
end
|
#index(list, value)
Returns the position of the given value within the given list. If not found, returns false.
1393 1394 1395 1396 1397 1398 1399 1400 1401 |
# File 'lib/sass/script/functions.rb', line 1393
def index(list, value)
assert_type list, :List
index = list.value.index {|e| e.eq(value).to_bool }
if index
Number.new(index + 1)
else
Bool.new(false)
end
end
|
#invert(color) ⇒ Color
Returns the inverse (negative) of a color. The red, green, and blue values are inverted, while the opacity is left alone.
1040 1041 1042 1043 1044 1045 1046 1047 1048 |
# File 'lib/sass/script/functions.rb', line 1040
def invert(color)
return Sass::Script::String.new("invert(#{color})") if color.is_a?(Sass::Script::Number)
assert_type color, :Color
color.with(
:red => (255 - color.red),
:green => (255 - color.green),
:blue => (255 - color.blue))
end
|
#join(list1, list2, separator: auto)
Joins together two lists into a new list.
Unless the $separator
argument is passed,
if one list is comma-separated and one is space-separated,
the first parameter's separator is used for the resulting list.
If the lists have only one item each, spaces are used for the resulting list.
1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 |
# File 'lib/sass/script/functions.rb', line 1308
def join(list1, list2, separator = Sass::Script::String.new("auto"))
assert_type separator, :String
unless %w[auto space comma].include?(separator.value)
raise ArgumentError.new("Separator name must be space, comma, or auto")
end
sep1 = list1.separator if list1.is_a?(Sass::Script::List) && !list1.value.empty?
sep2 = list2.separator if list2.is_a?(Sass::Script::List) && !list2.value.empty?
Sass::Script::List.new(
list1.to_a + list2.to_a,
if separator.value == 'auto'
sep1 || sep2 || :space
else
separator.value.to_sym
end)
end
|
#length(list) ⇒ Number
Return the length of a list.
1256 1257 1258 |
# File 'lib/sass/script/functions.rb', line 1256
def length(list)
Sass::Script::Number.new(list.to_a.size)
end
|
#lighten(color, amount) ⇒ Color
Makes a color lighter. Takes a color and an amount between 0% and 100%, and returns a color with the lightness increased by that value.
665 666 667 |
# File 'lib/sass/script/functions.rb', line 665
def lighten(color, amount)
_adjust(color, amount, :lightness, 0..100, :+, "%")
end
|
#lightness(color) ⇒ Number
Returns the hue component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
561 562 563 564 |
# File 'lib/sass/script/functions.rb', line 561
def lightness(color)
assert_type color, :Color
Sass::Script::Number.new(color.lightness, ["%"])
end
|
#max(*values) ⇒ Number
Finds the maximum of several values. This function takes any number of arguments.
1243 1244 1245 1246 |
# File 'lib/sass/script/functions.rb', line 1243
def max(*values)
values.each {|v| assert_type v, :Number}
values.inject {|max, val| max.gt(val).to_bool ? max : val}
end
|
#min(*values) ⇒ Number
Finds the minimum of several values. This function takes any number of arguments.
1228 1229 1230 1231 |
# File 'lib/sass/script/functions.rb', line 1228
def min(*values)
values.each {|v| assert_type v, :Number}
values.inject {|min, val| min.lt(val).to_bool ? min : val}
end
|
#mix(color1, color2, weight: 50%) ⇒ Color
Mixes together two colors. Specifically, takes the average of each of the RGB components, optionally weighted by the given percentage. The opacity of the colors is also considered when weighting the components.
The weight specifies the amount of the first color that should be included in the returned color. The default, 50%, means that half the first color and half the second color should be used. 25% means that a quarter of the first color and three quarters of the second color should be used.
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 |
# File 'lib/sass/script/functions.rb', line 969
def mix(color1, color2, weight = Number.new(50))
assert_type color1, :Color
assert_type color2, :Color
assert_type weight, :Number
Sass::Util.check_range("Weight", 0..100, weight, '%')
# This algorithm factors in both the user-provided weight (w) and the
# difference between the alpha values of the two colors (a) to decide how
# to perform the weighted average of the two RGB values.
#
# It works by first normalizing both parameters to be within [-1, 1],
# where 1 indicates "only use color1", -1 indicates "only use color2", and
# all values in between indicated a proportionately weighted average.
#
# Once we have the normalized variables w and a, we apply the formula
# (w + a)/(1 + w*a) to get the combined weight (in [-1, 1]) of color1.
# This formula has two especially nice properties:
#
# * When either w or a are -1 or 1, the combined weight is also that number
# (cases where w * a == -1 are undefined, and handled as a special case).
#
# * When a is 0, the combined weight is w, and vice versa.
#
# Finally, the weight of color1 is renormalized to be within [0, 1]
# and the weight of color2 is given by 1 minus the weight of color1.
p = (weight.value/100.0).to_f
w = p*2 - 1
a = color1.alpha - color2.alpha
w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0
w2 = 1 - w1
rgb = color1.rgb.zip(color2.rgb).map {|v1, v2| v1*w1 + v2*w2}
alpha = color1.alpha*p + color2.alpha*(1-p)
Color.new(rgb + [alpha])
end
|
#nth(list, n) ⇒ Literal
Gets the nth item in a list.
Note that unlike some languages, the first item in a Sass list is number 1, the second number 2, and so forth.
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 |
# File 'lib/sass/script/functions.rb', line 1273
def nth(list, n)
assert_type n, :Number
if !n.int?
raise ArgumentError.new("List index #{n} must be an integer")
elsif n.to_i < 1
raise ArgumentError.new("List index #{n} must be greater than or equal to 1")
elsif list.to_a.size == 0
raise ArgumentError.new("List index is #{n} but list has no items")
elsif n.to_i > (size = list.to_a.size)
raise ArgumentError.new("List index is #{n} but list is only #{size} item#{'s' if size != 1} long")
end
list.to_a[n.to_i - 1]
end
|
#opacify(color, amount) ⇒ Color Also known as: fade_in
Makes a color more opaque. Takes a color and an amount between 0 and 1, and returns a color with the opacity increased by that value.
623 624 625 |
# File 'lib/sass/script/functions.rb', line 623
def opacify(color, amount)
_adjust(color, amount, :alpha, 0..1, :+)
end
|
#opacity(color) ⇒ Number
Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.
603 604 605 606 607 |
# File 'lib/sass/script/functions.rb', line 603
def opacity(color)
return Sass::Script::String.new("opacity(#{color})") if color.is_a?(Sass::Script::Number)
assert_type color, :Color
Sass::Script::Number.new(color.alpha)
end
|
#percentage(value) ⇒ Number
Converts a decimal number to a percentage.
1158 1159 1160 1161 1162 1163 |
# File 'lib/sass/script/functions.rb', line 1158
def percentage(value)
unless value.is_a?(Sass::Script::Number) && value.unitless?
raise ArgumentError.new("#{value.inspect} is not a unitless number")
end
Sass::Script::Number.new(value.value * 100, ['%'])
end
|
#quote(string) ⇒ String
Add quotes to a string if the string isn't quoted, or returns the same string if it is.
1080 1081 1082 1083 |
# File 'lib/sass/script/functions.rb', line 1080
def quote(string)
assert_type string, :String
Sass::Script::String.new(string.value, :string)
end
|
#red(color) ⇒ Number
Returns the red component of a color.
489 490 491 492 |
# File 'lib/sass/script/functions.rb', line 489
def red(color)
assert_type color, :Color
Sass::Script::Number.new(color.red)
end
|
#rgb(red, green, blue) ⇒ Color
Creates a Color object from red, green, and blue values.
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/sass/script/functions.rb', line 373
def rgb(red, green, blue)
assert_type red, :Number
assert_type green, :Number
assert_type blue, :Number
Color.new([red, green, blue].map do |c|
v = c.value
if c.numerator_units == ["%"] && c.denominator_units.empty?
v = Sass::Util.check_range("Color value", 0..100, c, '%')
v * 255 / 100.0
else
Sass::Util.check_range("Color value", 0..255, c)
end
end)
end
|
#rgba(red, green, blue, alpha) ⇒ Color #rgba(color, alpha) ⇒ Color
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/sass/script/functions.rb', line 416
def rgba(*args)
case args.size
when 2
color, alpha = args
assert_type color, :Color
assert_type alpha, :Number
Sass::Util.check_range('Alpha channel', 0..1, alpha)
color.with(:alpha => alpha.value)
when 4
red, green, blue, alpha = args
rgba(rgb(red, green, blue), alpha)
else
raise ArgumentError.new("wrong number of arguments (#{args.size} for 4)")
end
end
|
#round(value) ⇒ Number
Rounds a number to the nearest whole number.
1174 1175 1176 |
# File 'lib/sass/script/functions.rb', line 1174
def round(value)
numeric_transformation(value) {|n| n.round}
end
|
#saturate(color, amount) ⇒ Color
Makes a color more saturated. Takes a color and an amount between 0% and 100%, and returns a color with the saturation increased by that value.
702 703 704 705 706 707 |
# File 'lib/sass/script/functions.rb', line 702
def saturate(color, amount = nil)
# Support the filter effects definition of saturate.
# https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html
return Sass::Script::String.new("saturate(#{color})") if amount.nil?
_adjust(color, amount, :saturation, 0..100, :+, "%")
end
|
#saturation(color) ⇒ Number
Returns the saturation component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
544 545 546 547 |
# File 'lib/sass/script/functions.rb', line 544
def saturation(color)
assert_type color, :Color
Sass::Script::Number.new(color.saturation, ["%"])
end
|
#scale_color(color, kwargs) ⇒ Color
Scales one or more properties of a color by a percentage value.
Unlike adjust-color, which changes a color's properties by fixed amounts,
scale-color fluidly changes them based on how high or low they already are.
That means that lightening an already-light color with scale-color
won't change the lightness much,
but lightening a dark color by the same amount will change it more dramatically.
This has the benefit of making scale-color($color, ...)
have a similar effect
regardless of what $color
is.
For example, the lightness of a color can be anywhere between 0 and 100.
If scale-color($color, $lightness: 40%)
is called, the resulting color's lightness
will be 40% of the way between its original lightness and 100.
If scale-color($color, $lightness: -40%)
is called instead,
the lightness will be 40% of the way between the original and 0.
This can change the red, green, blue, saturation, value, and alpha properties. The properties are specified as keyword arguments. All arguments should be percentages between 0% and 100%.
All properties are optional.
You can't specify both RGB properties ($red
, $green
, $blue
)
and HSL properties ($saturation
, $value
) at the same time.
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 |
# File 'lib/sass/script/functions.rb', line 864
def scale_color(color, kwargs)
assert_type color, :Color
with = Sass::Util.map_hash({
"red" => 255,
"green" => 255,
"blue" => 255,
"saturation" => 100,
"lightness" => 100,
"alpha" => 1
}) do |name, max|
next unless val = kwargs.delete(name)
assert_type val, :Number, name
if !(val.numerator_units == ['%'] && val.denominator_units.empty?)
raise ArgumentError.new("$#{name}: Amount #{val} must be a % (e.g. #{val.value}%)")
else
Sass::Util.check_range("$#{name}: Amount", -100..100, val, '%')
end
current = color.send(name)
scale = val.value/100.0
diff = scale > 0 ? max - current : current
[name.to_sym, current + diff*scale]
end
unless kwargs.empty?
name, val = kwargs.to_a.first
raise ArgumentError.new("Unknown argument $#{name} (#{val})")
end
color.with(with)
end
|
#transparentize(color, amount) ⇒ Color Also known as: fade_out
Makes a color more transparent. Takes a color and an amount between 0 and 1, and returns a color with the opacity decreased by that value.
644 645 646 |
# File 'lib/sass/script/functions.rb', line 644
def transparentize(color, amount)
_adjust(color, amount, :alpha, 0..1, :-)
end
|
#type_of(value) ⇒ String
Inspects the type of the argument, returning it as an unquoted string.
1097 1098 1099 |
# File 'lib/sass/script/functions.rb', line 1097
def type_of(value)
Sass::Script::String.new(value.class.name.gsub(/Sass::Script::/,'').downcase)
end
|
#unit(number) ⇒ String
Inspects the unit of the number, returning it as a quoted string. Complex units are sorted in alphabetical order by numerator and denominator.
1114 1115 1116 1117 |
# File 'lib/sass/script/functions.rb', line 1114
def unit(number)
assert_type number, :Number
Sass::Script::String.new(number.unit_str, :string)
end
|
#unitless(number) ⇒ Bool
Inspects the unit of the number, returning a boolean indicating if it is unitless.
1128 1129 1130 1131 |
# File 'lib/sass/script/functions.rb', line 1128
def unitless(number)
assert_type number, :Number
Sass::Script::Bool.new(number.unitless?)
end
|
#unquote(string) ⇒ String
Removes quotes from a string if the string is quoted, or returns the same string if it's not.
1061 1062 1063 1064 1065 1066 1067 |
# File 'lib/sass/script/functions.rb', line 1061
def unquote(string)
if string.is_a?(Sass::Script::String)
Sass::Script::String.new(string.value, :identifier)
else
string
end
end
|
#zip(*lists)
Combines several lists into a single comma separated list space separated lists.
The length of the resulting list is the length of the shortest list.
1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 |
# File 'lib/sass/script/functions.rb', line 1370
def zip(*lists)
length = nil
values = []
lists.each do |list|
assert_type list, :List
values << list.value.dup
length = length.nil? ? list.value.length : [length, list.value.length].min
end
values.each do |value|
value.slice!(length)
end
new_list_value = values.first.zip(*values[1..-1])
List.new(new_list_value.map{|list| List.new(list, :space)}, :comma)
end
|