2 个稳定版本
1.1.1 | 2023年11月18日 |
---|---|
1.1.0 | 2023年11月2日 |
#8 in #spin
3MB
918 行
KolorWheel.rs
是什么?
这个crate旨在简化创建GUI应用程序调色板的过程。
具有略微不同的API和平台:[KolorWheel.js](https://github.com/ern0/kolorwheel.js/)
创建调色板的方式是指定一个基色和一些参数,这些参数会根据给定的 spin模式 和步数修改H, S, L的值。
感谢 [H2CO3](https://h2co3.github.io/) 对其审查和支持!
HSL颜色模型
HSL颜色模型中,颜色由 色调、饱和度 和 亮度 定义。
色调 是一个圆形维度,0°是红色,180°是青色,360°也是红色。
饱和度 从0到100%,0是灰色,100%是全色。
亮度 同样从0到100%,0是黑色,100%是白色。
注意,HSL颜色空间不是线性的。
- 当 饱和度 越接近零时,色调 的影响越小。
- 如果 饱和度 为0,则 色调 没有意义。
- 当 亮度 越远离50%时,色调 和 饱和度 的影响越小。
- 如果 亮度 为0或100%,则 色调 和 饱和度 完全没有影响。
- 并非所有值三元组都是不同的颜色,但不同的颜色有不同的值。
另外请注意,将HSL值转换为RGB是微不足道的,但将RGB转换为HSL则不是。例如,#000000
(黑色)颜色具有零 亮度,但 色调 和 饱和度 可以是任何值。
HSL颜色模型的缺陷
HSL模型没有表示人类视觉实际工作的方式。
H, S, L值的线性变化可能不会被人类眼睛线性感知。
另请参阅
- Pastel:一个用于生成、分析、转换和操作颜色的不错命令行工具
- Kolorwheel.js 文档:一些文档和想法
快速API概览
步骤1:使用基色和步数创建 KolorWheel
对象
let base_color = HslColor::new(0, 100, 40);
let mut kw = KolorWheel::new(base_color, 10);
步骤2:定义H/S/L的绝对或相对变化
kw.with_hue(SpinMode::Absolute(120));
kw.with_saturation(SpinMode::RelativeIncl(-15));
步骤3:可选地,在绝对/相对变化之上,可以指定偏移数组切片
kw.with_lightness(SpinMode::Offset(&[0, 15, 30]));
步骤4:可选地,结果可以分叉,因此每个结果项都使用项目颜色作为基色生成一系列颜色,只需指定子系列的大小即可
kw.fork(5);
kw.with_hue(SpinMode::RelativeIncl(45));
总项目数量将是原始计数和分支计数的乘积(在本例中:10 * 5 = 50);
步骤 5:结果可以通过迭代器获取。项目类型是 HslColor
,可以转换为 RgbColor
for hsl_color in kw {
let rgb_color: RgbColor = hsl_color.into();
//...
}
API 详细信息
创建 KolorWheel
对象
KolorWheel::new<T>(color:T,count: usize) -> Self
创建具有基本参数的 KolorWheel
对象
color
:基本颜色,应该是HslColor
或实现了Into<HslColor>
的任何类型。count
:颜色变换的步数,包括初始状态。
返回 KolorWheel
对象,该对象必须声明为可变的。
旋转轮子
这些方法在 KolorWheel
对象上应用指定的 SpinMode
。
它们返回可变引用以进行链式调用。
with_hue(&mut self,spin_mode:SpinMode) -> &mutKolorWheel
with_saturation(&mut self,spin_mode:SpinMode) -> &mutKolorWheel
with_lightness(&mut self,spin_mode:SpinMode) -> &mutKolorWheel
SpinMode
枚举列出了可能的旋转操作。
色调 的有效范围是 0 到 360°,但在溢出或下溢时将进行归一化,例如 365° -> 5° 或 -10° -> 350°。
饱和度 和 亮度 必须在 0 到 100% 之间。在溢出或下溢时将被截断,例如 99% + 5% -> 100% 或 10% - 25% = 0。
API 使用 i32
表示度数和百分比值。
pub enum SpinMode<'m> {
Still,
Absolute(i32),
RelativeIncl(i32),
RelativeExcl(i32),
Offset(&'m [i32]),
}
Still
:无变化时的默认值,在 API 调用中可能不会使用。Absolute
:设置绝对目标值。RelativeIncl
:设置相对目标值。目标值将包含在结果中。RelativeIncl
:设置相对目标值,目标值将不包括在结果中。当创建的调色板是环形时,这很有用,实际目标是下一轮的第一个颜色,因此最后一个颜色应该退一步。Offset
:定义一个列表,该列表偏移结果。如果偏移大小小于旋转大小,则偏移将重复。
H/S/L 组件可以有一个可选的 Absolute
、RelativeIncl
或 RelativeExcl
,以及一个可选的 Offset
。
旋转宏
此方法在 KolorWheel
对象上应用指定的 SpinMacro
。
它返回可变引用以进行链式调用。
with_macro(&mut self,spin_macro:SpinMacro) -> &mut Self
SpinMacro
变换是常见操作的快捷方式,它们在底层使用 SpinMode
实现。
pub enum SpinMacro {
GradientColor(HslColor),
FadeToGray(i32),
FadeToBlack,
FadeToWhite,
}
GradientColor
:简单渐变,设置 H、S 和 L 的绝对变换的快捷方式。目标颜色应该是HslColor
或实现了Into<HslColor>
的任何类型。FadeToGray
:将 饱和度 转换为零,并将 亮度 转换为指定值,即灰度级别。FadeToBlack
:FadeToGray
的特殊情况,亮度 值为 0。FadeToWhite
:FadeToGray
的特殊情况,亮度 值为 100%。
分支
为每个结果创建一个新的 spinner,结果作为基本颜色。
fork(&mut self,count: usize) -> &mut Self
count
:内部 spinner 的步骤数。
返回可变引用以进行链式调用。
整体步骤将是所有 count
参数的乘积,例如构造函数中的初始值,以及 fork()
调用中指定的值。
例如,
- 创建一个基础颜色为红色且具有4个步骤的
KolorWheel
, - 将变换
SpinMode::Absolute
添加到蓝色中,然后 - 调用
fork()
并传入计数为10,添加一个宏变换SpinMacro::FadeToWhite
。
我们得到的结果是
- 结果的第一种颜色将是红色,然后
- 它在10步中淡入白色。
- 第11种颜色将是紫色(距离蓝色更近1/4步),并且
- 它将在10步中淡入白色,
...以此类推。结果的总数将是 4 * 10 = 40。
结果
可以通过迭代器获取结果
let mut kw = KolorWheel::new( ... );
...
for hsl_color in kw {
let rgb_color: RgbColor = hsl_color.into();
...
}
结果类型是 HslColor
,可以使用 From
和 Into
特性将其转换为 RgbColor
pub struct RgbColor {
pub r: u8,
pub g: u8,
pub b: u8,
}
示例
在 examples/
目录中包含一个小型GUI应用程序(使用 egui),其中包含一些示例面板,展示了库的主要功能。
如何构建和运行示例应用程序
cargo run --example main
1: 渐变
两种颜色之间的过渡缺乏想象力和创造力,但显然有一个宏可以做到这一点。
let mut kw = KolorWheel::new(self.color1, 5*5);
kw.with_macro(SpinMacro::GradientColor(self.color2));
请参阅完整示例以获取详细信息。
2: 照明/绝对值
通过指定目标亮度值简单地加深或变浅颜色是很常见的。
let mut kw = KolorWheel::new(self.color, 4*4);
kw.with_lightness(SpinMode::Absolute(self.lit));
请参阅完整示例以获取详细信息。
3-4: 色调/相对,色调/相对X
对于相对值,最后一步是否包含在结果中很重要,特别是在色调变换的情况下。
如果您只显示一次生成的调色板,则最后一个值应该是指定的值。
let mut kw = KolorWheel::new(self.color, 3*2);
kw.with_hue(SpinMode::RelativeIncl(self.hue));
如果您多次显示生成的调色板,以无限或循环的方式,则最后一个项目将与下一轮的第一个项目相匹配,因此应该省略。
let mut kw = KolorWheel::new(self.color, 3*2);
kw.with_hue(SpinMode::RelativeExcl(self.hue));
请参阅完整示例以获取详细信息。
5: 饱和度+亮度/相对
最常见的变换之一是在保持色调不变的同时一起改变饱和度和亮度。
let mut kw = KolorWheel::new(self.color, 8*6);
kw.with_saturation(SpinMode::RelativeIncl(self.sat));
kw.with_lightness(SpinMode::RelativeIncl(self.lit));
请参阅完整示例以获取详细信息。
6: 色调偏移量
除了计算变换外,还可以将偏移量数组(切片)应用于任何通道。在这个例子中,对外部渐变中的每个项目应用了内部变换,它简单地说是一系列的色调偏移量。您可以在第一行和第五行中看到原始色调上的外部变换。
let mut kw = KolorWheel::new(self.color1, self.rows);
kw.with_macro(SpinMacro::GradientColor(self.color2));
kw.fork(self.count);
kw.with_hue(SpinMode::Offset(&self.values[0 .. self.cols]));
请参阅完整示例以获取详细信息。
7: 调色板1
如果选择合适的值,可以在同一通道上使用计算变换和偏移。
color: HslColor::new(20, 70, 60),
hue_offsets: [0, 0, 0, 0, 120],
lit_offsets: [0, 0, 0, 0, -60],
(...)
let mut kw = KolorWheel::new(self.color, 5);
kw.with_hue(SpinMode::RelativeIncl(75));
kw.with_hue(SpinMode::Offset(&self.hue_offsets[0..5]));
kw.with_lightness(SpinMode::RelativeIncl(30));
kw.with_lightness(SpinMode::Offset(&self.lit_offsets[0..5]));
请参阅完整示例以获取详细信息。
8: 调色板2
虽然计算变换描述了一个基本调色板,但偏移值可以用于给特定项目赋予功能,例如,较暗的颜色可以用作字体颜色。
color: HslColor::new(240, 80, 70),
sat_offsets: [60, 0, 0, 70, 0, 0],
lit_offsets: [-40, 0, 0],
(...)
let mut kw = KolorWheel::new(self.color, 3*2);
kw.with_hue(SpinMode::RelativeIncl(90));
kw.with_saturation(SpinMode::RelativeIncl(-20));
kw.with_saturation(SpinMode::Offset(&self.sat_offsets[0..6]));
kw.with_lightness(SpinMode::Offset(&self.lit_offsets[0..3]));
请参阅完整示例以获取详细信息。