palette.js颜色科学揭秘:RGB、线性RGB与HSV转换原理及环状彩虹色生成机制
【免费下载链接】palette.jsScript for generating colour palettes for use with graphs, charts and cartography.项目地址: https://gitcode.com/gh_mirrors/pa/palette.js
palette.js 是 Google 开源的一款颜色调色板生成库,专为图表、图形与地图提供科学配色。本文带你快速读懂 palette.js 背后的颜色科学:RGB 颜色如何编码、线性 RGB 为何要做 gamma 校正、HSV 转换的"六段法"原理,以及环状彩虹色生成机制如何做到首尾颜色不重复 🎨。
🎨 快速认识:palette.js 能做什么
对 palette.js 来说,一次函数调用就能得到一整条配色,例如palette('tol-sq', 10)即生成 10 色的顺序色板,palette('rainbow', 12)则生成 12 色环状彩虹色板。库中内置了三大类配色分组:
- qualitative(定性):用于区分不同类别,如饼图图例
- sequential(顺序):从浅到深表示数值大小,如热力图
- diverging(发散):从两个极端向中性色过渡,如偏差图
理解两个核心概念即可玩转 API:**palette(调色板)**是一组固定数量的RRGGBB十六进制颜色序列;**scheme(配色方案)**是一个可调用的"生成器函数",负责按任意数量生产调色板。项目结构非常精简:
| 文件 | 作用 |
|---|---|
| palette.js | 核心库:颜色转换函数 + 全部内置色板(约 1500 行) |
| demo.js | 演示页脚本:渲染所有色板,支持色盲模拟 |
| demo.html | 演示页:拖动滑块实时预览 1–100 色 |
| README.md | 官方使用文档与色板命名规则 |
| package.json | npm 包信息(包名 google-palette) |
📝 颜色如何编码:RGB 值到 "RRGGBB" 字符串
所有内置色板最终都输出小写的 6 位十六进制字符串(如ff8000),可直接拼上#用于 CSS。这一步由rgbColor函数完成(见 palette.js),逻辑非常直白:
- 三个通道值各自限制在 [0, 1] 区间内(超出会被
clamp函数截断,见 palette.js) - 乘以 255 并四舍五入,得到 0–255 的整数
- 转成两位十六进制,不足两位补零,最后拼接
这个clamp截断看似不起眼,却很关键——它保证即使自定义颜色函数在边界处"算飞了"(比如超过 1),输出也始终是合法颜色,而不会报错。
🌗 线性 RGB 与 sRGB:gamma 校正的奥秘
屏幕上的颜色数值并不是光能量的"线性"记录。人眼对暗部更敏感,因此 sRGB 标准给颜色加了gamma 曲线:数值上的中点(128)看起来比实际亮度中点更亮。
如果要"按物理光强"处理颜色(比如做插值、混合),就必须先换算回线性空间,处理完再转回来。palette.js 提供的linearRgbColor(见 palette.js)实现了标准的 sRGB 分段公式:
- 当
v ≤ 0.0031308时:v = 12.92 × v - 否则:
v = 1.055 × v^(1/2.4) − 0.055
几个典型换算结果能直观感受这条曲线:
| 线性 RGB 值 | 转换后 (0–255) | 十六进制 | 直观效果 |
|---|---|---|---|
| 0.0 | 0 | 00 | 纯黑 |
| 0.04 | ≈ 56 | 38 | 低光区被明显提亮 |
| 0.5 | ≈ 188 | bc | 中间调已升至约 74% |
| 1.0 | 255 | ff | 纯白 |
💡实践意义:在两个颜色之间插值时,如果在线性空间计算再经 gamma 转换输出,中间过渡色会自然、不"发灰",这正是 palette.js 让自定义色板保持视觉平滑的底层工具。
🌈 HSV 转换原理:六段法拆解色相环
HSV 用三个直觉维度描述颜色:H(色相 0–1,对应 0°–360°)、S(饱和度)、V(明度)。hsvColor函数(见 palette.js)把色相环切成 6 段,每段恰好对应 RGB 色轮的一条棱边:
| 色相段(h×6 取整) | RGB 通道排列 | 颜色过渡 |
|---|---|---|
| 0 | (v, x, m) | 红 → 黄 |
| 1 | (x, v, m) | 黄 → 绿 |
| 2 | (m, v, x) | 绿 → 青 |
| 3 | (m, x, v) | 青 → 蓝 |
| 4 | (x, m, v) | 蓝 → 品红 |
| 5 | (v, m, x) | 品红 → 红 |
其中m = v × (1 − s)是饱和度垫出的"底色",x = v × (1 − s × |h%2 − 1|)是在每段内做线性变化的中间通道。整个转换没有任何循环与三角函数,只有一个 switch 六分支——这是性能与可读性兼顾的经典实现。饱和度与明度默认都为 1,即最鲜艳的纯色。
🔄 环状彩虹色生成机制:首尾为何不重复
色相环有个"陷阱":0° 和 360° 都是正红色。如果按常规方式在 [0, 1] 上均匀取 n 个点(步长1/(n−1)),第一个和最后一个颜色完全相同,白白浪费一个色位,图上会出现两条挨着的"红条"。
palette.js 用cyclic(环状)采样优雅地解决了这个问题(见 palette.js):当颜色函数首尾同色时,步长改为(end − start) / n,从 0 开始取 n 个点,最末一个停在(n−1)/n——刚好在转回起点之前"刹住车"。一行公式(palette.js):
step = (opt_end - opt_start) / (opt_cyclic ? i : (i - 1))
内置的rainbow方案正是这样注册的:HSV 色相函数 + 环状采样 + 定性分组(见 palette.js),可以生成任意数量的彩虹色板。按 12 等分实际采样的结果如下(每个单元格即该色):
| ff0000 | ff8000 | ffff00 | 80ff00 | 00ff00 | 00ff80 | 00ffff | 0080ff | 0000ff | 8000ff | ff00ff | ff0080 |
⚠️ 注意:
rainbow不是色盲友好(红绿难以区分),所以它的-cbf查询会返回空。演示页内置了红盲/绿盲/灰度模拟(见 demo.js),你可以亲眼验证这一点。
🗺️ 内置色板一览:从图表到地图的科学配色
除了程序化生成的彩虹,库还内置了大量"人工精心调校"的色板,全部可通过名称调用(完整清单见 palette.js):
| 名称 | 分组 | 特点 |
|---|---|---|
rainbow | 定性 | HSV 环状采样,可生成任意数量颜色 |
mpn65 | 定性 | 65 色大色板,适合批量图表自动配色 |
tol/tol-sq/tol-dv/tol-rainbow | 定性/顺序/发散/定性 | Paul Tol 数学推导配色,全部色盲友好 |
cb-YlGn…cb-Spectral等 27 组 | 顺序/发散/定性 | ColorBrewer 地图配色标准,每档 3–12 色 |
sol-base/sol-accent | 顺序/定性 | Solarized 终端风格配色 |
其中tol-sq的顺序色板最有意思:它是用误差函数 erf对三个通道做平滑函数得到的(见 palette.js),从浅蓝平滑过渡到深蓝,任意取色都协调。
🔍色盲友好(CBF)是库的一等公民:每个方案都记录cbf_max(最多多少色仍色盲友好),调用时只需在名称后加-cbf后缀,如palette('qualitative-cbf', 8),即可只获得色盲友好的色板。
🚀 三步上手:生成你的第一个配色
获取代码
git clone https://gitcode.com/gh_mirrors/pa/palette.js引入脚本:在页面中通过 script 标签加载
palette.js即可,无依赖。调用生成:
palette('tol-sq', 10)生成顺序色板;palette(['sequential'], 10, 1)取顺序组的第 2 个方案,方便为不同数据系列分配互不冲突的配色;传入负数(如-8)则得到倒序颜色。
✅ 小结:palette.js 颜色科学要点
- RGB 编码:通道值 clamp 到 [0,1] → 乘 255 → 转十六进制,输出统一的
RRGGBB字符串 - 线性 RGB:通过 sRGB 分段公式做 gamma 校正,让颜色混合"符合物理直觉"
- HSV 转换:色相环六段法 + 线性插值,无三角函数、高效易读
- 环状彩虹色:cyclic 采样把步长从
1/(n−1)改为1/n,巧妙避开首尾同色 - 科学配色:内置 Paul Tol、ColorBrewer、mpn65 等方案,并原生支持色盲友好筛选
理解这些原理后,无论是做数据可视化还是地图着色,你都能 confidently 选对颜色、并知道为什么 📊。
【免费下载链接】palette.jsScript for generating colour palettes for use with graphs, charts and cartography.项目地址: https://gitcode.com/gh_mirrors/pa/palette.js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考