主要用到函数
名称 | 归类 |
---|---|
useState | react状态 |
useRef | react获取ref |
useEffect | react初始化函数 |
onmousedown | js鼠标按下 |
onmousemove | js鼠标移动 |
onmouseup | js鼠标抬起 |
这个基于 Ant-Design-Pro 4.1.0, 里面用到了一些 Ant Design 的UI 组件
逻辑代码
import React, { useState, useRef, useEffect } from 'react';
import { Col } from 'antd';
import { MinusCircleOutlined, PlusCircleOutlined } from "@ant-design/icons";
import "./PictureModule.less";
const drag = (obj, set) => {
// 鼠标被按下
obj.onmousedown = (event) => {
event = event || window.event;
// 阻止默认事件
event.preventDefault();
// 鼠标手
obj.style.cursor = "grabbing";
// 最大移动距离
var maxMoveX = obj.clientWidth - 100;
var maxMoveY = obj.clientHeight - 100;
// 计算鼠标当前坐标 = 鼠标按下坐标 - 元素当前坐标(距离父元素距离)
// div的水平偏移量 鼠标.clentX - 元素.offsetLeft
// div的垂直偏移量 鼠标.clentY - 元素.offsetTop
var ol = event.clientX - obj.offsetLeft;
var ot = event.clientY - obj.offsetTop;
// 绑定鼠标移动事件
document.onmousemove = (event2) => {
event2 = event2 || window.event;
// 计算移动距离 = 当前鼠标坐标 - 鼠标按下坐标
var left = event2.clientX - ol;
var top = event2.clientY - ot;
// 判断左右移动距离
if (left >= maxMoveX) {
left = maxMoveX;
} else if (left <= (-maxMoveX)) {
left = -maxMoveX;
}
// 判断上下移动距离
if (top >= maxMoveY) {
top = maxMoveY;
} else if (top <= (-maxMoveY)) {
top = -maxMoveY;
}
set({ left, top });
}
// 绑定一个鼠标松开事件
document.onmouseup = () => {
// 取消鼠标移动事件
document.onmousemove = null;
document.onmouseup = null;
// 还原鼠标手
obj.style.cursor = "grab";
}
}
}
export default ({ memoize, titleInfo, coords }) => {
// 缩放
const [scale, setScale] = useState(1);
const [scaleTwo, setScaleTwo] = useState(1);
// 拖拽
const [xyz, setXyz] = useState({ left: 0, top: 0 });
const [xyzTwo, setXyzTwo] = useState({ left: 0, top: 0 });
// 盒子元素
const container = useRef(null);
const containerTwo = useRef(null);
// 放大
const handleZoomIn = (val) => {
if (val === 1) {
setScale(scale + 0.5);
} else if (val === 2) {
setScaleTwo(scaleTwo + 0.5)
}
};
// 缩小
const handleZoomOut = (val) => {
if (val === 1) {
if (scale <= 1) {
setScale(1);
setXyz({ left: 0, top: 0 });
} else {
setScale(scale - 0.5);
}
} else if (val === 2) {
if (scaleTwo <= 1) {
setScaleTwo(1);
setXyzTwo({ left: 0, top: 0 });
} else {
setScaleTwo(scaleTwo - 0.5);
}
}
};
useEffect(() => {
if (container) drag(container.current, setXyz);
if (containerTwo) drag(containerTwo.current, setXyzTwo);
}, []);
return (
<>
<Col span={9}>
<div className="picture_title_box">
<div className="title_text" title={titleInfo.srcName}>标准文档:{titleInfo.srcName}</div>
<div className="title_btn_icon">
<MinusCircleOutlined onClick={() => handleZoomOut(1)} />
<PlusCircleOutlined onClick={() => handleZoomIn(1)} />
</div>
</div>
<div id="LeftXyzContainer" className="container_box">
<div
ref={container}
style={{
position: "relative",
left: xyz.left, top: xyz.top,
transform: `scale3d(${scale}, ${scale}, 1) rotate(0deg)`,
}}
>
<img src={memoize.src} width="100%" alt="图片加载失败" />
<div style={{ position: 'absolute', backgroundColor: 'rgb(82, 196, 26, 0.5)', width: 0, height: 0, ...coords.left }} />
</div>
</div>
</Col>
<Col span={9}>
<div className="picture_title_box">
<div className="title_text" title={titleInfo.dstName}>比对文档:{titleInfo.dstName}</div>
<div className="title_btn_icon">
<MinusCircleOutlined onClick={() => handleZoomOut(2)} />
<PlusCircleOutlined onClick={() => handleZoomIn(2)} />
</div>
</div>
<div id="RightXyzContainer" className="container_box">
<div
ref={containerTwo}
style={{
position: "relative",
cursor: "grab",
left: xyzTwo.left, top: xyzTwo.top,
transform: `scale3d(${scaleTwo}, ${scaleTwo}, 1) rotate(0deg)`,
}}
>
<img src={memoize.dst} width="100%" alt="图片加载失败" />
<div style={{ position: 'absolute', backgroundColor: 'rgb(82, 196, 26, 0.5)', width: 0, height: 0, ...coords.right }} />
</div>
</div>
</Col>
</>
);
};
样式
@import '~antd/es/style/themes/default.less';
// 标题盒子
.picture_title_box {
height: 40px;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fafafa;
}
// 标题文字
.title_text {
flex: 1;
font-size: 16px;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 标题按钮
.title_btn_icon {
width: 50px;
font-size: 18px;
margin-left: 24px;
cursor: pointer;
display: flex;
justify-content: space-between;
}
// 容器盒子
.container_box {
overflow: hidden;
position: relative;
border: 1px solid #a5b1b8;
background-color: #f3f3f3;
}