博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
h5实现移动端图片预览器(一)
阅读量:7112 次
发布时间:2019-06-28

本文共 4036 字,大约阅读时间需要 13 分钟。

最近接触vue.js移动端开发。自己写一个类似微博的图片预览器来学习一下移动端手势的实现和css3的属性的使用。

目标分析

首先分析图片预览器的功能:

1.图片显示

2.缩放(swipe)图片
3.拖拽图片(drag)
3.双击(doubleTap)放大/缩小
4.单击(tap)隐藏图片
5.左右滑到前一页或后一页

分析的手势有:单击(tap) 双击(doubleTap) 缩放(swipe) 拖拽(drag)

都是由有三个事件构成:touchstart, touchmove,touchend.

手势解析:

单击(tap)

手势分解:点击进入touchstart事件,touchmove几乎没有,但是也要为用户预留点击时的微小移动,再触发touchend事件。在本组件中touchmove移动半径设置为小于10

图片描述

从触摸屏幕到离开屏幕的时间是非常短的,所以touchstart事件到touchend事件之间的时间间隔是非常小的,不超过500毫秒。t2-t1<500

图片描述
代码实现:

onTouchstart(evt){    this.startTime = new Date().getTime();    if(evt.touches.length>1){//双手势    }else{//单手势         this.start.x = evt.touches[0].pageX;         this.start.y = evt.touches[0].pageY;    } } onTouchMove(evt){    this.move.x =  evt.touches[0].pageX;    this.move.y = evt.touches[0].pageY; } onTouchEnd(evt){    let timestamp = new Date().getTime();    if(this.move.x !== null && Math.abs(this.move.x - this.start.x)< 10 ||this.move.y !== null && Math.abs(this.move.y - this.start.y)<10){    //有移动的情况    }else{    //单击        if(timestamp - this.startTime < 500){            //触发单击事件        }    } }

双击(doubleTap)

双击事件包含了两次单击事件,区分在于两次单击的时间判断,两次单击的时间,也就是touchstart触发的时间间隔,不超过300毫秒,当然,也要给用户一些触摸移动的像素,将两个点的x,y轴上的距离控制在10像素内。
图片描述

实现:

touchStartFn(evt){      this.startTime = new Date().getTime();      if(evt.touches.length>1){//双手势       }else{//单手势            this.start.x = evt.touches[0].pageX;            this.start.y = evt.touches[0].pageY;            if(this.previousTouchPoint){//上一次的触摸点                if(Math.abs(this.start.x- this.previousTouchPoint.startX)<10 &&Math.abs(this.start.y- this.previousTouchPoint.startY)<10 && this.startTime - this.previousStartTime < 300){                   //触发双击的事件                    ...                }            }            this.previousTouchTime = this.startTime;            this.previousTouchPoint = {                startX:this.start.x,                startY:this.start.y            };       }   }

如果一个页面上既有单击tap事件,又有双击doubleTap事件,怎么办用上述方法,两种事件会相互冲突,光靠时间和偏移量来控制是不够的。

解决思路:初始化this.previousTouchTime = 0;this.previousTouchPoint = undefined;在执行完双击事件后将this.previousTouchPoint置为undefined,this.previousTouchTime置为0。在触摸结束事件中添加一个setTimeout来监听是否有新的单击事件发生。如果新单击事件发生,则去除这个监听,如果没有,则触发单击事件

touchEndFn(evt){    let timer = setTimeout(()=>{         if(this.previousTouchPoint !== undefined && this.previousTouchTime !== 0){         //触发单击事件         ...         }else{             clearTimeout(timer);//去除监听         }             },300);  }

这样,单击和双击事件就不会冲突了。

缩放(swipe)

缩放是个双手势触摸过程,触摸点会有两个,也就是Touch对象会有两个。并在触摸滑动过程中,要计算出缩放倍数。

图片描述
point1与point2的触摸开始位置和结束位置都会有偏移,缩放的倍数计算:scale = r2/r1

onTouchStart(evt){    if(evt.touches.length>1){//双手势        let point1 = evt.touches[0];        let point2 = evt.touches[1];        let deltaX = Math.abs(point2.pageX - point1.pageX);        let deltaY = Math.abs(point2.pageY - point1.pageY);        this.distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);//初始时候的距离,r1    }else{    //单手势事件    }}onTouchMove(evt){    if(evt.touches.legnth>1){         let point1 = evt.touches[0];        let point2 = evt.touches[1];        let deltaX = Math.abs(point2.pageX - point1.pageX);        let deltaY = Math.abs(point2.pageY - point1.pageY);        let distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);        if(this.distance){            this.swipeScale = distance/this.distance;            //执行缩放事件        }            }else{//单手势事件}}

拖拽/移动

移动事件就是在触摸屏幕并移动的时候,图片或者元素能够跟随手指一起移动。这是一个单手势操作,屏幕上只要一个触摸点。在touchmove发生时将坐标位置向减得到位移量。

图片描述

onTouchStart(evt){    if(evt.touches.length>1){//双手势    }else{//单手势         this.start.x = evt.touches[0].pageX;         this.start.y = evt.touches[0].pageY;    } } onTouchMove(evt){      if(evt.touches.length>1){//双手势               }else{//单手势          let deltaX  = evt.touches[0].pageX - this.start.x;          let deltaY = evt.touches[0].pageY- this.start.y;          //触发移动事件      } }

图片放大功能的实现

我采用了css3的transform属性进行缩放,并且设置transform-origin来设置缩放中心位置。缩放的倍数为缩放事件计算出的this.swipeScale

缩放代码:

$img.style.transform = "scale("+this.swipeScale +")";   $img.style.transformOrigin = x + " " + y;

下一节将讲用vue.js具体实现过程

转载地址:http://apmhl.baihongyu.com/

你可能感兴趣的文章
什么是软件测试
查看>>
(摘录笔记)蓝桥杯算法训练
查看>>
linux PATH变量
查看>>
测试流程
查看>>
我的友情链接
查看>>
c++产生100以内的随机数
查看>>
java设计模式-可复用面向对象软件的基础(四)
查看>>
VS2010中安装Qt插件错误
查看>>
nodejs中path模块
查看>>
MS_SQL必须了解的脚本语句(自留)
查看>>
《Python网络数据采集》读书笔记(四)
查看>>
数据结构 链表学习笔记
查看>>
C# 中奇妙的函数–String Split 和 Join
查看>>
禁止 iOS 浏览器 自动识别拨号
查看>>
KVM 手动添加raw格式的lun给guest
查看>>
ESXi5.1嵌套KVM虚拟化环境支持配置
查看>>
我的友情链接
查看>>
java学习笔记----运算符
查看>>
Linux 配置VNC远程桌面
查看>>
rdesktop的使用方法
查看>>