React实现简单图片放大缩小旋转还原模块
工作需要在Model中实现一个简单的查看图片来检验表单字段的功能,antd提供的IMG为预览图形式的画廊,不符合要求,因此需要在react中实现一个简单的图片查看模块,在此记录。
效果预览
React实现简单图片缩放
代码实现
主要通过操作dom元素实现
import React, { useState, useRef, useEffect } from 'react';
import {Button} from "antd";
//示例图片,来自antd组件示例图片
let url="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png";
//定义鼠标事件,入参为dom元素与useState函数
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";
}
}
}
const Index=() => {
// 定义一个dom元素并将他绑定在img标签上
const container = useRef(null);
//定义一个transform来控制旋转角度实现旋转功能,current用来记录角度
const [transform,setTransform]=useState('')
const [current,setCurrent]=useState(0);
//定义偏离位置
const [xyzTwo, setXyzTwo] = useState({ left: 0, top: 0 });
//定义图片大小百分比
const [zoom,setZoom]=useState('100%')
// 拖拽
useEffect(() => {
if (container) drag(container.current, setXyzTwo);
}, []);
//放大
const imgToSizeAdd=()=>{
let a=parseInt(zoom) + ( 4 ) + '%';
setZoom(a)
}
//缩小
const imgToSizeMinus=()=>{
let a=parseInt(zoom) + ( -4 ) + '%';
setZoom(a)
}
//还原
const restore=()=>{
setZoom('100%')
setXyzTwo({ left: 0, top: 0 })
setTransform('')
setCurrent(0)
}
//左旋转
const imgRoll=()=>{
let a = (current - 90) % 360;
setTransform('rotate(' + a + 'deg)')
setCurrent(a)
}
//右旋转
const imgRoll2=()=>{
let a = (current + 90) % 360;
setTransform('rotate(' + a + 'deg)')
setCurrent(a)
}
return (
<>
<div style={{width:'100%',margin:'0 auto'}}>
<Button onClick={imgToSizeAdd}>放大</Button>
<Button onClick={imgToSizeMinus}>缩小</Button>
<Button onClick={restore}>还原</Button>
<Button onClick={imgRoll}>左旋90度</Button>
<Button onClick={imgRoll2}>右旋90度</Button>
</div>
{/*
*使用overflow:hidden实现当图片放大到超出父元素边框后仅显示边框内的内容
*/}
<div
style={{width:'100%',height:'100%',overflow:"hidden"}}
>
<img
ref={container}
src={url}
style={{
width:500,
position: "relative",
cursor: "grab",
left: xyzTwo.left,
top: xyzTwo.top,
zoom:zoom,
transform:transform
}}
/>
</div>
</>
);
};
export default Index;
参考文章
https://www.cnblogs.com/Buringke/p/6560028.html
https://blog.csdn.net/weixin_44953227/article/details/111353771