亲宝软件园·资讯

展开

react 可拖拽进度条

Jedi Hongbin 人气:0

效果

请添加图片描述

/*
 * @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<IProps> = ({ value, onChange }): ReactElement => {
  const totalRef = useRef<HTMLDivElement>(null);

  return (
    <Container>
      <div ref={totalRef}>
        <div style={{ width: value * 100 + "%" }} />
      </div>
      <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;
}

加载全部内容

相关教程
猜你喜欢
用户评论