效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/03170ceaba274568aee302f92c8b8ac6.gif)
Main
import { useState } from 'react';
import Progress from './Progress'
const contentStyle = {
margin: '200px auto',
width: '300px'
};
const index = () =>
{
const [count, setCount] = useState(50)
return (
<div style={contentStyle} >
<Progress percent={count} unSelectedColor={'#000'} strokeColor={{
from: 'rgb(161, 29, 102)',
to: 'rgb(83, 177, 36)',
}} />
</div>
);
};
export default index
JS
import { useState, useRef } from 'react';
import styles from './style.less'
const index = ({ percent, unSelectedColor, strokeColor }) =>
{
const [count, setCount] = useState(percent)
const myRef = useRef(null)
const bgDown = (e) =>
{
e = e || window.event
const { nativeEvent: { offsetX } } = e
setCount(Math.round(offsetX / myRef.current.clientWidth * 100))
myRef.current.addEventListener('mousemove', fn)
function fn (e)
{
const { offsetX } = e
let newCount = Math.round(offsetX / myRef.current.clientWidth * 100)
newCount <= 100 ? setCount(newCount) : setCount(100)
}
document.addEventListener('mouseup', (() =>
{
myRef?.current?.removeEventListener('mousemove', fn);
}))
}
return (
<div className={`${styles.progress} ${styles.progress_line} ${styles.progress_show_info}`}>
<div className={styles.progress_outer}>
<div id='inner' ref={myRef} style={{ backgroundColor: unSelectedColor && unSelectedColor }} onMouseDown={bgDown} className={styles.progress_inner}>
<div style={{ width: `${count}%`, backgroundImage: `linear-gradient(to right, ${strokeColor['from']}, ${strokeColor['to']}` }} className={styles.progress_bg}>
<span>{count}</span>
</div>
</div>
</div>
<span className={styles.progress_text}>{`${count}%`}</span>
</div>
);
};
export default index
CSS
.progress {
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5715;
list-style: none;
font-feature-settings: 'tnum', "tnum";
display: inline-block;
}
.progress_line {
position: relative;
width: 100%;
font-size: 14px;
}
.progress_outer {
display: inline-block;
width: 100%;
margin-right: 0;
padding-right: 0;
margin-right: calc(-2em - 8px);
padding-right: calc(2em + 8px);
}
.progress_inner {
position: relative;
display: inline-block;
width: 100%;
// overflow: hidden;
vertical-align: middle;
background-color: #f5f5f5;
border-radius: 100px;
// ! 这里可以加个 padding 效果
// padding: 3px;
}
.progress_bg {
position: relative;
background-color: #1890ff;
border-radius: 100px;
transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s;
height: 8px;
animation: progress-info 3s ease-out;
&::before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #fff;
border-radius: 10px;
opacity: 0;
animation: progress-active 2.4s cubic-bezier(0.23, 1, 0.32, 1) infinite;
content: '';
}
&::after {
content: "";
display: inline-block;
position: absolute;
right: -4px;
top: -8px;
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 3px solid #fff;
}
span {
display: inline-block;
position: absolute;
right: 6px;
top: -20px;
}
.progress-status-active .ant-progress-bg::before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #fff;
border-radius: 10px;
opacity: 0;
animation: progress-active 2.4s cubic-bezier(0.23, 1, 0.32, 1) infinite;
content: '';
}
@keyframes progress-active {
0% {
transform: translateX(-100%) scaleX(0);
opacity: 0.1;
}
20% {
transform: translateX(-100%) scaleX(0);
opacity: 0.5;
}
100% {
transform: translateX(0) scaleX(1);
opacity: 0;
}
}
}
@keyframes progress-info {
0% {
width: 0;
}
}
.progress_text {
display: inline-block;
width: 2em;
margin-left: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 1em;
line-height: 1;
white-space: nowrap;
text-align: left;
vertical-align: middle;
word-break: normal;
}
效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/5e702a3d66194a3296aee11862a7b4d4.gif)
JS
import { useState, useEffect } from 'react';
import styles from './style.less'
const index = () =>
{
const [count, setCount] = useState(0)
useEffect(() =>
{
setTimeout(() =>
{
setCount(80)
}, 1000);
}, [])
return (
<div className={styles.container}>
<div className={styles.progress}>
<div style={{ width: `${count}%` }} className={styles.progress_bg}></div>
<span>我套你猴子</span>
</div>
</div>
);
};
export default index
CSS
body {
margin: 300px;
background-color: pink;
width: 300px;
}
.progress {
display: inline-block;
width: 200px;
height: 3px;
background-color: hsla(0, 0%, 100%, .2);
vertical-align: middle;
.progress_bg {
position: relative;
background-color: #fff;
height: 3px;
// ! 线展开的过度效果
transition: all 3s;
// ! 线的宽度
width: 30%;
&::after {
content: "";
display: inline-block;
position: absolute;
right: -4px;
top: -8px;
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 3px solid #fff;
}
}
span {
font-size: 12px;
color: hsla(0, 0%, 100%, .4);
opacity: 0;
position: relative;
top: -5px;
letter-spacing: .5em;
transition: all .3s
}
&:hover span {
opacity: 1;
top: 0
}
}