fix light mode negation, improve oklch dist calc efficiency
This commit is contained in:
@@ -54,6 +54,7 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
# particularly good measure of perceptual distinction, so we'd prefer the
|
# particularly good measure of perceptual distinction, so we'd prefer the
|
||||||
# former.
|
# former.
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
"-l",
|
||||||
"--l-base",
|
"--l-base",
|
||||||
type=int,
|
type=int,
|
||||||
default=20,
|
default=20,
|
||||||
@@ -82,7 +83,7 @@ def register_parser(subparsers: _SubparserType) -> None:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--term-fg-gap",
|
"--term-fg-gap",
|
||||||
type=int,
|
type=int,
|
||||||
default=60,
|
default=65,
|
||||||
help="Terminal foreground lightness gap (default: 60)",
|
help="Terminal foreground lightness gap (default: 60)",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ L_max: int = parameters.get("L_max", 98)
|
|||||||
L_step: int = parameters.get("L_step", 5)
|
L_step: int = parameters.get("L_step", 5)
|
||||||
|
|
||||||
L_points: list[int] = list(range(L_min, L_max+1))
|
L_points: list[int] = list(range(L_min, L_max+1))
|
||||||
|
|
||||||
|
# L-space just affects accuracy of chroma max
|
||||||
L_space = np.arange(0, 100 + L_step, L_step)
|
L_space = np.arange(0, 100 + L_step, L_step)
|
||||||
|
|
||||||
monotone_C_map = parameters.get("monotone_C_map", {})
|
monotone_C_map = parameters.get("monotone_C_map", {})
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ def generate_scheme_groups(
|
|||||||
|
|
||||||
metric_map = {
|
metric_map = {
|
||||||
"wcag": lambda mc,ac: ac.contrast(mc, method='wcag21'),
|
"wcag": lambda mc,ac: ac.contrast(mc, method='wcag21'),
|
||||||
"oklch": lambda mc,ac: mc.distance(ac, space="oklch"),
|
"oklch": oklch_distance,
|
||||||
"lightness": lambda mc,ac: abs(mc.coords()[0]-ac.coords()[0])*100,
|
"lightness": lambda mc,ac: abs(mc.coords()[0]-ac.coords()[0])*100,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +131,9 @@ def generate_scheme_groups(
|
|||||||
("distance", distance),
|
("distance", distance),
|
||||||
("l_base", l_base),
|
("l_base", l_base),
|
||||||
("l_step", l_step),
|
("l_step", l_step),
|
||||||
|
("fg_gap", fg_gap),
|
||||||
|
("grey_gap", grey_gap),
|
||||||
|
("term_fg_gap", term_fg_gap),
|
||||||
]
|
]
|
||||||
|
|
||||||
# note how selection_bg steps up by `l_step`, selection_fg steps down by
|
# note how selection_bg steps up by `l_step`, selection_fg steps down by
|
||||||
@@ -157,7 +160,7 @@ def generate_scheme_groups(
|
|||||||
accent_pairs = [
|
accent_pairs = [
|
||||||
("black", f"f{{{{{biome}.l{l_base}}}}}"),
|
("black", f"f{{{{{biome}.l{l_base}}}}}"),
|
||||||
("grey", f"f{{{{{biome}.l{l_base+grey_gap}}}}}"),
|
("grey", f"f{{{{{biome}.l{l_base+grey_gap}}}}}"),
|
||||||
("white", f"f{{{{{biome}.l{l_base+term_fg_gap-l_step}}}}}"),
|
("white", f"f{{{{{biome}.l{l_base+term_fg_gap-2*l_step}}}}}"),
|
||||||
]
|
]
|
||||||
for color_name, mb_accent in accent_color_map.items():
|
for color_name, mb_accent in accent_color_map.items():
|
||||||
aL = int(100*accent_colors[mb_accent].coords()[0])
|
aL = int(100*accent_colors[mb_accent].coords()[0])
|
||||||
@@ -184,29 +187,42 @@ def generate_scheme(
|
|||||||
term_color_map: dict[str, str],
|
term_color_map: dict[str, str],
|
||||||
vim_color_map: dict[str, str],
|
vim_color_map: dict[str, str],
|
||||||
) -> str:
|
) -> str:
|
||||||
|
l_sys = l_base
|
||||||
|
l_app = l_base + l_step
|
||||||
|
|
||||||
|
term_bright_offset = 10
|
||||||
|
|
||||||
|
# negate gaps if mode is light
|
||||||
|
if mode == "light":
|
||||||
|
l_step *= -1
|
||||||
|
fg_gap *= -1
|
||||||
|
grey_gap *= -1
|
||||||
|
term_fg_gap *= -1
|
||||||
|
term_bright_offset *= -1
|
||||||
|
|
||||||
meta, _, mt, ac = generate_scheme_groups(
|
meta, _, mt, ac = generate_scheme_groups(
|
||||||
mode, biome, metric, distance,
|
mode, biome, metric, distance,
|
||||||
l_base, l_step,
|
l_sys, l_step,
|
||||||
fg_gap, grey_gap, term_fg_gap,
|
fg_gap, grey_gap, term_fg_gap,
|
||||||
full_color_map
|
full_color_map
|
||||||
)
|
)
|
||||||
|
|
||||||
_, term, _, term_norm_ac = generate_scheme_groups(
|
_, term, _, term_norm_ac = generate_scheme_groups(
|
||||||
mode, biome, metric, distance,
|
mode, biome, metric, distance,
|
||||||
l_base + l_step, l_step,
|
l_app, l_step,
|
||||||
fg_gap, grey_gap, term_fg_gap,
|
fg_gap, grey_gap, term_fg_gap,
|
||||||
term_color_map
|
term_color_map
|
||||||
)
|
)
|
||||||
_, _, _, term_bright_ac = generate_scheme_groups(
|
_, _, _, term_bright_ac = generate_scheme_groups(
|
||||||
mode, biome, metric, distance,
|
mode, biome, metric, distance,
|
||||||
l_base + l_step + 10, l_step,
|
l_app + term_bright_offset, l_step,
|
||||||
fg_gap, grey_gap, term_fg_gap,
|
fg_gap, grey_gap, term_fg_gap,
|
||||||
term_color_map
|
term_color_map
|
||||||
)
|
)
|
||||||
|
|
||||||
_, _, vim_mt, vim_ac = generate_scheme_groups(
|
_, _, vim_mt, vim_ac = generate_scheme_groups(
|
||||||
mode, biome, metric, distance,
|
mode, biome, metric, distance,
|
||||||
l_base + l_step, l_step,
|
l_app, l_step,
|
||||||
fg_gap, grey_gap, term_fg_gap,
|
fg_gap, grey_gap, term_fg_gap,
|
||||||
vim_color_map
|
vim_color_map
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import math
|
||||||
from types import GenericAlias
|
from types import GenericAlias
|
||||||
from argparse import ArgumentParser, _SubParsersAction
|
from argparse import ArgumentParser, _SubParsersAction
|
||||||
|
|
||||||
@@ -6,5 +7,29 @@ from coloraide import Color
|
|||||||
_SubParsersAction.__class_getitem__ = classmethod(GenericAlias)
|
_SubParsersAction.__class_getitem__ = classmethod(GenericAlias)
|
||||||
_SubparserType = _SubParsersAction[ArgumentParser]
|
_SubparserType = _SubParsersAction[ArgumentParser]
|
||||||
|
|
||||||
def oklch_distance(mc: Color, ac: Color) -> float:
|
def oklch_distance(xc: Color, yc: Color) -> float:
|
||||||
return mc.distance(ac, space="oklch")
|
"""
|
||||||
|
Compute the distance between two colors in OKLCH space.
|
||||||
|
|
||||||
|
Note: `xc` and `yc` are presumed to be OKLCH colors already, such that
|
||||||
|
`.coords()` yields an `(l, c, h)` triple directly rather than first
|
||||||
|
requiring conversion. When we can make this assumption, we save roughly an
|
||||||
|
order of magnitude in runtime.
|
||||||
|
|
||||||
|
1. `xc.distance(yc, space="oklch")`: 500k evals takes ~2s
|
||||||
|
2. This method: 500k evals takes ~0.2s
|
||||||
|
"""
|
||||||
|
|
||||||
|
l1, c1, h1 = xc.coords()
|
||||||
|
l2, c2, h2 = yc.coords()
|
||||||
|
|
||||||
|
rad1 = h1 / 180 * math.pi
|
||||||
|
rad2 = h2 / 180 * math.pi
|
||||||
|
x1, y1 = c1 * math.cos(rad1), c1 * math.sin(rad1)
|
||||||
|
x2, y2 = c2 * math.cos(rad2), c2 * math.sin(rad2)
|
||||||
|
|
||||||
|
dx = x1 - x2
|
||||||
|
dy = y1 - y2
|
||||||
|
dz = l1 - l2
|
||||||
|
|
||||||
|
return (dx**2 + dy**2 + dz**2)**0.5
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "monobiome"
|
name = "monobiome"
|
||||||
version = "1.4.0"
|
version = "1.3.1"
|
||||||
description = "Monobiome color palette"
|
description = "Monobiome color palette"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|||||||
Reference in New Issue
Block a user