升级版js实现图片拖拽、根据鼠标位置放大、缩小功能

38 阅读1分钟
const canvasImage = function (path, annotations) {
    let imageUrl = '';
    imageUrl = path;
    let initState = true;
    let scale = 1; let originX = 0; let originY = 0; let isDragging = false; let lastX; let lastY;
    const canvas = document.getElementById('annotationCanvas');

    // 清空画布内容和标注信息
    canvas.innerHTML = '';

    canvas.style.display = 'block';
    const ctx = canvas.getContext('2d');
    const image = new Image();
    function resizeCanvas() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      draw();
    }
    // 添加关闭按钮
    const closeButton = document.createElement('button');
    closeButton.innerHTML = 'X';
    closeButton.title = '关闭预览';
    closeButton.className = 'canvasCloseButton';
    document.body.appendChild(closeButton);

    closeButton.addEventListener('click', function () {
      imageUrl = '';
      canvas.style.display = 'none';
      document.body.removeChild(closeButton);
    });
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.save();
      ctx.translate(originX, originY);
      ctx.scale(scale, scale);

      if (annotations.length) {
        ctx.drawImage(image, 0, 0);
      } else {
        // 获取 canvas 的宽度和高度
        const canvasWidth = canvas.width;
        const canvasHeight = canvas.height;
        // 获取图片的宽度和高度
        const imageWidth = image.width;
        const imageHeight = image.height;
        // 计算图片在画布上的位置
        const x = (canvasWidth - imageWidth) / 2;
        const y = (canvasHeight - imageHeight) / 2;
        ctx.drawImage(image, x, y);
        initState = false;
      }
      if (annotations.length) {
        annotations.forEach((item) => {
          if (item.range) {
            ctx.lineWidth = 10;
            ctx.beginPath();
            ctx.strokeStyle = 'red';
            ctx.strokeRect(
              item.range.x - 10,
              item.range.y - 10,
              item.range.width + 20,
              item.range.height + 20
            );
          }
          ctx.fillStyle = 'yellow';
          ctx.font = '100px fangsong';
          ctx.fillText(item.text, item.posX, item.posY - 50);
          ctx.fill();
          if (item.rect) {
            ctx.lineWidth = 10;
            ctx.beginPath();
            ctx.strokeStyle = 'yellow';
            ctx.strokeRect(
              item.rect.x - 5,
              item.rect.y - 5,
              item.rect.width + 10,
              item.rect.height + 10
            );
          }
          if (initState) {
            scale = canvas.height / image.height;
            originX = (canvas.width - image.width * scale) / 2;
            initState = false;
            draw();
          }
        });
        ctx.restore();
      }
      ctx.restore();
    }
    image.src = imageUrl;
    image.onload = resizeCanvas;
    window.addEventListener('resize', resizeCanvas);
    ['mousedown', 'mouseup', 'mouseout', 'mousemove', 'wheel'].forEach(eventName => {
      canvas.addEventListener(eventName, (e) => {
        switch (eventName) {
          case 'mousedown':
            isDragging = true;
            lastX = e.offsetX - originX;
            lastY = e.offsetY - originY;
            break;
          case 'mouseup':
          case 'mouseout':
            isDragging = false;
            break;
          case 'mousemove':
            if (isDragging) {
              originX = e.offsetX - lastX;
              originY = e.offsetY - lastY;
              draw();
            }
            break;
          case 'wheel':
            e.preventDefault();
            var mouseX = e.offsetX;
            var mouseY = e.offsetY;
            var wheel = e.deltaY < 0 ? 1.1 : 0.9;
            var newScale = scale * wheel;
            draw();
            if (newScale < 0.1 || newScale > 5) return;
            var newOriginX = mouseX - (mouseX - originX) * wheel;
            var newOriginY = mouseY - (mouseY - originY) * wheel;
            scale = newScale;
            originX = newOriginX;
            originY = newOriginY;

            break;
        }
      });
    });

    // 监听键盘事件
    window.addEventListener('keydown', (e) => {
      if (e.keyCode === 27) { // 检测到 esc 键被按下
        imageUrl = '';
        canvas.style.display = 'none';
        document.body.removeChild(closeButton);
      }
    });
  };