Shun 发表于 2021-12-21 22:17:50

js 实现双指缩放

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

缩放原理
原理其实很简单,双指向外扩张表示放大,向内收缩表示缩小,缩放比例是通过计算双指当前的距离 / 双指上一次的距离获得的。详见下图:
https://s7.51cto.com/images/blog/202112/21152249_61c180c99388e36013.webp
计算出缩放比例后再通过下面两种方式实现缩放。


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

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

两点间距离公式
设两个点A、B以及坐标分别为A(x1, y1)、B(x2, y2),则A和B两点之间的距离为:
https://s9.51cto.com/images/blog/202112/21152249_61c180c9a1c5990254.webp
/**
* 获取两点间距离
* @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的坐标为:
https://s3.51cto.com/images/blog/202112/21152249_61c180c99677694468.webp
/**
* 获取中点坐标
* @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 }
}






https://blog.51cto.com/u_15465492/4828702
页: [1]
查看完整版本: js 实现双指缩放