Skip to content

Instantly share code, notes, and snippets.

@voxpelli
Last active June 13, 2019 10:01
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save voxpelli/1069204 to your computer and use it in GitHub Desktop.
Save voxpelli/1069204 to your computer and use it in GitHub Desktop.
/*! hsv_to_hsl.scss | MIT License | https://gist.github.com/voxpelli/1069204 */
@function max($v1, $v2) {
@return if($v1 > $v2, $v1, $v2);
}
@function min($v1, $v2) {
@return if($v1 < $v2, $v1, $v2);
}
@function hsv_to_hsl($h, $s: 0, $v: 0) {
@if type_of($h) == 'list' {
$v: nth($h, 3);
$s: nth($h, 2);
$h: nth($h, 1);
}
@if unit($h) == 'deg' {
$h: 3.1415 * 2 * ($h / 360deg);
}
@if unit($s) == '%' {
$s: 0 + ($s / 100%);
}
@if unit($v) == '%' {
$v: 0 + ($v / 100%);
}
$ss: $s * $v;
$ll: (2 - $s) * $v;
@if $ll <= 1 {
$ss: $ss / $ll;
} @else if ($ll == 2) {
$ss: 0;
} @else {
$ss: $ss / (2 - $ll);
}
$ll: $ll / 2;
@return 360deg * $h / (3.1415 * 2), percentage(max(0, min(1, $ss))), percentage(max(0, min(1, $ll)));
}
@function hsl_to_hsv($h, $ss: 0, $ll: 0) {
@if type_of($h) == 'list' {
$ll: nth($h, 3);
$ss: nth($h, 2);
$h: nth($h, 1);
} @else if type_of($h) == 'color' {
$ll: lightness($h);
$ss: saturation($h);
$h: hue($h);
}
@if unit($h) == 'deg' {
$h: 3.1415 * 2 * ($h / 360deg);
}
@if unit($ss) == '%' {
$ss: 0 + ($ss / 100%);
}
@if unit($ll) == '%' {
$ll: 0 + ($ll / 100%);
}
$ll: $ll * 2;
@if $ll <= 1 {
$ss: $ss * $ll;
} @else {
$ss: $ss * (2 - $ll);
}
$v: ($ll + $ss) / 2;
$s: (2 * $ss) / ($ll + $ss);
@return 360deg * $h / (3.1415 * 2), percentage(max(0, min(1, $s))), percentage(max(0, min(1, $v)));
}
@function color_to_hsv($color) {
@return hsl_to_hsv($color);
}
@function hsv_to_color($h, $s: 0, $v: 0) {
$hsl: hsv_to_hsl($h, $s, $v);
@return hsl(nth($hsl, 1), nth($hsl, 2), nth($hsl, 3));
}
@metaskills
Copy link

I found this one useful for a ruby alternative http://blog.nataliabuckley.co.uk/2011/11/21/convert-rgb-to-hsb-hsv-in-ruby/ which I then put into Sass's Color class with accessors. This would let me call these methods on a color object and use the HSV values in other custom functions.

class Sass::Script::Color < Sass::Script::Literal

  def hsv_h
    rgb_to_hsv!
    @attrs[:hsv_h]
  end

  def hsv_s
    rgb_to_hsv!
    @attrs[:hsv_s]
  end

  def hsv_v
    rgb_to_hsv!
    @attrs[:hsv_v]
  end

  private

  def rgb_to_hsv!
    return if @attrs[:hsv_h] && @attrs[:hsv_s] && @attrs[:hsv_v]
    r = red / 255.0
    g = green / 255.0
    b = blue / 255.0
    max = [r, g, b].max
    min = [r, g, b].min
    delta = max - min
    v = max * 100
    if (max != 0.0)
      s = delta / max *100
    else
      s = 0.0
    end
    if (s == 0.0) 
      h = 0.0
    else
      if (r == max)
        h = (g - b) / delta
      elsif (g == max)
        h = 2 + (b - r) / delta
      elsif (b == max)
        h = 4 + (r - g) / delta
      end
      h *= 60.0
      if (h < 0)
        h += 360.0
      end
    end
    @attrs[:hsv_h] = h
    @attrs[:hsv_s] = s
    @attrs[:hsv_v] = v
  end

end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment