当前位置: 首页 > news >正文

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

需求

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

使用前端框架是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><imgclass="img-detail"id="img-detail"bind:this={imgDetailRef}src={selectedImage}alt="selectedImage"/></div>
{/if}

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

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

或让bodyoverflow:hidden

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 安全防御:双机热备
  • 19.x86游戏实战-创建MFC动态链接库
  • 基于 CNN(二维卷积Conv2D)+LSTM 实现股票多变量时间序列预测(PyTorch版)
  • vue3 tab切换函数回调刷新跳转页面
  • tensorflow keras Model.fit returning: ValueError: Unrecognized data type
  • WordPress外贸建站案例
  • 基于JAVA+SpringBoot+Vue+uniApp的校园日常作品商品分享小程序
  • 航班管理系统【C语言版】单文件编写
  • MPNN消息传递神经网络
  • IDEA的断点调试(Debug)
  • Ajax是什么?如何在HTML5中使用Ajax?
  • 分享一个 .NET EF 6 扩展 Where 的方法
  • ES6 字符串的新增方法(二十)
  • P4-AI产品经理-九五小庞
  • 云原生系列 - Jenkins
  • @jsonView过滤属性
  • ➹使用webpack配置多页面应用(MPA)
  • Apache的基本使用
  • canvas 五子棋游戏
  • co.js - 让异步代码同步化
  • CSS实用技巧干货
  • Java 内存分配及垃圾回收机制初探
  • java概述
  • mysql外键的使用
  • MySQL用户中的%到底包不包括localhost?
  • Python 反序列化安全问题(二)
  • React系列之 Redux 架构模式
  • Windows Containers 大冒险: 容器网络
  • 阿里云购买磁盘后挂载
  • 百度小程序遇到的问题
  • 多线程 start 和 run 方法到底有什么区别?
  • 聚簇索引和非聚簇索引
  • 力扣(LeetCode)56
  • 区块链分支循环
  • 我的zsh配置, 2019最新方案
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 阿里云ACE认证之理解CDN技术
  • 阿里云服务器购买完整流程
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • #70结构体案例1(导师,学生,成绩)
  • #java学习笔记(面向对象)----(未完结)
  • #在 README.md 中生成项目目录结构
  • (007)XHTML文档之标题——h1~h6
  • (C语言)字符分类函数
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (二)WCF的Binding模型
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (七)Knockout 创建自定义绑定
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (五十)第 7 章 图(有向图的十字链表存储)
  • (新)网络工程师考点串讲与真题详解
  • (转)jQuery 基础