REF make color module more functional

This commit is contained in:
Nathan Dwarshuis 2022-07-23 23:52:13 -04:00
parent 25b2ddf2fd
commit f05b4ea4b7
3 changed files with 40 additions and 38 deletions

View File

@ -293,6 +293,7 @@ properties:
properties: properties:
color: color:
type: integer type: integer
maximum: 0xffffff
alpha: &alpha alpha: &alpha
type: number type: number
minimum: 0 minimum: 0
@ -311,6 +312,7 @@ properties:
maximum: 1 maximum: 1
color: color:
type: integer type: integer
maximum: 0xffffff
gradient_alpha: gradient_alpha:
type: array type: array

View File

@ -1,4 +1,5 @@
local err = require 'err' local err = require 'err'
local pure = require 'pure'
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- colors -- colors
@ -17,9 +18,7 @@ local rgba = function(hex, alpha)
return err.set_type(obj, "color") return err.set_type(obj, "color")
end end
local rgb = function(hex) local rgb = pure.partial(pure.flip(rgba), 1.0)
return rgba(hex, 1.0)
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Gradients -- Gradients
@ -27,30 +26,35 @@ end
-- these are tables like {[stop] :: color} where stop is a float between 0 and 1 -- these are tables like {[stop] :: color} where stop is a float between 0 and 1
-- and color is a color as defined above -- and color is a color as defined above
local _make_gradient = function(colorstops, f) local _make_gradient = function(f)
local c = {} return pure.compose(
for stop, spec in pairs(colorstops) do pure.partial(pure.flip(err.set_type), "gradient"),
assert( err.safe_table,
stop <= 1 and stop >= 0, pure.array_to_map,
"ERROR: color stop must be between 0 and 1; got " .. stop pure.partial(pure.kmap, function(stop, spec) return {stop, f(spec)} end)
) )
c[stop] = f(spec)
end
return err.set_type(err.safe_table(c), "gradient")
end end
-- {[stop] :: hex} -> Gradient -- {[stop] :: hex} -> Gradient
local gradient_rgb = function(colorstops) local gradient_rgb = _make_gradient(rgb)
return _make_gradient(colorstops, rgb)
end
-- {[stop] :: {hex, alpha}} -> Gradient -- {[stop] :: {hex, alpha}} -> Gradient
local gradient_rgba = function(colorstops) local gradient_rgba = _make_gradient(function(spec) return rgba(spec[1], spec[2]) end)
return _make_gradient(
colorstops, --------------------------------------------------------------------------------
function(spec) return rgba(spec[1], spec[2]) end -- Yaml config to pattern tree
)
end local compile_gradient = pure.compose(
gradient_rgb,
pure.array_to_map,
pure.partial(pure.map, function(g) return {g.stop, g.color} end)
)
local compile_gradient_alpha = pure.compose(
gradient_rgba,
pure.array_to_map,
pure.partial(pure.map, function(g) return {g.stop, {g.color, g.alpha}} end)
)
local compile_patterns local compile_patterns
@ -62,21 +66,9 @@ compile_patterns = function(patterns)
elseif v.color ~= nil then elseif v.color ~= nil then
r[k] = rgba(v.color, v.alpha) r[k] = rgba(v.color, v.alpha)
elseif v.gradient ~= nil then elseif v.gradient ~= nil then
local p = {} r[k] = compile_gradient(v.gradient)
local g = v.gradient
for i = 1, #g do
local _g = g[i]
p[_g.stop] = _g.color
end
r[k] = gradient_rgb(p)
elseif v.gradient_alpha ~= nil then elseif v.gradient_alpha ~= nil then
local p = {} r[k] = compile_gradient_alpha(v.gradient_alpha)
local g = v.gradient_alpha
for i = 1, #g do
local _g = g[i]
p[_g.stop] = {_g.color, _g.alpha}
end
r[k] = gradient_rgba(p)
else else
r[k] = compile_patterns(v) r[k] = compile_patterns(v)
end end

View File

@ -77,6 +77,14 @@ M.imap = function(f, seq)
return r return r
end end
M.kmap = function(f, seq)
local r = {}
for k, v in pairs(seq) do
r[k] = f(k, v)
end
return r
end
M.map_keys = function(key, tbls) M.map_keys = function(key, tbls)
local r = {} local r = {}
for i = 1, #tbls do for i = 1, #tbls do
@ -119,8 +127,8 @@ end
M.array_to_map = function(arr) M.array_to_map = function(arr)
local r = {} local r = {}
for i = 1, #arr do for _, v in pairs(arr) do
r[arr[i][1]] = arr[i][2] r[v[1]] = v[2]
end end
return r return r
end end