WezTerm 配色编程:解析color:adjust_hue_fixed_ryb()与 RYB 艺术家色轮色调调整
【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm
color:adjust_hue_fixed_ryb(degrees)是 WezTerm Lua 配置 API 中Color对象的一个方法,它基于 RYB(红-黄-蓝)色彩模型在色轮上旋转指定角度,用于以艺术家配色思维生成互补色、三角色(triad)和方形色(square)等和谐色组。读完本文你将掌握该方法的使用方式、与 HSL 版本color:adjust_hue_fixed()的差异、其底层分段线性映射的实现原理,以及如何在.wezterm.lua中用它编程式地生成整套配色方案。
方法与版本背景
该方法在 WezTerm 版本20220807-113146-c2fee766中引入(与color:complement_ryb()、color:triad()、color:square()等同批出现)。它是 Color 对象 的实例方法,作用于已经通过wezterm.color.parse()解析、或其他 API 返回的Color对象上,返回值是新的Color对象,不会修改原对象。
Color对象内部以 SRGBA 存储颜色,因此无论调用方传入的原始格式是十六进制字符串、命名色还是from_hsla()构造的值,本方法都统一走"SRGBA → HSL → RYB 角度旋转 → HSL → SRGBA"的往返路径,最终输出一个可直接写回配色表的值。
基本用法
local wezterm = require 'wezterm' -- 解析一个颜色,然后按 RYB 色轮旋转 45 度 local base = wezterm.color.parse('#336699') local shifted = base:adjust_hue_fixed_ryb(45) return { color_scheme = '...', -- 在配置中把 shifted 应用到任意颜色相关配置项 }参数degrees是一个浮点数,表示旋转的角度,可以是正数(顺时针)也可以是负数(逆时针)。底层实现会通过normalize_angle对结果取模并规整到[0, 360)区间,因此传入370与10等价,传入-10等价于350。
RYB 与 HSL 色轮的本质区别
文档明确说明,本方法使用的是 RYB 色彩模型("artist's color wheel"),它比 RGB/HSL 模型更贴近艺术家对颜色混合的直觉:
- HSL 色轮以红(0°)→ 绿(120°)→ 蓝(240°)为三个主色轴,
adjust_hue_fixed()直接在这个色轮上旋转。但 RGB 空间下"红与青互为互补"这类结果并不符合传统颜料混色的直觉。 - RYB 色轮以红、黄、蓝为三个主色,是画家调色时对"哪些颜色放在一起和谐"的经验模型。RYB 上真正的互补色(如红与绿)在视觉与颜料混色语义上更自然。
对应地,仓库同时提供了两组 API:
| API(HSL 色轮) | API(RYB 色轮) |
|---|---|
color:adjust_hue_fixed(degrees) | color:adjust_hue_fixed_ryb(degrees) |
color:complement() | color:complement_ryb() |
color:triad() | (triad()基于 HSL,未提供 RYB 变体) |
color:square() | (square()基于 HSL) |
其中complement_ryb()正是adjust_hue_fixed_ryb(180.)的简写封装,见 color-types/src/lib.rs。两个方法的完整对比文档见 color:adjust_hue_fixed()。
经典色组规则
文档给出三种基于色轮角度的经典和谐色组,这些规则对 RYB 与 HSL 两个变体同样成立,只是旋转所在色轮不同:
- 互补色(complement):旋转 180 度得到与当前颜色互补的颜色。
- 三角色(triad):三个彼此相隔 120 度的颜色构成一组 triad。
- 方形色(square):四个彼此相隔 90 度的颜色构成一组 square。
在代码中这些规则被直接实现为方法:complement()调用adjust_hue_fixed(180.),triad()返回(adjust_hue_fixed(120.), adjust_hue_fixed(-120.))两个颜色,square()返回分别旋转90°/270°/180°的三个颜色(见 color-types/src/lib.rs)。这意味着你可以把adjust_hue_fixed_ryb当作底层原语,自行拼出"RYB 风格的 triad/square",例如:
local a = base:adjust_hue_fixed_ryb(120) local b = base:adjust_hue_fixed_ryb(-120) -- 与 a 一起构成 RYB 三角色源码级实现原理
核心实现位于 color-types/src/lib.rs:
/// Rotate the hue angle by the specified number of degrees, using /// the RYB color wheel pub fn adjust_hue_fixed_ryb(&self, amount: f64) -> Self { let (h, s, l, a) = self.to_hsla(); let h = rgb_hue_to_ryb_hue(h); let h = normalize_angle(h + amount); let h = ryb_huge_to_rgb_hue(h); Self::from_hsla(h, s, l, a) }执行流程分四步:
- 将当前 SRGBA 颜色转换为 HSLA,取得色相角
h(饱和度和亮度在旋转过程中保持不变,因此旋转只改变色相); - 通过
rgb_hue_to_ryb_hue把 RGB 色轮上的色相角映射到 RYB 色轮坐标系; - 加上旋转量
amount,并用normalize_angle规整到[0, 360); - 通过
ryb_huge_to_rgb_hue把结果映射回 RGB 色轮,再从 HSLA 还原为颜色。
两次色轮映射并非简单缩放,而是分段线性映射。rgb_hue_to_ryb_hue(color-types/src/lib.rs)把 RGB 色相区间[0°,35°)→[0°,60°)、[35°,60°)→[60°,122°)、[60°,120°)→[122°,165°)、[120°,180°)→[165°,218°)、[180°,240°)→[218°,275°)、[240°,300°)→[275°,330°)、[300°,360°)→[330°,360°)七段分别做线性插值;ryb_huge_to_rgb_hue(color-types/src/lib.rs)则执行完全相反的七段逆映射。线性插值由map_range(color-types/src/lib.rs)完成,其算法来源于 Material Design 色板生成工具中的rybcolor.js(代码注释中给出了出处引用)。正因如此,RYB 映射在 35°、60°、120° 等处存在拐点,旋转同样 180 度,两个变体产出的互补色在视觉上会有明显差异。
Lua 绑定与调用链
在 Lua 侧,ColorWrap结构体把方法逐一对接到 Rust 实现,并注册到color模块(lua-api-crates/color-funcs/src/lib.rs):
pub fn adjust_hue_fixed_ryb(&self, amount: f64) -> Self { Self(self.0.adjust_hue_fixed_ryb(amount).into()) }方法通过methods.add_method("adjust_hue_fixed_ryb", ...)(lua-api-crates/color-funcs/src/lib.rs)暴露给 Lua。因此调用链为:Luacolor:adjust_hue_fixed_ryb(n)→ColorWrap::adjust_hue_fixed_ryb→SrgbaTuple::adjust_hue_fixed_ryb(即上面展示的核心实现)。整个color模块中还包含parse、from_hsla、get_default_colors、load_scheme、save_scheme等工具函数(lua-api-crates/color-funcs/src/lib.rs),可以与色调调整组合出完整的配色生成流水线。
实战:编程式生成一套和谐配色
Color对象的方法体系(明度/饱和度调整、对比度计算、色相旋转)设计初衷就是支持在.wezterm.lua中程序化生成配色方案(见 Color 对象文档)。下面是一个把 RYB 旋转用于配色微调的完整示例:
local wezterm = require 'wezterm' local accent = wezterm.color.parse('#e07a5f') return { color_scheme = 'Catppuccin', colors = { -- 用 RYB 色轮旋转,得到与强调色呼应的前景/背景变体 foreground = accent:adjust_hue_fixed_ryb(30):lighten(0.15), background = accent:adjust_hue_fixed_ryb(180):darken(0.6), -- 选中色用互补色,保持对比又不刺眼 selection_fg = accent:complement_ryb(), selection_bg = accent:adjust_hue_fixed_ryb(180):lighten(0.3), }, }使用要点:
adjust_hue_fixed_ryb只旋转色相,不改变饱和度与亮度;如需同步调亮调暗,可链式调用lighten/darken(按比例缩放)或lighten_fixed/darken_fixed(按绝对值增减);- 返回值仍是
Color对象,可以继续链式调用其它方法,也可以直接赋给colors表中接受颜色的配置项; - 该方法与
complement_ryb()、complement()、triad()、square()同属于色相关系工具族,适合搭配使用。
注意事项
- 版本要求:本方法需要 WezTerm
20220807-113146-c2fee766或更高版本;低版本配置文件中直接调用会报错。 - 角度可负可超界:实现内置了取模规整,负数角度与超过 360° 的角度都能得到合理结果。
- RYB 与 HSL 结果不同:不要混用两套结果,同一需求下应固定选择其中一个变体,否则会出现"互补色不一致"的观感问题。
- 色相变换不涉及亮度/饱和度:若希望得到符合可读性要求的颜色,请配合
lighten、darken、saturate、desaturate或contrast_ratio使用。
如需了解不基于 RYB 的普通色相旋转版本,参见 color:adjust_hue_fixed();其余色相/明度/饱和度操作见 Color 对象方法索引。
【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考