微信小程序中实现手势缩放图片
在开发「知了地铁」小程序的时候,我们发现:在几寸的手机屏幕上完整显示地铁线网图,用户就很难看清细节;而默认将线网图按照 1:1 模式显示出来,用户需要多次拖动才能看到线网图的概况。
很明显,两种实现方式的体验,都非常糟糕。
因此,如果要在小程序中展示带有细节信息的图片(例如地铁线网图),就需要为其加上缩放功能。而用双指张合手势进行缩放,是大部分智能手机用户都已经习惯了的缩放方法。
今天,知晓程序就为大家带来有关手势缩放功能的实现方法,以及手势缩放实现在小程序中的局限和问题。
关注知晓程序(微信号 zxcx0101),回复「知了地铁」,抢先看「知了地铁」小程序上手体验文章。
手势动态检测
首先,我们需要获得用户的触摸事件。只有获得了这个事件,小程序才能得知用户希望缩放图片,同时确定图片的缩放倍数。
我们发现微信提供 touchmove 事件,在用户触摸屏幕并在屏幕上移动手指时,这个事件就会被触发。
手势缩放的核心思想是:根据两只手指相对距离的变化来对图片进行放大或缩小。因此,我们需要知道两只手指相对距离的变化,才能做到良好的缩放体验。
touchmove
事件可以实现的功能,大致可以总结为:
- 手指在屏幕上进行移动时,对应的组件上就会以 16 ms 一次的频率不断触发
touchmove
事件; - 手指离开屏幕后,则会触发
touchend
事件。
touchmove
事件所包含的事件对象中有一个 touches
属性,此属性为当前停留在屏幕中的触摸点信息的数组。触摸点的信息包括:
identifier
:触摸点的标志符;pageX
和pageY
:距离文档左上角的距离;clientX
和clientY
:距离屏幕可显示区域左上角距离。
我们可以通过不断获取 clientX
和 clientY
数据的方式,来确定手指在屏幕上的位置变化。
xMove = e.touches[1].clientX - e.touches[0].clientX;
yMove = e.touches[1].clientY - e.touches[0].clientY;
distance = Math.sqrt(xMove * xMove + yMove * yMove);
distance
变量即为两只手指之间的距离。在 touchmove
被触发的时候,小程序就会计算一次 distance
。
我们为新的 distance
变量定名为 newDistance
,相应地,旧变量定名为 oldDistance
。
之后,我们设定一个新的变量 distanceDiff = newDistance - oldDistance
,它反映两次 touchmove
触发瞬间,两根手指相对距离的变化值。
distanceDiff
为正数时,表示两指间距离在变大,图片需要被放大;反之,则代表两指间距缩小,图片需要被缩小。
图片动态缩放
到这里,我们已经可以探测用户的手指距离变化了。接下来,我们需要根据用户的手势,确定图片缩放倍数,然后根据倍数缩放图片。
首先,要确定 distance
的变化值与图片放大或缩小的变化率相关联的规则。
我们将图片正常显示时的尺寸定为基准值,存放于变量 baseWidth
和 baseHeight
中。图片需要放大的倍数设置为变量 scale
,它的初始值和最小值为 1
,最大值可根据需要来设置。
经过多次试验,我们最后确定了一个公式:
newScale = oldScale + 0.005 * distanceDiff
此公式中的 0.005
为图片的缩放比例。在实测中,使用 0.005 这个值可获得比较良好的缩放体验。
现在,我们为图片对象绑定 touchmove
事件。在每次 touchmove
被触发后,我们都可以计算出新的图片需要被放大的倍数,我们将这个变量定名为 scale
。
具体方式是:在每次 touchmove
被触发后,通过探测手指距离变化而得到的数据,来得到图片按比例缩放后的高宽值。
scaleWidth = scale * baseWidth;
scaleHeight = scale * baseHeight;
接下来,我们在 WXML 中,将图片对象的高和宽绑定相应的动态值,我们就能实现手势缩放功能了:
<image class = "image"
src = "..."
style = "width:{{ scaleWidth }}px;
height:{{ scaleHeight }}px">
用 scroll-view
,还是用 view
?
实现了图片的缩放之后,还需要一个容器存放图片。微信为视图组件提供了 `scroll-view` 和 `view` 两种容器容。但在目前阶段,两种容器都不能非常完美地实现手势缩放功能。
我们原本使用的方案是:利用 scroll-view
,设置 scroll-x
和 scroll-y
属性为 true
。这样做,可以在放大并滑动浏览图片时,拥有良好的浏览体验。
但是,我们发现 scroll-view
组件还存在缩放时出现界面闪动的现象的 bug。用双指手势缩放存在 scroll-view
容器中的图片,极易触发此 bug。
此问题只能等待微信官方进行修复。但在目前阶段,开发者也可以选择:
- 放弃
scroll-view
,转而使用不带有良好滑动体验的 view 组件; - 放弃使用手势缩放功能,转而开发「放大 – 缩小」按钮组件。
以上就是知晓程序(微信号 zxcx0101)带来的手势缩放图片功能的实现教程。虽然目前手势缩放并不能完美实现,但也希望大家可以举一反三,通过这个思路,创造出体验更好的小程序。
本文由知晓程序原创出品,关注微信号 zxcx0101,回复「上手」获取全网最值得看的小程序上手体验系列文章。
快速关注知晓程序↓↓↓
知晓程序 ( 微信号 zxcx0101)是爱范儿旗下专注于小程序生态的公众号。我们提供最全面、新鲜的小程序资讯 ( 消息、观点、指南、活动)和服务,在这里你能了解到关于小程序的一切。