移动端双指缩放图片JS事件的实践心得

摘要:
只有当两个手指同时触摸屏幕时,才能识别为触摸启动事件中的两个手指操作。因此,需要在触摸移动事件中执行双指事件的判断。如下图所示:示例演示假设页面上有一个图片元素。要实现此图片的双指缩放预览效果:您可以尝试使用下面显示的js代码:vareleImg=document.querySelector;varstore={scale:1};//缩放事件处理eleImg.addEventListener;document.addEventListener('touchmove',函数(事件){if(!

一、Chrome浏览器双指触摸的模拟

结果是模拟不了。

页面整体缩放行为是可以通过按住Shift键+页面左键模拟的,但是,实际上,还是一个触摸点,因此无法模拟双指缩放行为。

除非是有触摸板,或者屏幕就是触摸屏。

否则,只能连手机进行调试了。

二、触摸屏与event.touches

在触屏设备下,要判断是单指还是多指操作,可以通过 event.touches 数组对象的长度判断。

例如:

document.addEventListener('touchstart', function (event) {
    var touches = event.touches;
    if (touches.length == 1) {
        console.log('单指');
    } else if (touches.length >= 2) {
        console.log('多指');
    }
});

按照我们的理解,上面的逻辑应该是无懈可击的。

实际上并不是。

我一开始也是在 'touchstart' 事件中判断是单指还是双指,结果发现了奇怪的现象,有时候是单指,有时候是双指,双指复现的概率可能不到1成。

这可真是奇怪了。

后来一番测试,终于弄清楚原因了。

只有当两个指头同时触摸屏幕的时候,才能在touchstart事件中被识别为双指操作。

这太难了,没有谁的两个指头是一样长的,很难同一时间戳中屏幕的。

因此,双指事件的判断需要在 touchmove 事件中才行。

三、双指行为的判断

代码如下:

document.addEventListener('touchmove', function (event) {
    if (event.touches && event.touches.length == 2) {
        console.log('双指在移动');
    }
});
 

四、双指缩放功能的实现

双指缩放功能的实现的难点就是缩放比例的计算。

event.touches 中的每一项都是触摸点对象,包含了触碰的元素以及触摸点的坐标。

其中,触摸点的坐标就可以用来计算缩放比例。

我们记录下第一次双指行为发生时候的两个手指点的坐标值,于是就可以计算出这两个指头之间的距离;

然后继续 touchmove 的时候,实时计算出新的两个手指的坐标距离。

一开始的距离/现在的距离 = 应该缩放的比例。

如下图所示:

移动端双指缩放图片JS事件的实践心得第1张

实例演示

假设页面上有一张图片元素,要实现这种图片的双指缩放预览效果:

<img id="image" src="1.png">

则可以试试使用下面所示的js代码:

var eleImg = document.querySelector('#image');
var store = {
    scale: 1
};
// 缩放事件的处理
eleImg.addEventListener('touchstart', function (event) {
    var touches = event.touches;
    var events = touches[0];
    var events2 = touches[1];

    event.preventDefault();

    // 第一个触摸点的坐标
    store.pageX = events.pageX;
    store.pageY = events.pageY;

    store.moveable = true;

    if (events2) {
        store.pageX2 = events2.pageX;
        store.pageY2 = events2.pageY;
    }

    store.originScale = store.scale || 1;
});
document.addEventListener('touchmove', function (event) {
    if (!store.moveable) {
        return;
    }

    event.preventDefault();

    var touches = event.touches;
    var events = touches[0];
    var events2 = touches[1];
    // 双指移动
    if (events2) {
        // 第2个指头坐标在touchmove时候获取
        if (!store.pageX2) {
            store.pageX2 = events2.pageX;
        }
        if (!store.pageY2) {
            store.pageY2 = events2.pageY;
        }

        // 获取坐标之间的举例
        var getDistance = function (start, stop) {
            return Math.hypot(stop.x - start.x, stop.y - start.y);
        };
        // 双指缩放比例计算
        var zoom = getDistance({
            x: events.pageX,
            y: events.pageY
        }, {
            x: events2.pageX,
            y: events2.pageY
        }) /
        getDistance({
            x: store.pageX,
            y: store.pageY
        }, {
            x: store.pageX2,
            y: store.pageY2
        });
        // 应用在元素上的缩放比例
        var newScale = store.originScale * zoom;
        // 最大缩放比例限制
        if (newScale > 3) {
            newScale = 3;
        }
        // 记住使用的缩放值
        store.scale = newScale;
        // 图像应用缩放效果
        eleImg.style.transform = 'scale('+ newScale +')';
    }
});

document.addEventListener('touchend', function () {
    store.moveable = false;

    delete store.pageX2;
    delete store.pageY2;
});
document.addEventListener('touchcancel', function () {
    store.moveable = false;

    delete store.pageX2;
    delete store.pageY2;
});

大家可以访问这个地址(如果手机访问本文): https://www.zhangxinxu.com/study/202006/resize.html

双指缩放效果就可以体验了,最大比例做了限制,最小比例没有做限制。

广州vi设计公司 http://www.maiqicn.com我的007办公资源网 https://www.wode007.com

五、结语以及其他

demo页面的 touchmove 没有设置 passive:false 也没有报错,是因为 html 标签设置了如下css:

html { touch-action: none; }

如果有兴趣了解背后原理,可以访问这篇文章: touch-action简介与treated as passive错误解决

本文是自己实际工作实践中的一点手机中双指缩放图片的经验分享,考虑到自己以后遇到类似需求可能还会用到,所以记录下,希望可以帮到有类似需求的小伙伴。

免责声明:文章转载自《移动端双指缩放图片JS事件的实践心得》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇经验分享:给软件测试人员15个最好的测试管理工具MacOS command+tab 无法打开最小化应用的烦恼下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Qt 自定义事件

Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展。在 Qt 中,你需要继承的类是 QEvent。 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定义事件的类型值。这里的QEvent::Type类型是QEvent里面定义的一个enum,因此,你是可以传递一个int的。重要的是,你的事件类型不能和已经存在的...

div拖拽, onmousedown ,onmousemove, onmouseup

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <style type="text/css"> 7...

Web Worker javascript多线程编程(一)

什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验。 一般来说Javascript和UI页面会共用一个线程,在HTML页面中执行js脚本时,页面的状态是不可响应的,直到脚本已完成。而这段代码可以交给Web Worker在后台运行,那么页面在...

移动设备上的触摸事件

在 iOS 的 Safari 浏览器中,增加了一些触摸(touch)事件和手势(gesture)事件,这里总结一下它们的用法。 一、触摸事件 iOS 浏览器的触摸事件包括 touchstart,touchmove,touchend,touchcancel。Android 的浏览器中也同样支持这些事件。这些触摸事件的触发条件如下: touchstart:手...

火狐浏览器(firefox)中js要注意的问题

1.出现错误调用error方法或者ajax请求了多次,那么极有可能是异步请求的原因。 添加async : false , ->async. 默认是 true,即为异步方式,$.ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发$.ajax里的success方法,这时候执行的是两个线程。 -> async 设置为 fals...

实战:一种在http请求中使用protobuffer+nginx+lua收集打点日志的方案

背景 app打点日志的上报和收集,是互联网公司的基本需求。 一.方案选择 1.1 protobuffer vs json 探究一种以最高效的方式上报和解析打点数据是一个系统性的问题,需要解决的子问题有很多,例如降低网络传输成本,减少序列化反序列化的性能开销,可靠性和高峰期的水平扩展,以及非耦合的编码等等。 很多公司的打点日志会采用比较简单通用的json格式...