You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现调整颜色Opacity时同步更新TextField中的Hex值

实现滑块调整透明度时同步更新带透明度的Hex颜色值

当前已实现颜色预览框随opacity滑块变化,但TextField中的Hex值未同步更新为带透明度的8位十六进制格式,可通过以下步骤修复:

关键修改点

  • 新增透明度转十六进制的工具函数
  • 滑块值变化时同步计算并更新带透明度的Hex值
  • 调整初始值与表单验证规则适配8位Hex格式

1. 编写透明度转十六进制工具函数

// 将0-1范围的透明度值转换为两位十六进制字符串(00-FF)
const opacityToHex = (opacity) => {
  const hexNum = Math.round(opacity * 255);
  const hexStr = hexNum.toString(16);
  // 补前导零确保是两位
  return hexStr.length === 1 ? `0${hexStr}` : hexStr;
};

2. 修改滑块 onChange 逻辑

更新updateSlider函数,在设置透明度值后,立即计算并更新带透明度的Hex值:

const updateSlider = (event, newValue) => {
  settingForm.setFieldValue("opacityValue", newValue);
  // 提取基础Hex值(去除#,只保留前6位)
  const baseHex = settingForm.values.hexValue.replace('#', '').slice(0, 6);
  // 拼接透明度Hex,生成完整8位带透明度的颜色值
  const fullHex = `#${baseHex}${opacityToHex(newValue)}`;
  // 更新TextField的Hex值
  settingForm.setFieldValue("hexValue", fullHex);
};

3. 调整表单初始值

将初始透明度设为1(完全不透明),Hex值设为带全透明度的8位格式:

initialValues: {
  hexValue: "#272d85FF",
  opacityValue: 1
},

4. 更新表单验证规则

确保验证规则支持6位(无透明度)或8位(带透明度)的Hex格式:

// 假设使用Yup作为验证库
const settingFormSchema = Yup.object().shape({
  hexValue: Yup.string()
    .matches(/^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/, "请输入有效的6位或8位Hex颜色值")
    .required("Hex值为必填项"),
  opacityValue: Yup.number().min(0).max(1).required("透明度为必填项")
});

修改后的完整代码

import React from "react";
import { useFormik } from "formik";
import * as Yup from "yup";
import { Card, CardContent, Grid, Box, Typography, TextField, Slider, Button } from "@mui/material";
import LightModeIcon from '@mui/icons-material/LightMode';

const settingFormSchema = Yup.object().shape({
  hexValue: Yup.string()
    .matches(/^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/, "请输入有效的6位或8位Hex颜色值")
    .required("Hex值为必填项"),
  opacityValue: Yup.number().min(0).max(1).required("透明度为必填项")
});

export default function ColorPicker() {
  const [newHexCodes, setNewHexCodes] = React.useState([]);
  const [opacity, setOpacity] = React.useState([]);

  // 透明度转十六进制工具函数
  const opacityToHex = (opacity) => {
    const hexNum = Math.round(opacity * 255);
    const hexStr = hexNum.toString(16);
    return hexStr.length === 1 ? `0${hexStr}` : hexStr;
  };

  const settingForm = useFormik({
    initialValues: {
      hexValue: "#272d85FF",
      opacityValue: 1
    },
    validationSchema: settingFormSchema,
    onSubmit: (values) => {
      setNewHexCodes([values.hexValue, ...newHexCodes]);
      setOpacity([values.opacityValue, ...opacity]);
    }
  });

  const updateSlider = (event, newValue) => {
    settingForm.setFieldValue("opacityValue", newValue);
    const baseHex = settingForm.values.hexValue.replace('#', '').slice(0, 6);
    const fullHex = `#${baseHex}${opacityToHex(newValue)}`;
    settingForm.setFieldValue("hexValue", fullHex);
  };

  return (
    <Card>
      <CardContent sx={{ pl: 4, mt: 2 }}>
        <Grid
          container
          justifyContent="space-between"
          alignItems="center"
          spacing={2}
        >
          <Grid item xs={12} sm={6} md={4}>
            <Box
              display="flex"
              justifyContent="space-between"
              alignItems="center"
              flexWrap="wrap"
              gap={1}
            >
              <Box>
                <Typography variant="subtitle2" noWrap>
                  Hex Value
                </Typography>
              </Box>
              <Box>
                <TextField
                  size="small"
                  variant="outlined"
                  fullWidth
                  required
                  type="text"
                  placeholder="Enter Hex value"
                  name="hexValue"
                  {...settingForm.getFieldProps("hexValue")}
                  helperText={
                    settingForm?.touched?.hexValue &&
                    settingForm?.errors?.hexValue
                  }
                  error={Boolean(
                    settingForm?.touched?.hexValue &&
                      settingForm?.errors?.hexValue
                  )}
                />
              </Box>
              <Box>
                <Box
                  display="flex"
                  justifyContent="center"
                  component="span"
                  sx={{
                    backgroundColor: settingForm.values.hexValue,
                    width: "60px",
                    height: "35px"
                  }}
                />
              </Box>
            </Box>
          </Grid>
          <Grid item xs={12} sm={6} md={4}>
            <Box
              display="flex"
              justifyContent="space-evenly"
              alignItems="center"
              gap={2}
            >
              <LightModeIcon />
              <Box>
                <Typography variant="subtitle2">opacity</Typography>
              </Box>
              <Slider
                aria-label="Default slider"
                valueLabelDisplay="auto"
                onChange={updateSlider}
                value={settingForm.values.opacityValue}
                name="opacityValue"
                step={0.1}
                max={1}
              />
            </Box>
          </Grid>
          <Grid item xs={12} md={2}>
            <Box display="flex" justifyContent="flex-end">
              <Button
                color="primary"
                variant="contained"
                size="large"
                onClick={settingForm.handleSubmit}
              >
                ADD
              </Button>
            </Box>
          </Grid>
          <h2>you picked {newHexCodes.join(', ')}</h2>
        </Grid>
      </CardContent>
    </Card>
  );
}

内容的提问来源于stack exchange,提问作者user12302978

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 12:33:17