热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Vue多点触控手势:移动端多指操作详解

在移动端开发中,多点触控手势是提升用户体验的重要手段。然而,目前只有iOS浏览器原生支持手势事件,其他设备需要通过touchstart、touchmove和touchend等基础事件进行自定义实现。本文将详细介绍如何在Vue项目中实现多点触控手势。

在移动端开发中,多点触控手势是提升用户体验的关键。然而,目前只有iOS浏览器原生支持手势事件,其他设备需要通过touchstart、touchmove和touchend等基础事件进行自定义实现。本文将详细介绍如何在Vue项目中实现多点触控手势。

基础触摸事件

移动端的基础触摸事件包括:

  • touchstart:触摸开始
  • touchmove:触摸移动
  • touchend:触摸结束
  • touchcancel:触摸中断(如弹框打断)

示例代码:

box.addEventListener('touchmove', function(event) {
  console.log('触摸移动');
});

touchEvent 对象

touchEvent 对象包含以下属性:

  • touches:触发事件时屏幕上的触点个数
  • targetTouches:触发事件时事件元素上的触点个数
  • changedTouches:触发事件发生改变的触点个数
  • target:事件元素
  • stopPropagation():阻止事件冒泡
  • preventDefault():阻止默认行为

示例代码:

box.addEventListener('touchstart', function(event) {
  console.log(event.touches); // 一个手指触摸时输出 Touchlist{0: Touch, length: 1}
  var startX = event.touches[0].clientX; // 触点在视口上的位置
});

手势事件

iOS 的手势事件包括:

  • gesturestart:手势开始,屏幕上有两个或两个以上的手指
  • gesturechange:手势变化,屏幕上有两个或两个以上的手指位置在移动
  • gestureend:手势结束,屏幕上只剩下少于两个手指

新增的属性包括:

  • scale:触点的距离与初始距离的比例
  • rotation:触点的角度差与初始角度差的差

示例代码:

box.addEventListener('gesturechange', function(event) {
  box.innerHTML = 'rotation: ' + event.rotation + '
'; box.innerHTML += 'scale: ' + event.scale + '
'; });

自定义多点触控手势

为了在非iOS设备上实现多点触控手势,我们可以封装一个手势插件。以下是gestrue.js的实现:

(function(w) {
  /**
   * 用于给元素监听手势事件
   * @param node 要监听的元素
   * @param callback 对象,对象有三个函数 start、change、end
   */
  function gesture(node, callback) {
    // 手势开始
    node.addEventListener('touchstart', function(event) {
      if (event.touches.length >= 2) {
        node.isGestureStart = true;
        this.startDst = getDst(event.touches[0], event.touches[1]);
        this.startDeg = getDeg(event.touches[0], event.touches[1]);
        if (callback && typeof(callback['start']) === 'function') {
          callback['start']();
        }
      }
    });

    // 手势移动
    node.addEventListener('touchmove', function(event) {
      if (event.touches.length >= 2) {
        var currentDst = getDst(event.touches[0], event.touches[1]);
        var currentDeg = getDeg(event.touches[0], event.touches[1]);
        event.scale = currentDst / this.startDst;
        event.rotation = currentDeg - this.startDeg;
        if (callback && typeof(callback['change']) === 'function') {
          callback['change'](event);
        }
      }
    });

    // 手势结束
    node.addEventListener('touchend', function(event) {
      if (node.isGestureStart && event.touches.length <2) {
        node.isGestureStart = false;
        if (callback && typeof(callback['end']) === 'function') {
          callback['end']();
        }
      }
    });

    function getDst(touch1, touch2) {
      var x = touch2.clientX - touch1.clientX;
      var y = touch2.clientY - touch1.clientY;
      var z = Math.sqrt(x * x + y * y);
      return z;
    }

    function getDeg(touch1, touch2) {
      var x = touch2.clientX - touch1.clientX;
      var y = touch2.clientY - touch1.clientY;
      var angle = Math.atan2(y, x);
      var deg = angle / Math.PI * 180;
      return deg;
    }
  }

  w.gesture = gesture;
})(window);

使用案例:实现元素缩放及旋转

以下是一个简单的示例,展示如何使用上述手势插件实现元素的缩放和旋转。

* {
  margin: 0;
  padding: 0;
}
html, body, #app {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#box {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 150px;
  height: 150px;
  background-color: #f90;
}
(function() {
  var app = document.querySelector('#app');
  var box = document.querySelector('#box');

  app.addEventListener('touchstart', function(event) {
    event.preventDefault();
  });

  gesture(box, {
    start: function() {
      box.startScale = transformCss(box, 'scale') || 1;
      box.startRotate = transformCss(box, 'rotate') || 0;
    },
    change: function(event) {
      transformCss(box, 'scale', box.startScale * event.scale);
      transformCss(box, 'rotate', box.startRotate + event.rotation);
    }
  });
})();

注:本文中的transformCss函数用于设置CSS变换属性,具体实现请参考相关文档。

作者:捕猹少年闰土

若有任何问题或建议,请联系我,共同学习进步。


推荐阅读
  • 在使用Eclipse进行调试时,如果遇到未解析的断点(unresolved breakpoint)并显示“未加载符号表,请使用‘file’命令加载目标文件以进行调试”的错误提示,这通常是因为调试器未能正确加载符号表。解决此问题的方法是通过GDB的`file`命令手动加载目标文件,以便调试器能够识别和解析断点。具体操作为在GDB命令行中输入 `(gdb) file `。这一步骤确保了调试环境能够正确访问和解析程序中的符号信息,从而实现有效的调试。 ... [详细]
  • Python学习day3网络基础之网络协议篇
    一、互联网协议连接两台计算机之间的Internet实际上就是一系列统一的标准,这些标准称之为互联网协议,互联网的本质就是一系列网络协议。二、为什么要有互联网协议互联网协议就相当于计 ... [详细]
  • 本文介绍了如何使用线段树实现区间加法和区间查询操作,包括详细的代码实现和解释。 ... [详细]
  • 使用 Mui.js 获取复选框值的方法
    本文介绍如何使用 Mui.js 框架来获取复选框的值,并通过数组进行处理和展示。 ... [详细]
  • 说明Python教程正在编写中,欢迎大家加微信sinbam提供意见、建议、纠错、催更。drymail是一个邮件发送库,封装了Python的smtplib ... [详细]
  • 线段树,注 ... [详细]
  • iOS snow animation
    CTSnowAnimationView.hCTMyCtripCreatedbyalexon1614.Copyright©2016年ctrip.Allrightsreserved.# ... [详细]
  • 如何解决TS1219:实验性装饰器功能可能在未来版本中更改的问题
    本文介绍了两种方法来解决TS1219错误:通过VSCode设置启用实验性装饰器,或在项目根目录下创建配置文件(jsconfig.json或tsconfig.json)。 ... [详细]
  • packagecom.panchan.tsmese.utils;importjava.lang.reflect.ParameterizedType;importjava.lang. ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • PHP 5.5.31 和 PHP 5.6.17 安全更新发布
    PHP 5.5.31 和 PHP 5.6.17 已正式发布,主要包含多个安全修复。强烈建议所有用户尽快升级至最新版本以确保系统安全。 ... [详细]
  • 自定义滚动条美化页面内容
    当页面内容超出显示范围时,为了提升用户体验和页面美观,通常会添加滚动条。如果默认的浏览器滚动条无法满足设计需求,我们可以自定义一个符合要求的滚动条。本文将详细介绍自定义滚动条的实现过程。 ... [详细]
  • 本文介绍了 Oracle SQL 中的集合运算、子查询、数据处理、表的创建与管理等内容。包括查询部门号为10和20的员工信息、使用集合运算、子查询的注意事项、数据插入与删除、表的创建与修改等。 ... [详细]
  • Gty的二逼妹子序列 - 分块与莫队算法的应用
    Autumn 和 Bakser 正在研究 Gty 的妹子序列,但遇到了一个难题。他们希望计算某个区间内美丽度属于 [a, b] 的妹子的美丽度种类数。本文将详细介绍如何利用分块和莫队算法解决这一问题。 ... [详细]
  • 使用jqTransform插件美化表单
    jqTransform 是由 DFC Engineering 开发的一款 jQuery 插件,专用于美化表单元素,操作简便,能够美化包括输入框、单选按钮、多行文本域、下拉选择框和复选框在内的所有表单元素。 ... [详细]
author-avatar
月星名店_882
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有