使用React实现随机颜色选择器,JS如何生成随机颜色

背景

在标签功能中,由于有「背景色」属性,每次新增标签时都为选择哪种颜色犯难。因此,我们思考如何通过JS代码生成随机颜色,提取一个通用的随机颜色生成工具,并基于React框架封装随机颜色选择器组件。

实际效果

原理与思路

作为前端开发人员,我们知道HTML接受 RGB、HEX、HSL三种格式的颜色。虽然是不同的格式,但是它们的本质都是通过数字表达出颜色。

因为RGB、HEX、HSL 本身都是数字,那么通过生成随机数并组装成符合格式要求的数字,也就达到预期随机生成颜色的想法。

下面分别列举RGB和HEX格式的随机颜色生成思路

  • 以RGB格式为例,rbg(0,0,0)代表黑色,rbg(255,255,255)代表白色。所以我们通过JS的Math.random方法随机生成3个0~255之间的随机数,并且取整,将生成的三个随机数进行字符串拼接即可得到一个RGB格式的颜色。
  • 以HEX格式为例,#000000代表黑色, #FFFFFF代表白色。可以发现hex格式通常都是6位16进制的数字,每两位16进制数字分为一组,比如1~2位代表red,3~4代表blue,5~6代表green。同样的道理,通过Math.random方法随机生成3个0~255之间的随机数,通过JS的toString(16)方法将10进制随机数转化成16进制格式,最后通过字符串拼接得到HEX格式的颜色。

核心代码

  • RBG格式随机颜色生成方法

    jsx 复制代码
    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;
    }
  • HEX格式随机颜色生成方法

    jsx 复制代码
    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组件

这是标签背景随机颜色选择器的React组件代码,实现是非常简单的,可以直接复制使用。

实际运行效果可以看本文最开始的「实际效果」截图。对于标签功能,感兴趣的可以访问

标签 - 乐闻世界

typescript 复制代码
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>
  );
}
相关推荐
Cory.眼5 分钟前
WebRTC入门指南:实时通信零基础
javascript·webrtc·实时通信
前端架构师-老李29 分钟前
16 Electron 应用自动更新方案:electron-updater 完整指南
前端·javascript·electron
一只学java的小汉堡37 分钟前
HTML 01入门:从概念到开发环境搭建与页面头部配置
前端·css·html
拖拉斯旋风43 分钟前
📚 JavaScript 变量声明三剑客:`var`、`let`、`const` 学习笔记
javascript
用户21496515898751 小时前
从零搭建uniapp环境-记录
前端
可触的未来,发芽的智生3 小时前
追根索源:换不同的词嵌入(词向量生成方式不同,但词与词关系接近),会出现什么结果?
javascript·人工智能·python·神经网络·自然语言处理
努力写代码的熊大3 小时前
stack、queue与priority_queue的用法解析与模拟实现
java·前端·javascript
im_AMBER3 小时前
React 06
前端·javascript·笔记·学习·react.js·前端框架
wyzqhhhh3 小时前
前端常见的设计模式
前端·设计模式
IT_陈寒3 小时前
React 19重磅前瞻:10个性能优化技巧让你少写30%的useEffect代码
前端·人工智能·后端