• Hammer.js - 旋转 拖拽 移动 缩放


    感觉移动端原生支持的 touch、tap、swipe 几个事件好像还不够用,某些时候还会用到诸如缩放、长按等其他功能。

    学习了一个手势库 Hammer.js,它是一个轻量级的触屏设备手势库,能识别出常见的触摸、拖动、长按、缩放等行为。 

    目录

    一、hammer.js简介

    二、事件

    三、使用方式

    四、应用实例


    一、hammer.js简介

    hammerJS是一个开源的,轻量级的触屏设备javascript手势库,它可以在不需要依赖其他东西的情况下识别触摸,鼠标事件。允许同时监听多个手势、自定义识别器,也可以识别滑动方向。

    hammerJS很多姿势,比如旋转(Rotate)、捏合(Pinch)、按压(Press)、平移(Pan)、轻触(Tap)、滑动(Swipe)。

    二、事件

    1、Rotate事件:在指定的dom区域内,当两个手指或更多手指成圆型旋转时触发(就像两个手指拧螺丝一样)。该事件分别对以下事件进行监听并处理:

    Rotatestart:旋转开始;Rotatemove:旋转过程;Rotateend:旋转结束;Rotatecancel:旋转取消

    2、Pinch事件:在指定的dom区域内,两个手指(默认为两个手指,多指触控需要单独设置)或多个手指相对(越来越近)移动或相向(越来越远)移动时事件。该事件事以分别对以下事件进行监听并处理:

    Pinchstart:多点触控开始;Pinchmove:多点触控过程;Pinchend:多点触控结束;Pinchcancel:多点触控取消;Pinchin:多点触控时两手指距离越来越近;Pinchout:多点触控时两手指距离越来越远

    3、Press事件:在指定的dom区域内触屏版本的点击事件,这个事件相当于PC端的Click事件,该不能包含任何的移动,最小按压时间为500毫秒,常用于我们在手机上用的“复制、粘贴”等功能。该事件分别对以下事件进行监听并处理: 

    Pressup:点击事件离开时触发

    4、Pan事件:在指定的dom区域内,一个手指放下并移动事件,即触屏中的拖动事件。这个事件在屏触开发中比较常用,如:左拖动、右拖动等,如手要上使用QQ时向右滑动出现功能菜单的效果。该事件还可以分别对以下事件进行监听并处理:

    Panstart:拖动开始;Panmove:拖动过程;Panend:拖动结束;Pancancel:拖动取消;Panleft:向左拖动;Panright:向右拖动;Panup:向上拖动;Pandown:向下拖动 

    5、Tap事件:在指定的dom区域内,一个手指轻拍或点击时触发该事件(类似PC端的click)。该事件最大点击时间为250毫秒,如果超过250毫秒则按Press事件进行处理。

    6、Swipe事件:在指定的dom区域内,一个手指快速的在触屏上滑动。即我们平时用到最多的滑动事件。

    Swipeleft:向左滑动;Swiperight:向右滑动;Swipeup:向上滑动;Swipedown:向下滑动

    三、使用方式

    我非常乖巧,想翻我牌子的话特别简单,new一下即可。

    1. var hammertime = new Hammer(myElement, myOptions);
    2. hammertime.on('pan', function(ev) {
    3. console.log(ev);
    4. });

    当然也可以玩点更高级的,能同时为您解锁多种姿势

    1. // get a reference to an element
    2. var smartisan = document.getElementById('smartisan');
    3. // create a manager for that element
    4. var mc = new Hammer.Manager(smartisan);
    5. // create a recognizer
    6. var Rotate = new Hammer.Rotate();
    7. // add the recognizer
    8. mc.add(Rotate);
    9. // subscribe to events
    10. mc.on('rotate', function(e) {
    11. // do something cool
    12. var rotation = Math.round(e.rotation);
    13. stage.style.transform = 'rotate('+rotation+'deg)';
    14. });

    四、应用实例

     对图片进行拖动、缩放和旋转操作(用到hammerJS中的事件Pan、Pinch和Rotate

    1. html>
    2. <html>
    3. <head>
    4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    7. <meta name="format-detection" content="telephone=no">
    8. <title>Hammer.js-图片拖动、放缩、旋转title>
    9. <style>
    10. html, body {
    11. margin: 0;
    12. padding: 0;
    13. height: 100%;
    14. min-height: 100%;
    15. background: #eee;
    16. font: 13px/1.5em 'Open Sans', Helvetica, Arial, sans-serif;
    17. }
    18. a {
    19. color: #4986e7;
    20. }
    21. .bg1, .green { background: #42d692; }
    22. .bg2, .blue { background: #4986e7; }
    23. .bg3, .red { background: #d06b64; }
    24. .bg4, .purple { background: #cd74e6; }
    25. .bg5, .azure { background: #9fe1e7; }
    26. body {
    27. margin: 20px;
    28. }
    29. pre {
    30. background: #fff;
    31. padding: 20px;
    32. margin-bottom: 20px;
    33. }
    34. .container {
    35. max-width: 900px;
    36. margin: 0 auto;
    37. }
    38. .clear { clear: both; }
    39. body { -webkit-perspective: 500; -moz-perspective: 500; perspective: 500; }
    40. .animate { -webkit-transition: all .3s; -moz-transition: all .3s; transition: all .3s; }
    41. #hit { padding: 10px; }
    42. #imgid{width: 300px;}
    43. style>
    44. head>
    45. <body>
    46. <img id="imgid" class="animate" src="images/test2.jpg">
    47. <script type="text/javascript" src="js/hammer.min.js">script>
    48. <script>
    49. var reqAnimationFrame = (function () {
    50. return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) {
    51. window.setTimeout(callback, 1000 / 60);
    52. };
    53. })();
    54. var el = document.querySelector("#imgid");
    55. var START_X = Math.round((window.innerWidth - el.offsetWidth) / 2);
    56. var START_Y = Math.round((window.innerHeight - el.offsetHeight) / 2);
    57. var ticking = false;
    58. var transform; //图像效果
    59. var timer;
    60. var initAngle = 0; //旋转角度
    61. var initScale = 1; //放大倍数
    62. var mc = new Hammer.Manager(el); //用管理器 可以同时触发旋转 拖拽 移动
    63. //var mc = new Hammer(el); //旋转和移动互斥
    64. /**
    65. ev.srcEvent.type touchstart touchend touchmove
    66. ev.deltaX 手势移动位移变量
    67. */
    68. mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
    69. mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(mc.get('pan'));
    70. mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get('pan'), mc.get('rotate')]);
    71. //结束时做一些处理
    72. mc.on("hammer.input", function(ev) {
    73. if(ev.isFinal) {
    74. console.log(START_X+" "+transform.translate.x +" "+ev.deltaX);
    75. START_X = transform.translate.x ;
    76. START_Y = transform.translate.y ;
    77. }
    78. });
    79. mc.on("panstart panmove", onPan);
    80. mc.on("rotatestart rotatemove rotateend", onRotate);
    81. mc.on("pinchstart pinchmove", onPinch);
    82. /**
    83. 第二次进入拖拽时 delta位移重置
    84. 移动时 初始位置startxy不动。delta增加
    85. */
    86. function onPan(ev){
    87. if(!ev.isFinal) {
    88. el.className = '';
    89. console.log(START_X +" "+ START_Y +" | "+ev.deltaX +" "+ ev.deltaY);
    90. transform.translate = {
    91. x: START_X + ev.deltaX,
    92. y: START_Y + ev.deltaY
    93. };
    94. requestElementUpdate();
    95. }
    96. }
    97. function onPinch(ev){
    98. if(ev.type == 'pinchstart') {
    99. initScale = transform.scale || 1;
    100. }
    101. el.className = '';
    102. transform.scale = initScale * ev.scale;
    103. requestElementUpdate();
    104. }
    105. //旋转相关
    106. var preAngle =0 ;
    107. var tempAngleFlag=0;
    108. var deltaAngle = 0;
    109. var startRotateAngle = 0;
    110. function onRotate(ev) {
    111. //点下第二个触控点时触发
    112. if(ev.type == 'rotatestart') {
    113. startRotateAngle = ev.rotation ;
    114. tempAngleFlag = 0 ;
    115. }
    116. if(ev.type == 'rotatemove'){
    117. if(tempAngleFlag == 0){
    118. preAngle = startRotateAngle;
    119. tempAngleFlag ++;
    120. }else{
    121. deltaAngle = ev.rotation - preAngle;
    122. el.className = '';
    123. transform.rz = 1; //非0 垂直xy轴
    124. transform.angle =initAngle + deltaAngle;
    125. requestElementUpdate();
    126. }
    127. }
    128. //旋转结束 记录当前图片角度
    129. if(ev.type =='rotateend'){
    130. initAngle = transform.angle;
    131. }
    132. }
    133. function updateElementTransform() {
    134. var value = [
    135. 'translate3d(' + transform.translate.x + 'px, ' + transform.translate.y + 'px, 0)',
    136. 'scale(' + transform.scale + ', ' + transform.scale + ')',
    137. 'rotate3d('+ transform.rx +','+ transform.ry +','+ transform.rz +','+ transform.angle + 'deg)'
    138. ];
    139. value = value.join(" ");
    140. el.style.webkitTransform = value; /*为Chrome/Safari*/
    141. el.style.mozTransform = value; /*为Firefox*/
    142. el.style.transform = value; /*IE Opera?*/
    143. ticking = false;
    144. }
    145. function requestElementUpdate() {
    146. if(!ticking) {
    147. reqAnimationFrame(updateElementTransform);
    148. ticking = true;
    149. }
    150. }
    151. /**
    152. 初始化设置
    153. */
    154. function resetElement() {
    155. el.className = 'animate';
    156. transform = {
    157. translate: { x: START_X, y: START_Y },
    158. scale: 1,
    159. angle: 0,
    160. rx: 0,
    161. ry: 0,
    162. rz: 0
    163. };
    164. requestElementUpdate();
    165. }
    166. resetElement();
    167. script>
    168. body>
    169. html>

    hammer 中文教程https://www.jianshu.com/p/0b0b9364f967

    在vue 单独使用: https://blog.csdn.net/weixin_43963309/article/details/119057622

    vue 安装插件vue3-photo-hammer-mixture

  • 相关阅读:
    隆云通土壤pH传感器(扁三针)
    多线程(概念介绍)
    迁移学习
    STM32中断应用概括
    深入了解- TCP拥塞状态机 tcp_fastretrans_alert
    【如何学习CAN总线测试】——AUTOSAR网络管理测试
    windows操作系统双网卡问题处理办法
    卡塔尔世界杯在哪里可以看直播?
    设备软件控制平台会是什么样子?
    labview中如何更快的生成数组
  • 原文地址:https://blog.csdn.net/cddcj/article/details/125907676