【前端】原生实现图片的放大与缩放

news/2024/8/26 13:46:24 标签: 前端

需求

点击图片,出现一个蒙版和图片,双指捏合可以使图片放大或缩小。

使用前端框架是svelte,但是不影响,功能都是JS实现。

代码

相关定义:

  import { onMount, afterUpdate, onDestroy } from 'svelte';
  
  let imgDetailRef;
  let initialDistance = 0;
  let initialScale = 1;
  let currentScale = 1;

定义监听事件触发的方法:

scale(${currentScale})是缩放相关的样式。

  const getDistanceBetweenTouches = (ev) => {
    let [touch1, touch2] = ev.touches;
    return Math.sqrt(
      Math.pow(touch1.pageX - touch2.pageX, 2) +
        Math.pow(touch1.pageY - touch2.pageY, 2),
    );
  };
  
  const touchStartHandler = function (ev) {
    if (ev.touches.length === 2) {
      initialDistance = getDistanceBetweenTouches(ev);
      initialScale = currentScale;
    }
  };

  const touchMoveHandler = function (ev) {
    // 防止出现Infinity 
    if (ev.touches.length === 2 && initialDistance !== 0) {
      let distance = getDistanceBetweenTouches(ev);
      if (distance !== initialDistance) {
        currentScale = (initialScale * distance) / initialDistance;
        // 最多只能缩小到原本大小
        if (currentScale < 1) currentScale = 1;
        imgDetailRef.style.transform = `translate(-50%, -50%) scale(${currentScale})`;
      }
    }
  };

  const touchEndHandler = function (ev) {
    initialDistance = 0;
    initialScale = currentScale;
  };

在生命周期中定义事件监听与销毁:

定义在afterUpdate中:我们点击图片会显示一个蒙版,图片显示在蒙版上,允许放大和缩小。因此,点击图片时才渲染这个蒙版,imgDetailRef对应的div是条件渲染,若在onMount中定义此事件的监听,此时可能不存在imgDetailRef

若存在imgDetailRef,要先把之前定义的监听移除(removeEventListener),否则会不断地触发监听事件,表示为:当手指捏合操作图片的放大和缩小时,图片的变化显得很卡,且控制台输出一堆信息(console.log写在touchMoveHandler)中。

  afterUpdate(() => {
    if (imgDetailRef) {
      imgDetailRef.removeEventListener('touchstart', touchStartHandler, false);
      imgDetailRef.removeEventListener('touchmove', touchMoveHandler, false);
      imgDetailRef.removeEventListener('touchend', touchEndHandler, false);

      imgDetailRef.addEventListener('touchstart', touchStartHandler, false);
      imgDetailRef.addEventListener('touchmove', touchMoveHandler, false);
      imgDetailRef.addEventListener('touchend', touchEndHandler, false);
    }
  });
  onDestroy(() => {
    if (imgDetailRef) {
      imgDetailRef.removeEventListener('touchstart', touchStartHandler, false);
      imgDetailRef.removeEventListener('touchmove', touchMoveHandler, false);
      imgDetailRef.removeEventListener('touchend', touchEndHandler, false);
    }
  });

至于蒙版和图片:点击图片时showImageDetail=true等,简单逻辑不赘述。

{:else if showImageDetail}
 <div>
   <img
     class="img-detail"
     id="img-detail"
     bind:this={imgDetailRef}
     src={selectedImage}
     alt="selectedImage"
   />
 </div>
{/if}

如果想在蒙层出现时不允许蒙层下的内容滚动:给不想滚动的类加上此样式(会回到页面顶部)

.no-scroll {
    position: fixed;
    width: 100%;
  }

或让bodyoverflow:hidden


http://www.niftyadmin.cn/n/5558234.html

相关文章

kubernetes k8s 控制器 Replicaset 配置管理

目录 1、Replicaset控制器&#xff1a;概念、原理解读 1.1 Replicaset概述 1.2 Replicaset工作原理&#xff1a;如何管理Pod&#xff1f; 2、 Replicaset资源清单文件编写技巧 3、Replicaset使用案例&#xff1a;部署Guestbook留言板 4、Replicaset管理pod&#xff1a;扩…

Ubuntu 22.04.4 LTS (linux) 安装iftop 监控网卡流量 软件

1 安装iftop sudo apt update sudo apt-get install iftop 2 监控网卡 sudo iftop -i eth0 -n -p 界面最上面&#xff0c;显示的是类似刻度尺的刻度范围&#xff0c;显示流量图形的长条作标尺用的。 中间的< >这两个左右箭头&#xff0c;表示的是流量的进出方向.TX&…

K8S私有云裸金属服务器负载均衡器OpenELB——筑梦之路

OpenELB介绍 OpenELB 是一个专为裸机 Kubernetes 集群设计的开源负载均衡器实现。 在云服务环境中的 Kubernetes 集群里&#xff0c;通常可以用云服务提供商提供的负载均衡服务来暴露 Service&#xff0c;但是在本地没办法这样操作。而 OpenELB 可以让用户在裸金属服务器、边缘…

【PyTorch快速入门教程】02 Jupyter notebook安装及配置

文章目录 1 安装 Jupyter notebook2 安装 ipykernel3 更改 jupyter 默认配置3.1 生成配置文件3.2 关键配置信息 4 扩展插件推荐参考 1 安装 Jupyter notebook 一行命令搞定 python -m pip install jupyter 现在就可以打开Jupyter notebook来运行python啦。 jupyter notebook…

深度刨析程序中的指针

前面我们已经学习过了指针的一下性质&#xff1a; 指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识的一块内存空间指针的大小是固定的4/8个字节&#xff08;32位平台/64位平台&#xff09;指针是有类型&#xff0c;指针的类型决定了指针的加减整数的步长&…

彻底改变时尚:使用 GAN 实现 AI 的未来

彻底改变时尚&#xff1a;使用 GAN 实现 AI 的未来 一、介绍 想象一下&#xff0c;在这个世界里&#xff0c;时装设计师永远不会用完新想法&#xff0c;我们穿的每一件衣服都是一件艺术品。听起来很有趣&#xff0c;对吧&#xff1f;好吧&#xff0c;我们可以在通用对抗网络 &a…

MySQL零散拾遗(二)

列的别名只能在 ORDER BY 中使用&#xff0c;不能在 WHERE 中使用 举个栗子&#xff0c;有一个员工表employees 显示出表 employees 的 员工id&#xff0c;员工的月薪还有年薪&#xff0c;并按年薪进行升序排序。 SELECT employee_id, salary, salary * 12 annual_sal FROM …

Linux内核编译安装 - Deepin,Debian系

为什么要自己编译内核 优点 定制化&#xff1a;你可以根据自己的硬件和需求配置内核&#xff0c;去掉不必要的模块&#xff0c;优化性能。性能优化&#xff1a;移除不需要的驱动程序和特性&#xff0c;减小内核体积&#xff0c;提高系统性能。最新特性和修复&#xff1a;获取…