mirror of
https://github.com/craftzdog/solarized-osaka.nvim.git
synced 2026-09-10 07:16:21 -04:00
fix(vivid): Keep colors from washing out when brightened
HSLuv preserves *relative* saturation, but the sRGB gamut narrows toward white, so holding S constant while raising lightness silently drained real chroma: red lost 29.8%, violet 26.6% and magenta 18.2%. Work in LCh instead and never let chroma fall below where it started, capped at what the gamut can hold at the new lightness. Colors already on the boundary keep riding it up, so the hues that were not losing chroma are untouched and near-gray tokens stay neutral. red500 #f37574 -> #ff6c6a (+19.7% chroma) magenta500 #ef73a6 -> #fe67a8 (+22.1%) violet500 #989ad7 -> #9498ea (+35.6%) Contrast is unchanged, with the lowest still at 6.21:1.
This commit is contained in:
parent
b08592c1bb
commit
308edfd998
|
|
@ -36,7 +36,8 @@ function M.lighten(hex, amount, fg)
|
|||
return M.blend(hex, fg or M.fg, amount)
|
||||
end
|
||||
|
||||
--- Raises a color's perceptual lightness toward white, leaving hue and saturation untouched
|
||||
--- Raises a color's perceptual lightness without draining its colorfulness.
|
||||
---
|
||||
---@param hex string
|
||||
---@param amount number between 0 and 1, from unchanged to white
|
||||
---@return string
|
||||
|
|
@ -45,9 +46,23 @@ function M.brighten(hex, amount)
|
|||
return hex
|
||||
end
|
||||
local hsluv = require("solarized-osaka.hsluv")
|
||||
local color = hsluv.hex_to_hsluv(hex)
|
||||
color[3] = color[3] + (100 - color[3]) * amount
|
||||
return hsluv.hsluv_to_hex(color)
|
||||
local lch = hsluv.rgb_to_lch(hsluv.hex_to_rgb(hex))
|
||||
local chroma, hue = lch[2], lch[3]
|
||||
local ceiling_before = hsluv.max_safe_chroma_for_lh(lch[1], hue)
|
||||
|
||||
lch[1] = lch[1] + (100 - lch[1]) * amount
|
||||
|
||||
-- Colors already sitting on the gamut boundary should ride it up rather than
|
||||
-- stay pinned to their old chroma, so track the ceiling as well as the floor.
|
||||
local ceiling = hsluv.max_safe_chroma_for_lh(lch[1], hue)
|
||||
local scaled = ceiling_before > 0 and chroma * ceiling / ceiling_before or 0
|
||||
lch[2] = math.min(math.max(chroma, scaled), ceiling)
|
||||
|
||||
local rgb = hsluv.lch_to_rgb(lch)
|
||||
for i = 1, 3 do
|
||||
rgb[i] = math.min(math.max(rgb[i], 0), 1)
|
||||
end
|
||||
return hsluv.rgb_to_hex(rgb)
|
||||
end
|
||||
|
||||
function M.invert_color(color)
|
||||
|
|
|
|||
Loading…
Reference in a new issue