React+Tailwind CSS渐变进度条颜色匹配问题求助
修复渐变进度条颜色异常问题
我正在使用React与Tailwind CSS开发带渐变效果的技能进度条,但当进度达到特定百分比(例如15%)时,颜色完全不符合预期——此时进度条应全部显示为蓝色,却出现了多种不同颜色。

相关代码
Tailwind CSS 自定义样式
.progressbar { /* Size */ height: 10px; /* Content alignment */ display: flex; flex-direction: row; justify-content: flex-start; align-items: stretch; /* Style */ border-radius: 60px; background-color: #f0ecec; overflow: hidden; } .bar { /* Size */ width: 0%; /* Style */ background: rgb(255, 174, 105); background: linear-gradient(to right, #12B0FF 0%, #4399E7 7%, #5282DF 15%, #6565D7 22%, #951CC1 30%, #A517B8 37%, #A717B3 45%, #AF18A8 52%, #C83E82 60%, #CF4978 67%, #DE5E62 75%, #E86E51 84%, #F27D42 93%, #FA8838 100%); } .progressbar-text-container { /* Size */ width: 30px; /* Content alignment */ display: flex; flex-direction: row; /* Styling */ font-weight: bold; font-size: 30px; }
ProgressBar.js 组件
import { motion, animate } from 'framer-motion'; import { useEffect, useState } from "react"; function Progressbar({ name, value }) { // Replaced useRef with useState const [progressText, setProgressText] = useState("0"); useEffect(() => { animate(parseInt(progressText), value, { duration: 1.5, onUpdate: (cv) => { // Updating state instead of direct DOM manipulation setProgressText(cv.toFixed(0)); } }); }, [value]); return ( <div className="progressbar-container py-2"> <div className="flex py-1 justify-between"> <p className="progress-bar-title">{name}</p> <div className="flex justify-end"> {/* Replaced ref with state variable */} <p className="progress-bar-title">{progressText}</p> <p className="progress-bar-title">%</p> </div> </div> <div className="progressbar"> <motion.div className="bar" animate={{ width: `${value}%`, }} transition={{ duration: 1.5 }} /> </div> </div> ); } export default Progressbar;
问题原因
当前进度条的渐变背景直接应用在.bar元素上,渐变会根据.bar自身的宽度渲染完整的渐变序列。比如当.bar宽度为15%时,渐变会在这15%的宽度内从第一个颜色过渡到15%位置的颜色,导致进度条出现多种颜色,而非预期的单一蓝色。
修复方案
我们需要根据进度百分比,从渐变序列中匹配对应的单一颜色,将其设置为进度条的背景色:
- 修改
Progressbar组件,添加颜色映射与匹配逻辑:
import { motion, animate } from 'framer-motion'; import { useEffect, useState } from "react"; // 定义渐变颜色的百分比映射 const colorStops = [ { percent: 0, color: '#12B0FF' }, { percent: 7, color: '#4399E7' }, { percent: 15, color: '#5282DF' }, { percent: 22, color: '#6565D7' }, { percent: 30, color: '#951CC1' }, { percent: 37, color: '#A517B8' }, { percent: 45, color: '#A717B3' }, { percent: 52, color: '#AF18A8' }, { percent: 60, color: '#C83E82' }, { percent: 67, color: '#CF4978' }, { percent: 75, color: '#DE5E62' }, { percent: 84, color: '#E86E51' }, { percent: 93, color: '#F27D42' }, { percent: 100, color: '#FA8838' } ]; // 根据进度百分比获取对应颜色 function getColorForPercent(percent) { for (let i = 1; i < colorStops.length; i++) { if (percent <= colorStops[i].percent) { return colorStops[i].color; } } return colorStops[colorStops.length - 1].color; } function Progressbar({ name, value }) { const [progressText, setProgressText] = useState("0"); useEffect(() => { animate(parseInt(progressText), value, { duration: 1.5, onUpdate: (cv) => { setProgressText(cv.toFixed(0)); } }); }, [value]); // 获取当前进度对应的颜色 const barColor = getColorForPercent(value); return ( <div className="progressbar-container py-2"> <div className="flex py-1 justify-between"> <p className="progress-bar-title">{name}</p> <div className="flex justify-end"> <p className="progress-bar-title">{progressText}</p> <p className="progress-bar-title">%</p> </div> </div> <div className="progressbar"> <motion.div className="bar" // 设置进度条背景色为匹配到的单一颜色 style={{ backgroundColor: barColor }} animate={{ width: `${value}%`, }} transition={{ duration: 1.5 }} /> </div> </div> ); } export default Progressbar;
- 移除
.bar原有的渐变背景样式,保留基础尺寸设置:
.bar { /* Size */ width: 0%; }
修改完成后,当进度达到15%时,进度条会完整显示渐变序列中15%位置的蓝色,符合预期效果。
内容的提问来源于stack exchange,提问作者SpicyyRiice
相关产品推荐
相关产品推荐

