笔者常用的主题为 Sketch,这种主题涵盖了
颜色面板、
推荐色块、
RGB颜色输入等功能,比较完善。但是最近在写一个富文本编辑器,编写过程中遇到了一些问题,比如用户在点击推荐色块时,编辑器会失去焦点,无法对字体颜色进行更改。如果是编辑器自有的组件,可以使用以下代码
event.preventDefault();
2.1 HSV 色彩模型
2.2 HSV 转 RGB
\[rgb=\begin{cases}
(v,t,p),& \text{if $h_i=0$} \\
(q,v,& \text{if $h_i=1$} \\
(p,t),& \text{if $h_i=2$} \\
(p,q,v),& \text{if $h_i=3$} \\
(t,p,& \text{if $h_i=4$} \\
(v,q),& \text{if $h_i=5$} \\
\end{cases}\]
2.3 HSV 色彩模型在 ReactColor 中的实现
2.3.1 Hue 色相
颜色名称 |
红绿蓝含量 |
角度 |
代表物体 |
红色 |
R255,G0,B0 |
0° |
血液、草莓
|
橙色 |
R255,G128,B0 |
30° |
火、橙子
|
黄色 |
R255,G255,B0 |
60° |
香蕉、杧果
|
黄绿 |
R128,B0 |
90° |
柠檬 |
绿色 |
R0,B0 |
120° |
草、树叶
|
青绿 |
R0,B128 |
150° |
军装 |
青色 |
R0,B255 |
180° |
水面、天空
|
靛蓝 |
R0,B255 |
210° |
水面、天空
|
蓝色 |
R0,B255 |
240° |
海、墨水
|
紫色 |
R128,B255 |
270° |
葡萄、茄子
|
品红 |
R255,B255 |
300° |
火、桃子
|
紫红 |
R255,B128 |
330° |
墨水 |
background: linear-gradient(to right,#f00 0%,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,#f00 100%);
根据鼠标拖动的位置距离左边界的距离就可以计算出色相值。
/**
* 在颜色值发生变化时实时计算相应的色相值
* @param event
*/
const handleChange = (event: any) => {
if (!ref.current) {
return;
}
const clientRect = ref.current.getBoundingClientRect();
const { width: containerWidth } = clientRect;
const x: number = typeof event.pageX === 'number' ? event.pageX : event.touches[0].pageX;
const left = x - (clientRect.left + window.pageXOffset);
let innerHue;
// 处理边界值
if (left < 0) {
innerHue = 0;
} else if (left > containerWidth) {
innerHue = 359;
} else {
const percent = (left * 100) / containerWidth;
innerHue = (360 * percent) / 100;
}
setHue(innerHue);
props.onChange({ h: innerHue });
};
2.3.2 Saturation 饱和度与 Value 明度
其实用 CSS 表示也比较简单,使用渐变色来表示就可以实现该效果。
background: linear-gradient(to right,#fff,rgba(255,255,0));
background: linear-gradient(to top,#000,rgba(0,0));