前言
随着智能手机、平板电脑等触控设备的普及,交互方式也发生了改变。相对于使用鼠标和键盘进行交互的电脑,触控设备可以直接使用手指进行交互,而且基本上都支持多点触控。多点触控最常见的操作莫过于双指缩放了。比如双指缩放网页大小、朋友圈双指缩放图片进行查看。那么如此常见的手势操作,你有没有想过它是如何实现的呢?下面跟着我一探究竟吧!

缩放原理
原理其实很简单,双指向外扩张表示放大,向内收缩表示缩小,缩放比例是通过计算双指当前的距离 / 双指上一次的距离获得的。详见下图:

计算出缩放比例后再通过下面两种方式实现缩放。

通过transform进行缩放
通过修改宽高来实现缩放

主流的方法都是采用transform来实现,因为性能更好。本篇文章两种方式都会介绍,任你选择。不过在讲之前,还是要先搞懂两个数学公式以及​ ​PointerEvent​​指针事件。因为接下来会用到。如果对PointerEvent指针事件不太熟悉的小伙伴,也可以看看这篇文章​ ​js PointerEvent指针事件简单介绍​​。

两点间距离公式
设两个点A、B以及坐标分别为A(x1, y1)、B(x2, y2),则A和B两点之间的距离为:

/**
* 获取两点间距离
* @param {object} a 第一个点坐标
* @param {object} b 第二个点坐标
* @returns
*/
function getDistance(a, b) {
const x = a.x - b.x;
const y = a.y - b.y;
return Math.hypot(x, y); // Math.sqrt(x * x + y * y);
}
中点坐标公式
设两个点A、B以及坐标分别为A(x1, y1)、B(x2, y2),则A和B两点的中点P的坐标为:

/**
* 获取中点坐标
* @param {object} a 第一个点坐标
* @param {object} b 第二个点坐标
* @returns
*/
function getCenter(a, b) {
const x = (a.x + b.x) / 2;
const y = (a.y + b.y) / 2;
return { x: x, y: y };
}

获取图片缩放尺寸
<img id="image" alt="">
const image = document.getElementById('image');
let result, // 图片缩放宽高
x, // x轴偏移量
y, // y轴偏移量
scale = 1, // 缩放比例
maxScale,
minScale = 0.5;
// 由于图片是异步加载,需要在load方法里获取naturalWidth,naturalHeight
image.addEventListener('load', function () {
result = getImgSize(image.naturalWidth, image.naturalHeight, window.innerWidth, window.innerHeight);
maxScale = Math.max(Math.round(image.naturalWidth / result.width), 3);
// 图片宽高
image.style.width = result.width + 'px';
image.style.height = result.height + 'px';
// 垂直水平居中显示
x = (window.innerWidth - result.width) * 0.5;
y = (window.innerHeight - result.height) * 0.5;
image.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(1)';
});
// 图片赋值需放在load回调之后,因为图片缓存后读取很快,有可能不执行load回调
image.src='../images/xxx.jpg';
/**
* 获取图片缩放尺寸
* @param {number} naturalWidth
* @param {number} naturalHeight
* @param {number} maxWidth
* @param {number} maxHeight
* @returns
*/
function getImgSize(naturalWidth, naturalHeight, maxWidth, maxHeight) {
const imgRatio = naturalWidth / naturalHeight;
const maxRatio = maxWidth / maxHeight;
let width, height;
// 如果图片实际宽高比例 >= 显示宽高比例
if (imgRatio >= maxRatio) {
if (naturalWidth > maxWidth) {
width = maxWidth;
height = maxWidth / naturalWidth * naturalHeight;
} else {
width = naturalWidth;
height = naturalHeight;
}
} else {
if (naturalHeight > maxHeight) {
width = maxHeight / naturalHeight * naturalWidth;
height = maxHeight;
} else {
width = naturalWidth;
height = naturalHeight;
}
}
return { width: width, height: height }
}

js 实现双指缩放的更多相关文章

  1. js实现双指缩放图片 手机端双指缩放图片

    首先引入js文件,需要jq,pinchzoom.js.pinchzoom.js需要在jq环境下使用,可以 <meta name="viewport" content=&quo ...

  2. 微信小程序movable-view移动图片和双指缩放

    先从movable-view开始说起吧. movable-view是小程序自定义的组件.其描述为:"可移动的视图容器,在页面中可以拖拽滑动". 官方文档地址:https://mp. ...

  3. 解决ios10及以上Safari双击和双指缩放无法禁止的问题

    移动端web缩放有两种: 1.双击缩放: 2.双指手势缩放. 在iOS 10以前,iOS和Android都可以通过一行meta标签来禁止页面缩放 <meta content="widt ...

  4. 在viewPager中双指缩放图片,双击缩放图片,单指拖拽图片

    我们就把这个问题叫做图片查看器吧,它的主要功能有: (项目地址:https://github.com/TZHANHONG/ImageViewer/releases/tag/1.0,里面的MyImage ...

  5. 用开源项目PhotoView实现图片的双指缩放和双击放大缩小

    项目地址:https://github.com/chrisbanes/PhotoView 用开源项目有个好处,一是实现简单,二是bug少.那么我们就来说下这个项目能够实现的效果: 1.单个图片的双指缩 ...

  6. ios移动端禁止双指缩放功能

    在实际开发中,我们禁止缩放的实现方式: 1.meta设置: <meta name="viewport"  content="width=device-width,h ...

  7. JS等比例缩放图片,限定最大宽度和最大高度

    JS等比例缩放图片,限定最大宽度和最大高度 JavaScript //图片按比例缩放 var flag=false; function DrawImage(ImgD,iwidth,iheight){ ...

  8. JS控制SVG缩放+鼠标控制事件

    话不多说,直接上代码吧,不行你砍我... <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  9. js控制图片缩放、水平和垂直方向居中对齐

    已測试兼容 IE6,IE7,IE8,火狐FF,谷歌chrome. 这里使用了jquery插件,假设你不使用jquery,略微改造一下也非常快. 网上查了些资料,用css控制兼容性不好,看去非常揪心.于 ...

  10. js 元素大小缩放实例

    元素大小缩放是一套连贯事件,按下鼠标不放,拖动鼠标 然后松开. 按下鼠标事件 当按下鼠标时,记录元素大小.鼠标按下的位置.状态位. 拖动鼠标事件 当鼠标拖动时,计算元素调用后的大小. 元素调整后大小 ...

随机推荐

  1. react中css里面 class中的 图片的相对地址 完美解决 backgroundImage

    发现问题:缓存 之前react的图片,也在style里面,也无所谓. 刚做了一个输入框,change的时候改变图片,每次都刷新图片,关键是没缓存,这哪受得了 之前用的: 网上搜索各种插件,替换什么的, ...

  2. ts-对象数组reduce-数组转对象数组

    将字符串数组转化成{name:xxx,count:xxx}[]数组的代码 #定义数据类型 interface CartInfo{ name:string, count:number } let raw ...

  3. 爬虫实战:探索XPath爬虫技巧之热榜新闻

    之前我们已经详细讨论了如何使用BeautifulSoup这个强大的工具来解析HTML页面,另外还介绍了利用在线工具来抓取HTTP请求以获取数据的方法.在今天的学习中,我们将继续探讨另一种常见的网络爬虫 ...

  4. openlayers操作分享:如何从容的在vue中食用openlayers6

    这篇文章,分享下我对openlayers的一些经验和理解,会夹杂大量搜索出来得文档,是我正式使用时可以实现的,废话不多说,我们从下载开始 一,openlayers安装且初始化地图 创建vue项目就省略 ...

  5. TP6框架--EasyAdmin学习笔记:项目上线

    这是我暂时写EasyAdmin的最后一章,给大家分享下项目上线的全过程,希望对大家有所帮助,废话不多说,直接上内容 服务器我选用的是阿里云,上线时我使用的是宝塔面板来进行部署,如果你是新手,并不熟练服 ...

  6. 记录--开发uniapp nvue App+微信小程序,我踩过的坑( 纯干货 )

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近接了个项目,采用uniapp的nvue开发安卓和ios端+小程序端,第一次开发nvue,对于css布局这块,还是踩了很多坑.以及一些u ...

  7. docker相关命令杂理

    - 2020.11.16docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] #保存现有的镜像 # docker commit -a "r ...

  8. [Git]入门及其常用命令

    [版权声明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/17993832 出自[进步*于辰的博客] Git 的难点 ...

  9. 使用systemd部署r-nacos

    1. 前言 r-nacos是一个用rust实现的nacos服务.相较于java nacos来说,是一个提供相同功能,启动更快.占用系统资源更小(初始内存小于10M).性能更高.运行更稳定的服务. r- ...

  10. Zookeeper学习笔记-安装

    zookeeper官网地址https://zookeeper.apache.org/ 1.卸载CentOS自带的open jdk,安装oracle jdk(1.8) 2.时间同步 #安装ntpdate ...