local oklab = require "prismite.oklab" local M = {} function M.lerp(a, b, t) return a + t * (b - a) end function M.mix_oklch(a, b, t) if not (a.l and a.c and a.h) then error("`a` must be a valid OKLCH color", 2) end if not (b.l and b.c and b.h) then error("`b` must be a valid OKLCH color", 2) end if type(t) ~= "number" then error("'t' must be a number", 2) end local a_h = a.h local b_h = b.h -- https://drafts.csswg.org/css-color-4/#hue-shorter if b_h - a_h > 180 then print "adjusted +" a_h = a_h + 360 end if b_h - a_h < -180 then print "adjusted -" b_h = b_h + 360 end return { l = M.lerp(a.l, b.l, t), c = M.lerp(a.c, b.c, t), h = M.lerp(a_h, b_h, t) } end local function over(a, b, alpha) return a * alpha + b * (1 - alpha) end function M.overlay_oklch(a, b, alpha) if not (a.l and a.c and a.h) then error("`a` must be a valid OKLCH color", 2) end if not (b.l and b.c and b.h) then error("`b` must be a valid OKLCH color", 2) end if type(alpha) ~= "number" then error("'alpha' must be a number", 2) end local a_oklab = oklab.oklch2oklab(a) local b_oklab = oklab.oklch2oklab(b) local _l = over(a_oklab.l, b_oklab.l, alpha) local _a = over(a_oklab.a, b_oklab.a, alpha) local _b = over(a_oklab.b, b_oklab.b, alpha) return oklab.oklab2oklch { l = _l, a = _a, b = _b } end function M.is_oklch(oklch) return (oklch.l and oklch.c and oklch.h) end function M.oklch2hex(oklch) return oklab.rgb2hex(oklab.oklab2rgb(oklab.oklch2oklab(oklch))) end return M