引文
发现自己好几天没更新了,今天有点空,还是做一点小整理&&记录吧。前几天,JK问我要之前做短视频的代码,收到代码后,他发出还是以前我们几个的代码质量高的感慨,才发现去年我也做了类似的事情,在android上。参考这篇文章
背景
背景是在小程序上做一个简化版的“探探”,什么是“探探”呢?大概是这样的效果。
思路
看了一下小程序的api,发现能支持到,先说思路吧。
微信提供了一个 movable-area
movable-view
-> 官方文档,他支持可移动的view -> 效果
所以上下左右滑动是支持的。注意到原形图中有倾斜,可以这样做
<view style='transform:rotate({{dx}}deg);'></view>
那么这个dx怎么得到呢,看文档提供了一个bindchange
的方法
bindchange
EventHandle
完成一次拖动后触发的事件,event.detail = {x: x, y: y, source: source},其中source表示产生移动的原因,值可为touch(拖动)、touch-out-of-bounds(超出移动范围)、out-of-bounds(超出移动范围后的回弹)、friction(惯性)和空字符串(setData)
不过支持的版本有点高,1.9.90才有,如果是bindchange,可以这样算dx
<movable-area>
<movable-view
...
bindchange="onChange">
</movable-view>
</movable-area>
onChange: function (event) {
var dx = (event.detail.x - this.data.x)
this.setData({ dx: dx })
}
看版本覆盖率,还有一些用户没覆盖到,向下兼容可以用另外一种写法
<movable-area >
<movable-view
...
catchtouchcancel="onCancel"
catchtouchend="onCancel"
catchtouchstart="onTouchStart"
catchtouchmove="onTouchMove">
</movable-view>
</movable-area>
data: {
originX: 0 ,
...
},
onTouchStart:function(e){
this.setData({ originX: e.touches[0].pageX })
},
onTouchMove:function(e){
var dx = (e.touches[0].pageX - this.data.originX) * 45 / this.data.width
this.setData({
dx: dx,
unlike: dx < -5,
like: dx > 5
})
},
onCancel: function (e) {
if (this.data.like) {
this.triggerEvent('like', { uid: this.data.user.uid }, {})
} else if (this.data.unlike) {
this.triggerEvent('unlike', { uid: this.data.user.uid }, {})
}
this.setData({ x: this.data.x, dx:0 })
},
然后在手指松开的时候,触发喜欢
和讨厌
的操作.到这里基本的方案就讲完了。有一些实现的问题,这里也分享下吧~
常见问题
1,缓存多少张?如何避免上下层触点混乱?
毕竟是webview,所以我只是缓存了两张而已,每一张是一层。
在wx:for中,顺便设置了layer的z-index。代码大概是这样的
<block
wx:for="{{queue}}"
wx:for-index="index"
wx:for-item="item"
wx:key="seq">
<custom-widget
wx:if="{{index>=queue.length-2}}"
target="{{item}}"
refer="{{referSize}}"
bindlike="onlike"
bindunlike="onunlike"
layer="{{index}}"></ustom-widget>
</block>
ustom-widget.wxml
<view style="z-index:{{layer}};">
...
</view>
2,初始状态是居中,居中的x,y怎么算?
x,y要先知道根view的高宽,我用wx.getSystemInfo
-> systeminfo的接口拿了,但是在我的pixel的手机上,高度错了,发现是screenHeight没减掉虚拟按键栏的高度。
最后是这样拿的
page.wxml
<view id="root">
...
</view>
page.js
Page({
onReady: function () {
var query = wx.createSelectorQuery();
query.select('#root').boundingClientRect();
query.exec((res) => {
console.log("width:" + res[0].width)
console.log("height:" + res[0].height)
})
}
})
3,看到小程序里面的x,y的单位是px,和我们用的的rpx如何换算?
在我的这篇博客中有提到H5的单位,小程序也不例外.是怎么算的呢?
看文档尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。
如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素.
则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
所以iphone的宽度是320rpx,所以iphone5就是
iphone5
1px = 2.34rpx
320*2.34 = 750iphone6 p
1px = 1.81rpx
414*1.81 = 750
简单说,就是rpx就是以750为基准的单位了,那么到实际设备中,可以这样换算
var screenWidth; //第二问中获得的屏幕宽度
function px2rpx(px){
return px*screenWidth/750;
}