在标签功能中,由于有「背景色」属性,每次新增标签时都为选择哪种颜色犯难。因此,我们思考如何通过JS代码生成随机颜色,提取一个通用的随机颜色生成工具,并基于React框架封装随机颜色选择器组件。
作为前端开发人员,我们知道HTML接受 RGB、HEX、HSL三种格式的颜色。虽然是不同的格式,但是它们的本质都是通过数字表达出颜色。
因为RGB、HEX、HSL 本身都是数字,那么通过生成随机数并组装成符合格式要求的数字,也就达到预期随机生成颜色的想法。
下面分别列举RGB和HEX格式的随机颜色生成思路
export function getRandomRGBColor(limit: number = 256) {
//十六进制颜色随机
const r = Math.floor(Math.random() * limit);
const g = Math.floor(Math.random() * limit);
const b = Math.floor(Math.random() * limit);
const color = `rgb(${r},${g},${b})`;
return color;
}
export function getRandomHEXColor(limit: number = 256) {
const getRandomHexNumber = (limit: number): string => {
let randomNum = Math.floor(Math.random() * limit).toString(16);
if (randomNum.length < 2) {
randomNum = "0" + randomNum;
}
return randomNum;
};
//十六进制颜色随机
const r = getRandomHexNumber(limit);
const g = getRandomHexNumber(limit);
const b = getRandomHexNumber(limit);
const color = `#${r}${g}${b}`;
return color;
}
这是标签背景随机颜色选择器的React组件代码,实现是非常简单的,可以直接复制使用。
实际运行效果可以看本文最开始的「实际效果」截图。对于标签功能,感兴趣的可以访问
import { useMemo, useState } from "react";
import { getRandomColor } from "@/utils/color";
import classnames from "classnames";
import { Check, Refresh } from "@icon-park/react";
import { nanoid } from "nanoid";
interface ColorSelectProps {
defaultValue: string;
value?: string;
onChange?: (value: string) => void;
}
export default function ColorSelect(props: ColorSelectProps) {
const { defaultValue, value, onChange } = props;
// 用于重新生成颜色
const [randomId, setRandomId] = useState("");
const colors = useMemo(() => {
// 随机生成6个颜色
return new Array(6).fill(0).map(() => getRandomColor());
}, [randomId]);
const targetColors = useMemo(() => {
// 过滤是否存在默认值的情况
return [...colors, defaultValue || ""].filter(
v => !!v && !["#"].includes(v),
);
}, [defaultValue, colors]);
return (
<div className="flex gap-2">
{targetColors.map(color => {
console.log("color--->", color);
return (
<div
key={color}
data-color={color}
onClick={() => onChange?.(color)}
className={classnames(
"h-8 w-8 cursor-pointer flex justify-center items-center",
)}
style={{ backgroundColor: color }}>
{value === color && (
<Check theme="multi-color" size="24" fill="#fff" />
)}
</div>
);
})}
<div
className="h-8 w-8 cursor-pointer flex justify-center items-center border border-solid border-color-BGBrown text-color-BGBrown text-P4-Regular"
onClick={() => setRandomId(nanoid())}>
<Refresh theme="outline" size="18" fill="#333" />
</div>
</div>
);
}