js 实现双指缩放
前言
随着智能手机、平板电脑等触控设备的普及,交互方式也发生了改变。相对于使用鼠标和键盘进行交互的电脑,触控设备可以直接使用手指进行交互,而且基本上都支持多点触控。多点触控最常见的操作莫过于双指缩放了。比如双指缩放网页大小、朋友圈双指缩放图片进行查看。那么如此常见的手势操作,你有没有想过它是如何实现的呢?下面跟着我一探究竟吧!
缩放原理
原理其实很简单,双指向外扩张表示放大,向内收缩表示缩小,缩放比例是通过计算双指当前的距离 / 双指上一次的距离获得的。详见下图:
计算出缩放比例后再通过下面两种方式实现缩放。
通过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 实现双指缩放的更多相关文章
- js实现双指缩放图片 手机端双指缩放图片
		
首先引入js文件,需要jq,pinchzoom.js.pinchzoom.js需要在jq环境下使用,可以 <meta name="viewport" content=&quo ...
 - 微信小程序movable-view移动图片和双指缩放
		
先从movable-view开始说起吧. movable-view是小程序自定义的组件.其描述为:"可移动的视图容器,在页面中可以拖拽滑动". 官方文档地址:https://mp. ...
 - 解决ios10及以上Safari双击和双指缩放无法禁止的问题
		
移动端web缩放有两种: 1.双击缩放: 2.双指手势缩放. 在iOS 10以前,iOS和Android都可以通过一行meta标签来禁止页面缩放 <meta content="widt ...
 - 在viewPager中双指缩放图片,双击缩放图片,单指拖拽图片
		
我们就把这个问题叫做图片查看器吧,它的主要功能有: (项目地址:https://github.com/TZHANHONG/ImageViewer/releases/tag/1.0,里面的MyImage ...
 - 用开源项目PhotoView实现图片的双指缩放和双击放大缩小
		
项目地址:https://github.com/chrisbanes/PhotoView 用开源项目有个好处,一是实现简单,二是bug少.那么我们就来说下这个项目能够实现的效果: 1.单个图片的双指缩 ...
 - ios移动端禁止双指缩放功能
		
在实际开发中,我们禁止缩放的实现方式: 1.meta设置: <meta name="viewport" content="width=device-width,h ...
 - JS等比例缩放图片,限定最大宽度和最大高度
		
JS等比例缩放图片,限定最大宽度和最大高度 JavaScript //图片按比例缩放 var flag=false; function DrawImage(ImgD,iwidth,iheight){ ...
 - JS控制SVG缩放+鼠标控制事件
		
话不多说,直接上代码吧,不行你砍我... <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
 - js控制图片缩放、水平和垂直方向居中对齐
		
已測试兼容 IE6,IE7,IE8,火狐FF,谷歌chrome. 这里使用了jquery插件,假设你不使用jquery,略微改造一下也非常快. 网上查了些资料,用css控制兼容性不好,看去非常揪心.于 ...
 - js 元素大小缩放实例
		
元素大小缩放是一套连贯事件,按下鼠标不放,拖动鼠标 然后松开. 按下鼠标事件 当按下鼠标时,记录元素大小.鼠标按下的位置.状态位. 拖动鼠标事件 当鼠标拖动时,计算元素调用后的大小. 元素调整后大小 ...
 
随机推荐
- git 撤销本地 git提交的commit记录 (git reset --hard ID)
			
git 撤销本地 git提交的commit记录 (git reset --hard ID) ID的获取方法 这个id,就是你要退回的那个id,我这里截图的时候已经回退了,正常是你提错了的下面那个git ...
 - k8s如何对外访问service
			
在Kubernetes(K8s)中,可以通过以下几种方式对外访问Service: 1.NodePort: 这是最常见的对外访问Service的方式.通过将Service的类型设置为NodePort,K ...
 - offer收割机--js的隐式类型转换规则整理
			
类型转换 文中的值类型等价于所说的基础类型,其范围是(boolean,string,number) 转换为基础类型 布尔值 undefined, null, false, NaN,'', 0 --&g ...
 - lazy-nvim插件管理器基础入门
			
一篇通过使用lazy.nvim进行nvim插件管理的入门笔记. 基础安装 init.lua 路径:stdpath("config")/init.lua stdpath(" ...
 - 不要升级!不要升级!MacOS 14.4 引发Java 应用崩溃
			
如果最近您收到了MacOS 14.4的升级提醒,那么建议你暂时先不要升级! 在x上,Java开发领域的一些大v们,也发现了这个问题,并提醒大家不要升级. 根据Java官方发布的文章了解到,该问题主要是 ...
 - python高级技术(网络编程一)
			
一 socket是什么 链接socket前要熟悉计算机网络基础请看链接:https://www.cnblogs.com/coderxueshan/p/17344739.html Socket是应用层 ...
 - C# SM2 解密 对接兴业银行业务
			
下载地址
 - Java split 分割字符串避坑
			
使用split进行字符串分割时需要注意2点 1.特殊字符作为分隔符时需要使用\\进行转义(如\\ -> \\\\; | -> \\| ) 特殊字符 .$|()[{^?*+\\ 例如对&qu ...
 - shk_to_bram
			
Entity: shk_to_bram File: shk_to_bram.v Diagram Description Company: FpgaPublish Engineer: FP Create ...
 - 英语文档阅读学习系列之Zynq-7000 EPP Software Developers Guide
			
阅读ug821-zynq-7000-swdev记录 1.略看目录Table 依旧采用总说加解释的模式,这种方式易于查找,是可靠的框架.目录词条依次为: Introduction Software Ap ...