我正在使用 React 和 Tailwind CSS,我正在尝试做一个带有渐变颜色的技能进度条,但当它达到一定百分比时,颜色根本不匹配。
例如全宽度的15%,它应该是全蓝色而不是不同的颜色。我该如何解决它?
这是它的代码
顺风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
元素具有相同的 width
或 100%
,以便它们的背景渐变大小相同。然后,使用 clip-path:
inset()
设置其绘制尺寸:
const { motion, animate } = Motion;
const { useEffect, useState } = 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={{
clipPath: `inset(0 ${100 - value}% 0 0)`,
}}
transition={{
duration: 1.5
}}
/>
</div>
</div>
);
};
function App() {
return (
<React.Fragment>
<Progressbar value={100} name="foo"/>
<Progressbar value={50} name="bar"/>
<Progressbar value={25} name="baz"/>
</React.Fragment>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App/>);
.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: 100%;
/* 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%);
clip-path: inset(0 100% 0 0);
}
.progressbar-text-container {
/* Size */
width: 30px;
/* Content alignment */
display: flex;
flex-direction: row;
/* Styling */
font-weight: bold;
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/framer-motion.js" integrity="sha256-sS+KKDemoS6qg22Hi++wc5PAlgej08U6vDUKk/Y9K8Y=" crossorigin="anonymous"></script>
<script src="https://cdn.tailwindcss.com/3.3.3"></script>
<div id="app"></div>