小程序 左滑喜欢右滑讨厌的实现

引文

发现自己好几天没更新了,今天有点空,还是做一点小整理&&记录吧。前几天,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 = 750

iphone6 p
1px = 1.81rpx
414*1.81 = 750

简单说,就是rpx就是以750为基准的单位了,那么到实际设备中,可以这样换算

var screenWidth; //第二问中获得的屏幕宽度
function px2rpx(px){
    return px*screenWidth/750;
}

猜你喜欢

转载自blog.csdn.net/yeshennet/article/details/80034856