react使用react-draggable制作可拖拽弹出框

方式一:使用react-draggable实现拖拽

安装

yarn add react-draggable

使用

import Draggable from 'react-draggable';
export default function TableModal() {
  const [bounds, setBounds] = useState({
    left: 0,
    top: 0,
    bottom: 0,
    right: 0,
  });
  const draggleRef = useRef(null);
  const onStart = (_event, uiData) => {
    console.log('targetRect',_event, uiData)

    console.log(_event, uiData)
    const { clientWidth, clientHeight } = window.document.documentElement;
    const targetRect = draggleRef.current?.getBoundingClientRect();
    console.log('targetRect',targetRect)

    if (!targetRect) {
        return;
    }

    setBounds({
        left: -targetRect.left + uiData.x,
        right: clientWidth - (targetRect.right - uiData.x),
        top: -targetRect.top + uiData.y,
        bottom: clientHeight - (targetRect.bottom - uiData.y),
    });
  };

  return (
  <Draggable
    bounds={bounds}
    onStart={(event, uiData) => onStart(event, uiData)}
  >
      <div ref={draggleRef} 
        className={s.wrapPlantPop}  
      >
      // content
      </div>
  </Draggable>
)}

方式二:计算鼠标位置实现拖拽(不使用react-draggable)

1.使用antd Modal 组件,要想改变位置需要改变Modal style 的left 和top属性,其默认值分别为0,100

2.Modal 的标题可以使组件,给这个标题组件添加一个鼠标点击事件,记录下鼠标点击的位置;

当鼠标移动的时候计算鼠标当前的位置和初始的位置差就是弹窗相对于初始位置的移动距离,从而计算出弹窗的实际位置,

通过state 记录弹窗实际位置,从而更新弹窗的style,

3.计算鼠标的位置防止移出屏幕视图窗口

import React, { Component } from 'react';
import { Button, Modal } from 'antd';

class MoveModal extends Component {
  constructor(props) {
    super(props); // Modal 的初始值
    this.state = {
      styleTop: 100,
      styleLeft: 0,
    };
  }

  // 计算是否超出屏幕;超出后停止移动监听
  inWindow = (left, top, startPosX, startPosY) => {
    const H = document.body.clientHeight;
    const W = document.body.clientWidth;
    if (
      (left < 20 && startPosX > left) ||
      (left > W - 20 && startPosX < left) ||
      (top < 20 && startPosY > top) ||
      (top > H - 20 && startPosY < top)
    ) {
      document.body.onmousemove = null;
      document.body.onmouseup = null;
      return false;
    }
    return true;
  };

  onMouseDown = (e) => {
    e.preventDefault(); // 记录初始移动的鼠标位置
    const startPosX = e.clientX;
    const startPosY = e.clientY;
    const { styleLeft, styleTop } = this.state; // 添加鼠标移动事件
    document.body.onmousemove = (e) => {
      const left = e.clientX - startPosX + styleLeft;
      const top = e.clientY - startPosY + styleTop;
      if (this.inWindow(e.clientX, e.clientY, startPosX, startPosY)) {
        this.setState({
          styleLeft: left,
          styleTop: top,
        });
      }
    }; // 鼠标放开时去掉移动事件
    document.body.onmouseup = function () {
      document.body.onmousemove = null;
    };
  };

  showModal = () => {
    this.setState({
      visible: true,
    });
  };

  render() {
    const { styleLeft, styleTop, visible } = this.state;
    const style = { left: styleLeft, top: styleTop };

    return (
      <div>
        <Button type="primary" onClick={this.showModal}>
          Open Modal
        </Button>
        <Modal
          visible={visible}
          onCancel={()=>this.setState({visible:false})}
          style={style}
          footer={null}
          title={
            <div style={{ width: '100%', cursor: 'move' }} onMouseDown={this.onMouseDown}>
              标题
            </div>
          }
        >
          移动
        </Modal>
      </div>
    );
  }
}
export default MoveModal;
posted @ 2023-11-14 16:38  ZerlinM  阅读(1346)  评论(0编辑  收藏  举报