先来看看效果图
/*
- @Author: hongbin
- @Date: 2022-04-16 13:26:39
- @LastEditors: hongbin
- @LastEditTime: 2022-04-16 21:00:02
- @Description:拖动进度条组件
*/
import { FC, ReactElement, useRef } from “react”;
import styled from “styled-components”;
import { flexCenter } from “…/…/styled”;
interface IProps {
/**
- 0-1
/
value: number;
/* - callback 0-1
*/
onChange: (percent: number) => void;
}
const ProgressBar: FC = ({ value, onChange }): ReactElement => {
const totalRef = useRef(null);
return (
<div style={{ width: value * 100 + “%” }} />
<div
onMouseDown={(e) => {
const { offsetWidth } = totalRef.current!;
const stop = e.currentTarget;
const { offsetLeft } = stop;
stop.style[“left”] = offsetLeft + “px”;
const { pageX: start } = e;
const move = (e: MouseEvent) => {
let val = offsetLeft + e.pageX - start;
if (val <= 0) val = 0;
if (val >= offsetWidth) val = offsetWidth;
// stop.style[“left”] = val + “px”;
onChange(val / offsetWidth);
};
const clear = () => {
document.removeEventListener("mousemove", move);
document.removeEventListener("mouseup", clear);
document.removeEventListener("mouseleave", clear);
};
document.addEventListener("mousemove", move);
document.addEventListener("mouseup", clear);
document.addEventListener("mouseleave", clear);
}}
style={{ left: value * 100 + "%" }}
></div>
</Container>
);
};
export default ProgressBar;
const Container = styled.div position: relative; width: 10vw; height: 1vw; ${flexCenter}; & > :first-child { width: inherit; height: 0.5vw; background-color: var(--tint-color); border-radius: 10vw; overflow: hidden; display: flex; align-items: center; padding: 0.05vw; div { width: 5vw; height: 0.4vw; background-color: var(--deep-color); border-radius: 0.4vw; } } & > :last-child { width: 1vw; height: 1vw; background-color: var(--deep-color); border-radius: 1vw; position: absolute; cursor: pointer; transform: translateX(-0.5vw); svg { width: 0.9vw; } }
;
export const flexCenter = css display: flex; justify-content: center; align-items: center;
;
:root {
–deep-color: #978961;
–tint-color: #efe5d4;
}