Color blending code

I have a few handy, seen in folk’s patterns or ported from plain JS:


//linear interpolation
function lerp(a, b, t) {
  return a * (1-t) + b * t
}

//cross fade RGB between 2 colors using linear interpolation
//output sets r,g,b globals
function crossFadeColors(r1, g1, b1, r2, g2, b2, t) {
  r = lerp(r1, r2, t)
  g = lerp(g1, g2, t)
  b = lerp(b1, b2, t)
}

//convert HSV to RGB
//output sets r,g,b globals
function hsv2rgb(hh, ss, vv) {
  var h = mod(hh, 1)
  var s = clamp(ss, 0, 1)
  var v = clamp(vv, 0, 1)
  var i = floor(h * 6)
  var f = h * 6 - i
  var p = v * (1 - s)
  var q = v * (1 - (s * f))
  var t = v * (1 - (s * (1 - f)))

  if (i == 0) {
    r = v; g = t; b = p
  } else if (i == 1) {
    r = q; g = v; b = p
  } else if (i == 2) {
    r = p; g = v; b = t
  } else if (i == 3) {
    r = p; g = q; b = v
  } else if (i == 4) {
    r = t; g = p; b = v
  } else if (i == 5) {
    r = v; g = p; b = q
  }
}

//convert HSL to RGB
//output sets r,g,b globals
function hsl2rgb(h,s,l){
  value = s * min(l,1-l) + l
  sat2 = value ? 2-(2*l/value) : 0
  hsv2rgb(h,sat2,value);
}

//convert RGB to HSV
//output sets h,s,v globals
function rgb2hsv(r, g, b) {
  var rr, gg, bb, diff

  r = clamp(r, 0, 1)
  g = clamp(g, 0, 1)
  b = clamp(b, 0, 1)

  v = max(r, max(g, b))
  diff = v - min(r, min(g, b))
  if (diff == 0) {
    h = s = 0
  } else {
    s = diff / v
    rr = (v - r) / 6 / diff
    gg = (v - g) / 6 / diff
    bb = (v - b) / 6 / diff

    if (r == v) {
      h = bb - gg
    } else if (g == v) {
      h = (1 / 3) + rr - bb
    } else if (b == v) {
      h = (2 / 3) + gg - rr
    }
    if (h < 0) {
      h += 1
    } else if (h > 1) {
      h -= 1
    }
  }
}

(some could use slight tweaks/optimizations)

I’m considering these for inclusion in the API, but I want to figure out a good way to handle color “types”, and obviously wouldn’t be setting globals as a way of returning values.

1 Like