React实现简单图片放大缩小旋转还原模块

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值