React 模态框的拉伸和拖动

拖动使用 react-draggable 插件

App.js 

import { NodeExpandOutlined } from '@ant-design/icons';
import React, { useRef, useState } from 'react'; // 引入useState和useRef
import Draggable from 'react-draggable';



export default function Problem() {
  const [width, setWidth] = useState(400);
  const [height, setHeight] = useState(450);
  // 使用useRef保存调整大小时的宽度和高度
  const resizeRef = useRef({
    isResizing: false,
    newWidth: null,
    newHeight: null
  })
  const [tuod, setTuod] = useState(true)
  const handleResizeMouseDown = (resizeType, e) => {
    let x = e.pageX
    let y = e.pageY
    console.log(x, y);
    const parent = document.querySelector('.box_'); // 获取父级元素
    const parentRect = parent.getBoundingClientRect(); // 获取父级元素的位置信息
    const bleft = parentRect.left; // 获取父级元素相对于屏幕右边的坐标
    const btop = parentRect.top; // 获取父级元素的宽度
    const resizeFunction = resizeType === 'right'
      ? e => {
        if (x > e.pageX) {
          console.log('小');
          resizeRef.current.newWidth = e.pageX - e.target.getBoundingClientRect().left;
          resizeRef.current.isResizing = true;
        } else {
          console.log('大');
          resizeRef.current.newWidth = e.pageX - e.target.getBoundingClientRect().left - bleft;
          resizeRef.current.isResizing = true;
        }
      }
      : e => {
        if (y > e.pageY) {
          console.log('小');
          resizeRef.current.newHeight = e.pageY - e.target.getBoundingClientRect().top + 50;
          resizeRef.current.isResizing = true;
        } else {
          console.log('大');
          resizeRef.current.newHeight = e.pageY - e.target.getBoundingClientRect().top - btop + 50;
          resizeRef.current.isResizing = true;
        }
      };
    setTuod(false)
    const updateFunction = resizeType === 'right' ? setWidth : setHeight;
    const handleMouseUp = () => {
      setTuod(true)
      document.removeEventListener('mousemove', resizeFunction); //删除监听事件
      document.removeEventListener('mouseup', handleMouseUp);
      if (resizeRef.current.isResizing) { //当它修改成功后
        updateFunction(resizeType === 'right' ? resizeRef.current.newWidth : resizeRef.current.newHeight);
        resizeRef.current.isResizing = false;
      }
    };
    document.addEventListener('mousemove', resizeFunction);
    document.addEventListener('mouseup', handleMouseUp);
  };

  const [tdwidth, setTeidth] = useState(25);
  const [istou, setIstou] = useState(false)

  const tuoing = () => {
    setIstou(true)
  }

  const tuoed = () => {
    setIstou(false)
  }

  const [isshow, setIshow] = useState(true)
  return (
    <div className='problem' >

      <div style={{
        opacity: !isshow ? 0.5 : 1, pointerEvents:
          !isshow ? "none" : ""
      }}>
        <div>
          <h2 onClick={() => setIshow(!isshow)}>点击</h2>
        </div>
        <div>
          <p>www</p>
          <p>www</p>
          <p>www</p>
          <p>www</p>
        </div>
      </div>
      <Draggable axis="both" handle=".handle" defaultPosition={{ x: 0, y: 0 }} bounds=".problem" onDrag={tuoing} onStop={tuoed}>
        <div
          className="box_" style={{ display: isshow ? "none" : "", opacity: istou ? 0.8 : 1, backgroundColor: "white", position: "fixed", left: "200px", top: "100px", width: `${width}px`, height: `${height}px`, boxShadow: '0 0 5px 0px grey', userSelect: 'none' }}>
          <div className="handle">
            <span>用户模块管理</span>
            <span style={{ display: 'inline-block', float: "right", marginRight: "5px", fontSize: "20px" }} onClick={() => setIshow(true)}>x</span>
          </div>
          <div
            className='resize' style={{ position: 'absolute', top: 0, right: -1, width: '2px', height: '100%', cursor: 'e-resize' }}
            onMouseDown={(e) => handleResizeMouseDown('right', e)} />
          <div
            className='resizeBottom' style={{ position: 'absolute', bottom: 0, right: -1, width: '100%', height: '2px', cursor: 'n-resize' }}
            onMouseDown={(e) => handleResizeMouseDown('bottom', e)} />
          <div className='neirong'>
            <div style={{
              opacity: !tuod ? 0.3 : 1,

              display: istou ? "none" : ""
            }}>
              <h2>内容</h2>
            </div>
          </div>
        </div>
      </Draggable>
    </div>
  );
}

 App.css

.content_home{
    height: 617px;
    width: 375px;
}
.footer{
    position: fixed;
    bottom: 0px;
    height: 50px;
    width: 375px;
}
.top{
    position: fixed;
    top: 0px;
    height: 50px;
    width: 375px;
}
.content {
    position: fixed;
    top: 50px;
    height: 567px;
    width: 375px;
    overflow-y: auto;
}
.content::-webkit-scrollbar {
    display: none;
}
.problem{
    position: fixed;
    top: 50px;
    height: 567px;
    width: 100vw;
    overflow-y: auto;
}

.handle{
    background-color: #6c95db;
    color: white;
    height: 35px;
    line-height: 35px;
    text-indent: 1em;
    cursor: move;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值