微信小程序实现手势滑动卡片效果


Posted in Javascript onAugust 26, 2019

最近工作中有项目要使用微信小程序技术进行开发,其中一项功能困扰了我很久,卡片滑动动效以及手势识别。经过一番研究和参考,现在把成果展示。记录自己踩到的坑,如果大家有需要,也可以帮助到大家。

效果图:

微信小程序实现手势滑动卡片效果

首先是卡片布局的实现:

微信小程序实现手势滑动卡片效果

图片(一)

如图所示,我采用绝对定位absolute的方式,辅助index,可以实现卡片的层叠效果。注意:三张卡片一定都是相同的定位,否则index可能不起作用。

代码:

//设置position: absolute; left:50%;后,再 margin-left:负(一半的width);可以实现水平居中
//同理,设置top:50%;margin-top:负(一半height);可以实现垂直居中
.body-swiper {
 width: 680rpx;//rpx是为了适应屏幕
 height: 900rpx;
 left: 50%;
 position: absolute;
 margin-left: -340rpx;
 z-index: 3;
 box-sizing: border-box;
 -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 60px rgba(0, 0, 0, 0.06) inset;
 -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 40px rgba(0, 0, 0, 0.06) inset;
 box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 40px rgba(0, 0, 0, 0.06) inset;
 border-radius: 12px;
}
 
.body-swiper2 {
 width: 640rpx;
 height: 900rpx;
 left: 50%;
 position: absolute;
 margin-left: -320rpx;
 z-index: 2;
 box-sizing: border-box;
 -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 60px rgba(0, 0, 0, 0.06) inset;
 -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 40px rgba(0, 0, 0, 0.06) inset;
 box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 40px rgba(0, 0, 0, 0.06) inset;
 border-radius: 12px;
}
 
.body-swiper3 {
 width: 605rpx;
 height: 900rpx;
 left: 50%;
 position: absolute;
 margin-left: -302.5rpx;
 z-index: 1;
 box-sizing: border-box;
 -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 60px rgba(0, 0, 0, 0.06) inset;
 -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 40px rgba(0, 0, 0, 0.06) inset;
 box-shadow: 0 1px 4px rgba(0, 0, 0, 0.62), 0 0 40px rgba(0, 0, 0, 0.06) inset;
 border-radius: 12px;
}

接下来,是卡片手势的实现;

上代码:

/**
 * 卡片1手势
 */
 touchstart1: function (event) {
 touchDotX = event.touches[0].pageX; // 获取触摸时的原点
 touchDotY = event.touches[0].pageY;
 console.log("起始点的坐标X:" + touchDotX);
 console.log("起始点的坐标Y:" + touchDotY);
 },
 // 移动结束处理动画
 touchend1: function (event) {
 // 手指离开屏幕时记录的坐标
 let touchMoveX = event.changedTouches[0].pageX;
 let touchMoveY = event.changedTouches[0].pageY;
 // 起始点的坐标(x0,y0)和手指离开时的坐标(x1,y1)之差
 let tmX = touchMoveX - touchDotX;
 let tmY = touchMoveY - touchDotY;
 // 两点横纵坐标差的绝对值
 let absX = Math.abs(tmX);
 let absY = Math.abs(tmY);
 //起始点的坐标(x0,y0)和手指离开时的坐标(x1,y1)之间的距离
 let delta = Math.sqrt(absX * absX + absY * absY);
 console.log('起始点和离开点距离:' + delta + 'px');
 // 如果delta超过60px(可以视情况自己微调),判定为手势触发
 if (delta >= 60) {
 // 如果 |x0-x1|>|y0-y1|,即absX>abxY,判定为左右滑动
 if (absX > absY) {
 // 如更tmX<0,即(离开点的X)-(起始点X)小于0 ,判定为左滑
 if (tmX < 0) {
  console.log("左滑=====");
  // 执行左滑动画
  this.Animation1(-500);
  // 如更tmX>0,即(离开点的X)-(起始点X)大于0 ,判定为右滑
 } else {
  console.log("右滑=====");
  // 执行右滑动画
  this.Animation1(500);
 }
 // 如果 |x0-x1|<|y0-y1|,即absX<abxY,判定为上下滑动
 } else {
 // 如更tmY<0,即(离开点的Y)-(起始点Y)小于0 ,判定为上滑
 if (tmY < 0) {
  console.log("上滑动=====");
  this.setData({
  isFront1: !this.data.isFront1
  });
  // 如更tmY>0,即(离开点的Y)-(起始点Y)大于0 ,判定为下滑
 } else {
  console.log("下滑动=====");
  this.setData({
  isFront1: !this.data.isFront1
  });
 }
 }
 } else {
 console.log("手势未触发=====");
 }
 
 // 让上一张卡片展现正面(如果之前翻转过的话)
 this.setData({
 isFront3: true,
 });
 }

为了更直观的看到手势触发的条件,我画了一张图:

微信小程序实现手势滑动卡片效果

图片(二)

最后是动画的编写;

上代码:

/**
 * 卡片1:
 * 左滑动右滑动动画
 */
 Animation1: function (translateXX) {
 let animation = wx.createAnimation({
 duration: 680,
 timingFunction: "ease",
 });
 this.animation = animation;
 // 如果大于0,判定是右滑动画,否则左滑
 if (translateXX > 0) {
 this.animation.translateY(0).rotate(20).translateX(translateXX).opacity(0).step();
 } else {
 this.animation.translateY(0).rotate(-20).translateX(translateXX).opacity(0).step();
 }
 // 设置10ms,视觉欺骗,直接归位到原来位置
 this.animation.translateY(0).translateX(0).opacity(1).rotate(0).step({
 duration: 10
 });
 
 this.setData({
 animationData1: this.animation.export(),
 });
 // 动画结束后重拍三张卡片
 setTimeout(() => {
 this.setData({
 ballTop1: 220,
 ballLeft1: -302.5,
 ballWidth1: 605,
 index1: 1,
 
 ballTop2: 240,
 ballLeft2: -340,
 ballWidth2: 680,
 index2: 3,
 
 ballTop3: 230,
 ballLeft3: -320,
 ballWidth3: 640,
 index3: 2,
 })
 }, 500);
 }

如此一来,大功告成,我自己测试了几次,暂时没有发现什么大问题。如果你有更好的实现方法,欢迎留言。

代码已上传到github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery插件开发全解析
Oct 10 Javascript
JS中表单的使用小结
Jan 11 Javascript
使用typeof方法判断undefined类型
Sep 09 Javascript
js使用post 方式打开新窗口
Feb 26 Javascript
基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转
Jun 12 Javascript
详解Javascript获取缓存和清除缓存API
May 25 Javascript
利用C/C++编写node.js原生模块的方法教程
Jul 07 Javascript
浅析Angular19 自定义表单控件
Jan 31 Javascript
微信小程序实现预览图片功能
Oct 22 Javascript
详解JS浏览器事件循环机制
Mar 27 Javascript
个人小程序接入支付解决方案
May 23 Javascript
微信小程序实现下拉刷新动画
Jun 21 Javascript
微信小程序实现左侧滑栏过程解析
Aug 26 #Javascript
vue柱状进度条图像的完美实现方案
Aug 26 #Javascript
React传值 组件传值 之间的关系详解
Aug 26 #Javascript
js实现指定时间倒计时效果
Aug 26 #Javascript
Vue.use()在new Vue() 之前使用的原因浅析
Aug 26 #Javascript
微信小程序事件 bindtap bindinput代码实例
Aug 26 #Javascript
详解在vue-cli3.0中自定css、js和图片的打包路径
Aug 26 #Javascript
You might like
使用apache模块rewrite_module (转)
2007/02/14 PHP
ThinkPHP模板循环输出Volist标签用法实例详解
2016/03/23 PHP
PHP+Ajax无刷新带进度条图片上传示例
2017/02/08 PHP
完美解决Thinkphp3.2中插入相同数据的问题
2017/08/01 PHP
Laravel框架Eloquent ORM简介、模型建立及查询数据操作详解
2019/12/04 PHP
jQuery事件 delegate()使用方法介绍
2012/10/30 Javascript
js禁止document element对象选中文本实现代码
2013/03/21 Javascript
简单实现异步编程promise模式
2015/07/31 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
2016/09/21 Javascript
js, jQuery实现全选、反选功能
2017/03/08 Javascript
详解http访问解析流程原理
2017/10/18 Javascript
基于JavaScript中标识符的命名规则介绍
2018/01/06 Javascript
vue.js在标签属性中插入变量参数的方法
2018/03/06 Javascript
基于Vue 服务端Cookies删除的问题
2018/09/21 Javascript
用Fundebug插件记录网络请求异常的方法
2019/02/21 Javascript
Vue页面切换和a链接的本质区别详解
2019/11/12 Javascript
解决Can't find variable: SockJS vue项目的问题
2020/09/22 Javascript
[01:32]2014DOTA2西雅图邀请赛 CIS我们有信心进入正赛
2014/07/08 DOTA
新手该如何学python怎么学好python?
2008/10/07 Python
python中的字典详细介绍
2014/09/18 Python
Python中关键字nonlocal和global的声明与解析
2017/03/12 Python
python pandas实现excel转为html格式的方法
2018/10/23 Python
在PYQT5中QscrollArea(滚动条)的使用方法
2019/06/14 Python
Python OpenCV之图片缩放的实现(cv2.resize)
2019/06/28 Python
Python搭建代理IP池实现获取IP的方法
2019/10/27 Python
Python数据可视化:顶级绘图库plotly详解
2019/12/07 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
Python多个装饰器的调用顺序实例解析
2020/05/22 Python
java关于string最常出现的面试题整理
2021/01/18 Python
详解css3中的伪类before和after常见用法
2020/11/17 HTML / CSS
HTML5不支持frameset的两种解决方法
2016/11/14 HTML / CSS
澳大利亚天然护肤品、化妆品和健康产品一站式商店:Nourished Life
2018/12/02 全球购物
教师纪念9.18事件演讲稿范文
2014/09/14 职场文书
2015年化验室工作总结
2015/04/23 职场文书
三严三实·严以用权心得体会
2016/01/12 职场文书
某某店铺的开业庆典主持词范本
2019/11/25 职场文书