Compute the complement of a given colour.
It converts the input colour to HSL and then
shifts the hue by 180°. Doesn't give the same
complement colour as using the colour wheel,
but still a good enough complement colour.
501917
function complement(color) {
  let rgb = parseColor(color);
  let hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
  hsl[0] = (hsl[0] + .5) % 1;
  hsl[2] = 1 - hsl[2];
  return hslToRgb(...hsl);
}
265421
def _hue2rgb(v1, v2, vH):
    

    while vH < 0: vH += 1
    while vH > 1: vH -= 1

    if 6 * vH < 1: return v1 + (v2 - v1) * 6 * vH
    if 2 * vH < 1: return v2
    if 3 * vH < 2: return v1 + (v2 - v1) * ((2.0 / 3) - vH) * 6

    return v1
422720
private static int  hslToRgb(float hue, float sat, float light)
   {
      hue = (hue >= 0f) ? hue % 360f : (hue % 360f) + 360f;  // positive modulo (ie. -10 => 350)
      hue /= 60f;    // [0, 360] -> [0, 6]
      sat /= 100;   // [0, 100] -> [0, 1]
      light /= 100; // [0, 100] -> [0, 1]
      sat = (sat < 0f) ? 0f : (sat > 1f) ? 1f : sat;
      light = (light < 0f) ? 0f : (light > 1f) ? 1f : light;
      float  t1, t2;
      if (light <= 0.5f) {
         t2 = light * (sat + 1f);
      } else {
         t2 = light + sat - (light * sat);
      }
      t1 = light * 2f - t2;
      float  r = hueToRgb(t1, t2, hue + 2f);
      float  g = hueToRgb(t1, t2, hue);
      float  b = hueToRgb(t1, t2, hue - 2f);
      return clamp255(r * 256f)<<16 | clamp255(g * 256f)<<8 | clamp255(b * 256f);
   }
1274337
def rgb_to_hsl(red, green, blue)
      red = round_rgb_color(red)
      green = round_rgb_color(green)
      blue = round_rgb_color(blue)

      color_max = [red, green, blue].max
      color_min = [red, green, blue].min
      color_range = color_max - color_min
      if color_range == 0
        return [0, 0, (color_max * 100.0 / 255).to_i]
      end
      color_range = color_range.to_f
      hue = (case color_max
             when red then
               HUE_PER_6 * ((green - blue) / color_range)
             when green  then
               HUE_PER_6 * ((blue - red) / color_range) + HUE_PER_6 * 2
             else
               HUE_PER_6 * ((red - green) / color_range) + HUE_PER_6 * 4
             end)

      cnt = color_range / 2.0
      if cnt <= 127
        saturation = color_range / (color_max + color_min) * 100
      else
        saturation = color_range / (510 - color_max - color_min) * 100
      end
      lightness = (color_max + color_min) / 2.0 / 255.0 * 100

      [hue.round, saturation.round, lightness.round]
    end
548081
def RgbToRyb(hue):
    '''

    '''
    d = hue % 15
    i = int(hue / 15)
    x0 = _RybWheel[i]
    x1 = _RybWheel[i+1]
    return x0 + (x1-x0) * d / 15
190872
def euclidian other_color
      # TODO: different depths
      r  = (self.r.to_i - other_color.r.to_i)**2
      r += (self.g.to_i - other_color.g.to_i)**2
      r += (self.b.to_i - other_color.b.to_i)**2
      Math.sqrt r
    end
891196
function ( color ) {
            var hsla = {};
            color.replace( this.REG_HSL, function ( str, h, s, l, a ) {
                hsla = {h: parseFloat(h), s: parseFloat(s), l: parseFloat(l), a: 1};
                if ( a ) hsla.a = Number(a);
            });
            return hsla;
        }
137263
def hls(self):
        
        r, g, b = self.color
        hls = colorsys.rgb_to_hls(r, g, b)
        hls = (int(round(hls[0] * 360)), hls[1], hls[2])
        return self._append_alpha_if_necessary(hls)
509662
def HSL_to_RGB(cobj, target_rgb, *args, **kwargs):
    
    H = cobj.hsl_h
    S = cobj.hsl_s
    L = cobj.hsl_l

    if L < 0.5:
        var_q = L * (1.0 + S)
    else:
        var_q = L + S - (L * S)

    var_p = 2.0 * L - var_q

    # H normalized to range [0,1]
    h_sub_k = (H / 360.0)

    t_sub_R = h_sub_k + (1.0 / 3.0)
    t_sub_G = h_sub_k
    t_sub_B = h_sub_k - (1.0 / 3.0)

    rgb_r = __Calc_HSL_to_RGB_Components(var_q, var_p, t_sub_R)
    rgb_g = __Calc_HSL_to_RGB_Components(var_q, var_p, t_sub_G)
    rgb_b = __Calc_HSL_to_RGB_Components(var_q, var_p, t_sub_B)

    # TODO: Investigate intent of following code block.
    # In the event that they define an HSV color and want to convert it to
    # a particular RGB space, let them override it here.
    # if target_rgb is not None:
    #     rgb_type = target_rgb
    # else:
    #     rgb_type = cobj.rgb_type

    return target_rgb(rgb_r, rgb_g, rgb_b)
241254
def _lightness(color, **kwargs):
    
    l = colorsys.rgb_to_hls(*[x / 255.0 for x in color.value[:3]])[1]
    return NumberValue((l * 100, '%'))
1356003
def shift_hue(image, hue):
    
    hue = (hue - 1.0) * 180
    img = image.copy().convert("HSV")
    pixels = img.load()
    for i in range(img.width):
        for j in range(img.height):
            h, s, v = pixels[i, j]
            h = abs(int(h + hue))
            if h > 255:
                h -= 255
            pixels[i, j] = (h, s, v)
    return img.convert("RGBA")
78471
def _hsla(h, s, l, a, **kwargs):
    
    res = colorsys.hls_to_rgb(float(h), float(l), float(s))
    return ColorValue([x * 255.0 for x in res] + [float(a)])
1080498
private void calculateColor(int coord) {
    	    coord = coord - mBarPointerHaloRadius;
    	    if (coord < 0) {
    	    	coord = 0;
    	    } else if (coord > mBarLength) {
    	    	coord = mBarLength;
    	    }

    		mColor = Color.HSVToColor(
    			Math.round(mPosToOpacFactor * coord),
    			mHSVColor);
    		if (Color.alpha(mColor) > 250) {
    		    mColor = Color.HSVToColor(mHSVColor);
    		} else if (Color.alpha(mColor) < 5) {
    		    mColor = Color.TRANSPARENT;
    		}
        }
480291
static HSL toHSL( double color ) {
        long argb = Double.doubleToRawLongBits( color );
        double a = alpha( color );
        double r = clamp( ((argb >> 32) & 0xFFFF) / (double)0xFF00 );
        double g = clamp( ((argb >> 16) & 0xFFFF) / (double)0xFF00 );
        double b = clamp( ((argb >> 0) & 0xFFFF) / (double)0xFF00 );

        double max = Math.max( Math.max( r, g ), b );
        double min = Math.min( Math.min( r, g ), b );
        double h, s, l = (max + min) / 2, d = max - min;

        if( max == min ) {
            h = s = 0;
        } else {
            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);

            if( max == r ) {
                h = (g - b) / d + (g < b ? 6 : 0);
            } else if( max == g ) {
                h = (b - r) / d + 2;
            } else {
                h = (r - g) / d + 4;
            }
            h /= 6;
        }
        return new HSL( h * 360, s, l, a );
    }
459985
function(color1, color2, factor) {
		if (arguments.length < 3) { factor = 0.5; }
		var result = color1.slice();
		for (var i=0;i<3;i++) {
			result[i] = Math.round(result[i] + factor*(color2[i]-color1[i]));
		}
		return result;
	}
313995
function hsl2rgb(h, s, l) {
		// HSL 0 to 1 => RGB results from 0 to 255
		var r, g, b, var_1, var_2;

		if (s === 0) {
			r = l * 255;
			g = l * 255;
			b = l * 255;
		} else {
			var_2 = (l < 0.5) ? l * (1 + s) : ((l + s) - (s * l));
			var_1 = 2 * l - var_2;

			r = 255 * h2rgb(var_1, var_2, h + (1 / 3));
			g = 255 * h2rgb(var_1, var_2, h);
			b = 255 * h2rgb(var_1, var_2, h - (1 / 3));
		}

		return [r, g, b];
	}
913181
public RgbaColor adjustHue(float degrees) {
        float[] HSL = convertToHsl();
        HSL[0] = hueCheck(HSL[0] + degrees); // ensure [0-360)
        return RgbaColor.fromHsl(HSL);
    }