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 组件可以有一个可选的 AbsoluteRelativeInclRelativeExcl,以及一个可选的 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:将 饱和度 转换为零,并将 亮度 转换为指定值,即灰度级别。
  • FadeToBlackFadeToGray 的特殊情况,亮度 值为 0。
  • FadeToWhiteFadeToGray 的特殊情况,亮度 值为 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,可以使用 FromInto 特性将其转换为 RgbColor

pub struct RgbColor {
    pub r: u8, 
    pub g: u8, 
    pub b: u8,
}

示例

examples/ 目录中包含一个小型GUI应用程序(使用 egui),其中包含一些示例面板,展示了库的主要功能。

如何构建和运行示例应用程序

cargo run --example main

1: 渐变

两种颜色之间的过渡缺乏想象力和创造力,但显然有一个宏可以做到这一点。

gradient

let mut kw = KolorWheel::new(self.color1, 5*5);
kw.with_macro(SpinMacro::GradientColor(self.color2));

请参阅完整示例以获取详细信息。

2: 照明/绝对值

通过指定目标亮度值简单地加深或变浅颜色是很常见的。

lit_abs

let mut kw = KolorWheel::new(self.color, 4*4);
kw.with_lightness(SpinMode::Absolute(self.lit));

请参阅完整示例以获取详细信息。

3-4: 色调/相对,色调/相对X

对于相对值,最后一步是否包含在结果中很重要,特别是在色调变换的情况下。

如果您只显示一次生成的调色板,则最后一个值应该是指定的值。

hue_reli

let mut kw = KolorWheel::new(self.color, 3*2);
kw.with_hue(SpinMode::RelativeIncl(self.hue));

如果您多次显示生成的调色板,以无限或循环的方式,则最后一个项目将与下一轮的第一个项目相匹配,因此应该省略。

hue_relx

let mut kw = KolorWheel::new(self.color, 3*2);
kw.with_hue(SpinMode::RelativeExcl(self.hue));

请参阅完整示例以获取详细信息。

5: 饱和度+亮度/相对

最常见的变换之一是在保持色调不变的同时一起改变饱和度和亮度。

hue_offsets

let mut kw = KolorWheel::new(self.color, 8*6);
kw.with_saturation(SpinMode::RelativeIncl(self.sat));
kw.with_lightness(SpinMode::RelativeIncl(self.lit));

请参阅完整示例以获取详细信息。

6: 色调偏移量

除了计算变换外,还可以将偏移量数组(切片)应用于任何通道。在这个例子中,对外部渐变中的每个项目应用了内部变换,它简单地说是一系列的色调偏移量。您可以在第一行和第五行中看到原始色调上的外部变换。

palette1

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

如果选择合适的值,可以在同一通道上使用计算变换和偏移。

palette1

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

虽然计算变换描述了一个基本调色板,但偏移值可以用于给特定项目赋予功能,例如,较暗的颜色可以用作字体颜色。

palette1

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]));

请参阅完整示例以获取详细信息。

无运行时依赖