react优雅处理多条件鼠标拖拽位移

2022-08-26 16:12:01

本文实例为大家分享了react优雅处理多条件鼠标拖拽位移的具体代码,供大家参考,具体内容如下场景三种拖拽条件可纵轴横轴和全部方向如果加3个监听重复代码太多因为状态更改组件会重新渲染所以写的时...

本文实例为大家分享了react优雅处理多条件鼠标拖拽位移的具体代码,供大家参考,具体内容如下

react优雅处理多条件鼠标拖拽位移

场景

三种拖拽条件 可纵轴 横轴 和全部方向 如果加3个监听重复代码太多
因为状态更改组件会重新渲染 所以写的时候要多注意避免有大量代码的函数多次创建销毁

state

const [position, setPosition] = useState(axisPosition);

jsx

<Container
   style={{
    top: position.top + "px",
    left: position.left + "px",
   }}
  >
   <div>
    <span
     onMouseDown={handleDown(position, (p) => {
      setPosition({ ...p, left: position.left });
     })}
    ></span>
    <div onMouseDown={handleDown(position, setPosition)}></div>
    <span
     onMouseDown={handleDown(position, (p) => {
      setPosition({ ...p, top: position.top });
     })}
    ></span>
   </div&gphpt;
  </Container>

监听

const handleDown =
 (position: IPosition, setState: (position: IPosition) => void) => (e: React.MouseEvent<htmlElement, MouseEvent>) => {
  const startX = e.pageX;
  const startY = e.pageY;
  const { top, left } = position;
  const move = (ev: MouseEvent) => {
   const disX = ev.pageX - startX;
   const disY = ev.pageY - startY;
   setState({ left: left + disX, top: top + disY });
  };

  const cancel = () => {
   document.removeEventListener("mousemove", move);
   document.removeEventListener("mouseup", cancel);
   document.removeEventListener("mouseleave", cancel);
  };

  document.addEventListener("mousemove", move);
  document.addEventListener("mouseup", cancel);
  document.addEventListener("mouseleave", cancel);
 };

业务代码

/*
* @Author: hongbin
* @Date: 2022-04-03 13:38:02
* @LastEditors: hongbin
* @LastEditTime: 2022-04-03 21:49:42
* @Description:移动坐标轴
*/
import { FC, ReactElement, useEffect, useState } from "react";
import styled from "styled-components";
import { useElementContext } from "../../context/ElementContext";
import { FlexCenter } from "../../styled";

interface IProps {}

interface IPosition {
 top: number;
 left: number;
}

const handleDown =
 (position: IPosition, setState: (position: IPosition) => void) => (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
  const startX = e.pageX;
  const startY = e.pageY;
  const { top, left } = position;
  const move = (ev: MouseEvent) => {
   const disX = ev.pageX - startX;
   const disY = ev.pageY - startY;
   setState({ left: left + disX, top: top + disY });
  };

  const cancel = () => {
   document.removeEventListener("mousemove", move);
   document.removeEventListener("mouseup", cancel);
   document.removeEventListener("mouseleave", cancel);
  };

  document.addEventListener("mousemove", move);
  document.addEventListener("mouseup", canphpcel);
  document.addEventListener("mouseleave", cancel);
 };

const Axis: FC<IProps> = (): ReactElement => {
 const {python axisPosition } = useElementContext();
 const [position, setPosition] = useState<IPosition>(axisPosition);

 useEffect(() => {
  setPosition(axisPosition);
 }, [axisPosition]);

 return (
  <Container
   style={{
    top: position.top + "px",
    left: position.left + "px",
   }}
  >
   <div>
    <span
     onMouseDown={handleDown(position, (p) => {
      setPosition({ ...p, left: position.left });
     })}
    ></span>
    <div onMouseDown={handleDown(position, setPosition)}></div>
    <span
     onMouseDown={handleDown(position, (p) => {
      setPosition({ ...p, top: position.top });
     })}
    ></span>
   </div>
  </Container>
 );
};

export default Axis;

const Container = styled.div`
 position: absolute;
 z-index: 99999;
 transform: translateX(-6px);
 & > div {
  background: #c711ff;
  width: 0px;
  height: 0px;
  border-radius: 0px;
  border: 3px solid #c711ff;
  position: relative;
  ${flexCenter};
  span {
   position: absolute;
   :first-child {
    cursor: ns-resize;
    background-color: red;
    width: 2px;
    height: 3vw;
    transform: translateY(-60%);
    ::before {
     content: "";
     border: 4px solid red;
     top: 0;
     left: -3px;
     position: absolute;
     transform: scaleY(4) rotate(180deg);
     border-left-color: transparent;
     border-bottom-color: transparent;
     border-right-color: transparent;
     transform-origin: top;
    }
   }
   :last-child {
    cursor: ew-resize;
    width: 3vw;
    height: 2px;
    background-color: blue;
    transform: translateX(60%);
    ::before {
     content: "";
     border: 4px solid blue;
     top: -3px;
     right: 0;
     position: absolute;
     transform: scaleX(4) rotate(-90deg) translateY(50%);
     border-left-color: transparent;
     border-right-color: transparent;
     border-bottom-color: transparent;
    }
   }
  }
  div {
   cursor: move;
   width: inherit;
   height: inherit;
   border: inherit;
   border-radius: inherit;
   background-color: inherit;
   position: absolute;
   z-index: 1;
  }
 }
`;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。