current position:Home>Ant Design modal enables drag effects

Ant Design modal enables drag effects

2022-05-15 07:51:35User 4669777

Recently, the project team put forward a requirement during development , Need make ant-designModal Realize the function of dragging , I studied it , be based on and-designModal I encapsulate a antd-draggable-modal Components .

characteristic :

  • Support pop-up window opening in the middle
  • Support drag and drop title bar Drag and drop
  • Support multi-layer pop-up window drag

Realization principle

To achieve Modal The drag and drop , First of all, make it clear Modal What does your position have to do with , Open the browser , adopt F12 In the debug window, you can see , Modal The position is the same as class The attribute is ant-modal-content Related to the element of .

So the next idea is very simple , Set by listening for mouse events ant-modal-content Elemental transform Property to implement Modal Adjustment of position .

The code is as follows :

import React, { Component, MouseEvent } from 'react';
import AntdModal, { ModalProps } from 'antd/lib/modal';
import 'antd/es/modal/style/index.css';

export default class AntDraggableModal extends Component<ModalProps> {
  private simpleClass: string;
  private header: any;
  private contain: any;
  private modalContent: any;

  private mouseDownX: number = 0;
  private mouseDownY: number = 0;
  private deltaX: number = 0;
  private deltaY: number = 0;
  private sumX: number = 0;
  private sumY: number = 0;

  constructor(props: ModalProps) {
    super(props);
    this.simpleClass = Math.random()
      .toString(36)
      .substring(2);
  }

  handleMove = (event: any) => {
    const deltaX = event.pageX - this.mouseDownX;
    const deltaY = event.pageY - this.mouseDownY;

    this.deltaX = deltaX;
    this.deltaY = deltaY;

    this.modalContent.style.transform = `translate(${deltaX + this.sumX}px, ${deltaY + this.sumY}px)`;
  };

  initialEvent = (visible: boolean) => {
    const { title } = this.props;
    if (title && visible) {
      setTimeout(() => {
        window.removeEventListener('mouseup', this.removeUp, false);

        this.contain = document.getElementsByClassName(this.simpleClass)[0];
        this.header = this.contain.getElementsByClassName('ant-modal-header')[0];
        this.modalContent = this.contain.getElementsByClassName('ant-modal-content')[0];

        this.header.style.cursor = 'all-scroll';
        this.header.onmousedown = (e: MouseEvent<HTMLDivElement>) => {
          this.mouseDownX = e.pageX;
          this.mouseDownY = e.pageY;
          document.body.onselectstart = () => false;
          window.addEventListener('mousemove', this.handleMove, false);
        };

        window.addEventListener('mouseup', this.removeUp, false);
      }, 0);
    }
  };

  removeMove = () => {
    window.removeEventListener('mousemove', this.handleMove, false);
  };

  removeUp = () => {
    document.body.onselectstart = () => true;

    this.sumX = this.sumX + this.deltaX;
    this.sumY = this.sumY + this.deltaY;

    this.removeMove();
  };

  componentDidMount() {
    const { visible = false } = this.props;
    this.initialEvent(visible);
  }

  componentWillUnmount() {
    this.removeMove();
    window.removeEventListener('mouseup', this.removeUp, false);
  }

  render() {
    const { children, wrapClassName, ...other } = this.props;
    const wrapModalClassName = wrapClassName ? `${wrapClassName} ${this.simpleClass}` : `${this.simpleClass}`;
    return (
      <AntdModal
        {...other}
        wrapClassName={wrapModalClassName}
      >{children}</AntdModal>
    );
  }
}

stay AntDraggableModal In the constructor of the component , Randomly generate one simpleClass character string , Pass to AndModal Component's wrapClassName attribute , There are two main purposes for this :

  1. Easy to pass simpleClass Class to locate the pop-up window position
  2. When there are multiple pop-up windows , Can pass simpleClass Class to distinguish different pop-up windows , Realize multi-layer pop-up window drag function

One thing to pay attention to in usage is :

{this.state.visible && (
  <AntdDraggableModal
    title="Basic Modal"
    visible={this.state.visible}
    onOk={this.handleOk}
    onCancel={this.handleCancel}
  >
    <p>Some contents...</p>
    <p>Some contents...</p>
    <p>Some contents...</p>
    <Button onClick={() => this.setState({ visible2: true })}> Open the pop-up window 2</Button>
  </AntdDraggableModal>
)}

I have to write it this way , Because every time the pop-up window is closed, it will not be destroyed automatically , In other words, when the pop-up window is closed and then opened, we hope that the pop-up window position will be reinitialized .

summary

About ant-designMmodal That's all for the drag and drop package , I have released the component to npm The above , Interested students are welcome to install ,Have a nice weekend !

copyright notice
author[User 4669777],Please bring the original link to reprint, thank you.
https://en.chowdera.com/2022/131/202205102047500243.html

Random recommended