1、版本
"antd": "^5.1.6",
2、新建draggerModal.tsx文件,将下方代码复制进去
/* eslint-disable prefer-destructuring */
import type { MouseEvent } from "react";
import React, { Component } from "react";
import type { ModalProps } from "antd/lib/modal";
import { Modal } from "antd";
import "antd/es/modal/style/index"
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;
private offsetLeft: number = 0;
private offsetTop: 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;
let tranX = deltaX + this.sumX;
let tranY = deltaY + this.sumY;
// 左侧
if (tranX < -this.offsetLeft) {
tranX = -this.offsetLeft;
}
// 右侧
const offsetRight =
document.body.clientWidth -
this.modalContent.parentElement.offsetWidth -
this.offsetLeft;
if (tranX > offsetRight) {
tranX = offsetRight;
}
// 上侧
if (tranY < -this.offsetTop) {
tranY = -this.offsetTop;
}
// 下侧
const offsetBottom =
document.body.clientHeight -
this.modalContent.parentElement.offsetHeight -
this.offsetTop;
if (tranY > offsetBottom) {
tranY = offsetBottom;
}
this.modalContent.style.transform = `translate(${tranX}px, ${tranY}px)`;
};
initialEvent = (open: boolean) => {
const { title } = this.props;
if (open && title) {
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.offsetLeft = this.modalContent.parentElement.offsetLeft;
this.offsetTop = this.modalContent.parentElement.offsetTop;
this.header.style.cursor = "all-scroll";
this.header.style.color = "green";
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.deltaX;
this.sumY += this.deltaY;
this.deltaX = 0;
this.deltaY = 0;
if (this.sumX < -this.offsetLeft) {
this.sumX = -this.offsetLeft;
}
const offsetRight =
document.body.clientWidth -
this.modalContent.parentElement.offsetWidth -
this.offsetLeft;
if (this.sumX > offsetRight) {
this.sumX = offsetRight;
}
// 上侧
if (this.sumY < -this.offsetTop) {
this.sumY = -this.offsetTop;
}
// 下侧
const offsetBottom =
document.body.clientHeight -
this.modalContent.parentElement.offsetHeight -
this.offsetTop;
if (this.sumY > offsetBottom) {
this.sumY = offsetBottom;
}
this.removeMove();
};
componentDidMount() {
const { open = false } = this.props;
this.initialEvent(open);
}
componentWillReceiveProps(newProps: any) {
const { open } = this.props;
if (newProps.open && !open) {
this.initialEvent(newProps.open);
}
if (open && !newProps.open) {
this.removeMove();
window.removeEventListener("mouseup", this.removeUp, false);
}
}
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 (
<Modal {...other} wrapClassName={wrapModalClassName}>
{children}
</Modal>
);
}
}
3、引入并使用
import AntDraggableModal from "/@/plugins/commonPlugins/draggerModal";
.......
<AntDraggableModal
open={visiable}
onOk={() => {
setVisiable(false);
}}
onCancel={() => {
setVisiable(false);
}}
width={1380}
title={data.cellName}
destroyOnClose={true}
footer={null}
closable={true}
centered={true}
key={data?.cellId}
closeIcon={<CloseOutlined style={{ color: "#fff" }} />}
bodyStyle={{ backgroundColor: "rgb(17, 17, 41)" }}
className={modalStyle.modal}
>
{visiable && <aModal data={prop} visiable={visiable} />}
</AntDraggableModal>
over~