aboutsummaryrefslogtreecommitdiff
path: root/lua/prismite/utils.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/prismite/utils.lua')
-rw-r--r--lua/prismite/utils.lua73
1 files changed, 73 insertions, 0 deletions
diff --git a/lua/prismite/utils.lua b/lua/prismite/utils.lua
new file mode 100644
index 0000000..8a0dbca
--- /dev/null
+++ b/lua/prismite/utils.lua
@@ -0,0 +1,73 @@
+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