react之图片操作

75 阅读1分钟

包含: 拖拽 + 鼠标缩放

image.png

使用方式

1. imgChange代码

import { useState, useRef, useEffect } from 'react';
import { Button, Space } from "antd";

const Index = (props: any) => {

  //定义鼠标事件,入参为dom元素与useState函数
  const drag = (obj: any, set: any) => {
    // 鼠标被按下
    obj.onmousedown = (event: any) => {
      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";
      }
    }
    // 代码目的: 在img区域中页面不能滚动
    const scrollEvent = () => {
      window.scrollTo(0, 0)
      document.documentElement.style.position = 'fixed';
    }
       
    obj.addEventListener('mouseenter', () => {
      document.addEventListener('scroll', scrollEvent)
    })
    
    obj.addEventListener('mouseleave', () => {
      // 离开img区域页面可以滚动
      document.documentElement.style.position = 'static';
      document.removeEventListener('scroll', scrollEvent)
    })

    obj.onmousewheel = function (event: any) {
      if (event.wheelDelta > 0) {
        console.log("向上滚动");
        imgToSizeAdd()
      }
      if (event.wheelDelta < 0) {
        console.log("向下滚动");
        imgToSizeMinus()
      }
    }
  }

  // 定义一个dom元素并将他绑定在img标签上
  const container = useRef(null);
  const url = props.url
  //定义一个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);
  }, [zoom]);

  //放大
  const imgToSizeAdd = () => {
    let a = parseInt(zoom) + (4) + '%';
    console.log('放大', a);
    setZoom(a)
  }
  //缩小
  const imgToSizeMinus = () => {
    if (zoom == '60%') return
    let a = parseInt(zoom) + (-4) + '%';
    console.log('缩小', zoom);

    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%', display: 'flex', justifyContent: 'center' }}>
        <Space>
          <Button onClick={imgToSizeAdd}>放大</Button>
          <Button onClick={imgToSizeMinus}>缩小</Button>
          <Button onClick={restore}>还原</Button>
          <Button onClick={imgRoll}>左旋90度</Button>
          <Button onClick={imgRoll2}>右旋90度</Button>
        </Space>
      </div>
      <div
        style={{ width: '100%', height: '400px', overflow: "hidden", textAlign: 'center' }}
      >
        <img
          ref={container}
          src={url}
          style={{
            height: '400px',
            position: "relative",
            cursor: "grab",
            left: xyzTwo.left,
            top: xyzTwo.top,
            zoom: zoom,
            transform: transform
          }}
        />
      </div>
    </>
  );
};

export default Index;

2. 使用

image.png

image.png

3. 推荐库

infeng.github.io/react-viewe…

zmage.caldis.me/