文档章节

小程序swiper demo

igoryuyu
 igoryuyu
发布于 2018/08/28 17:48
字数 1756
阅读 693
收藏 0

小程序swiper demo

demo的性能太差,仅仅是提供思路,实际应用中需要优化
纯js实现swiper

方案1(需要优化性能、上下滚动)

swiper.js

function swiper(that) {
  that.handleStart = handleStart
  that.handleMove = handleMove
  that.handleEnd = handleEnd
}
/*
* @触摸起点
* @获取起点时间,起点坐标
*/
function handleStart(e){
  const { timeStamp } = e // 起点时间
  const { clientX, clientY } = e.touches[0] //起点坐标
  this.setData({ 
    touching: true,
    startX: clientX,
    startY: clientY,
    startTime: timeStamp
  })
}
/*
* @触摸变换
* @坐标轴
* X -> 右, X轴自左向右自增
* Y -> 下, Y轴自上向下自增
*
* @上下滑动(|Y| > |X|),终止计算
* @左右滑动(|Y| < |X|),终点X坐标 - 起点X坐标 > 0
* > 0;(页面向右滑动,偏移距离增大。偏移距离 = offsetOld + |X|)
* < 0;(页面向左滑动,偏移距离减小。偏移距离 = offsetOld - |X|)
*
*/
function handleMove(e){ // 坐标变换,触摸变换触发页面左右滑动
  const { clientX, clientY } = e.touches[0]
  let { startX, startY, offsetOld } = this.data
  let _X = clientX - startX,
      _Y = clientY - startY
  if(Math.abs(_X) <= Math.abs(_Y)) 
    return this.setData({ touching: false })
  else
    this.setData({ offset: offsetOld + _X })
}
/*
* @触摸结束
*
* @上下滑动(|Y| > |X|),终止计算
* @左右滑动(|Y| < |X|)
*
* @快速滑动: 时间最长小于300ms,最短距离50触发滑动事件  T < 300 && |X| >= 50
* @慢速滑动: T > 300 && |X| >= width/2
* index = 0 终止右移(X > 0),并复原move效果
* index = last 终止左移(X < 0),并复原move效果
*/
function handleEnd(e){ // 坐标变换终止
  const { timeStamp, target: { dataset: { index } } } = e // index 小圆点变换状态
  const { clientX, clientY } = e.changedTouches[0]
  let { list, startX, startY, startTime, width, offset, offsetOld } = this.data
  let T = timeStamp - startTime,
      _X = clientX - startX,
      _Y = clientY - startY,
      X = Math.abs(_X),
      Y = Math.abs(_Y)
  if(X < Y || T < 300 && X < 50 || T >= 300 && X < Math.round(width/2) || index == 0 && _X > 0 || index == list.length - 1 &&  _X < 0) {
    this.setData({
      offset: offsetOld
    })
  }else {
    // if(T <= 300) {
    //   this.setData({ duration: 300 })
    //   setTimeout(() => {
    //     this.setData({ duration: 0 })
    //   }, 300)
    // }
    if(_X < 0) width = -width
      this.setData({
        offset: offsetOld + width,
        offsetOld: offsetOld + width,
      })
  }

}
module.exports = swiper 

swiper.wxss

.page-swiper{
  width:100%;
  overflow-x:hidden;
}
.swiper-content{
  display:flex;
  min-height:100vh;
}
.swiper-content .content-slider{
  width:100vh;
  position: relative;
  top:0;
  left:0;
}
.swiper-content .content-slider:nth-child(odd){
  background-color:#f5f5f5;
}
.overflow-hidden{
  overflow:hidden;
}

index.js

const swiper = require('../../../../util/swiper')
Page({
  data: {
    list: [
      {
        page: '',
        title: '展览展览'
      },
      {
        page: '',
        title: 'VIP专区VIP专区'
      },
      {
        page: '',
        title: '购票购票购票'
      },
      {
        page: '',
        title: '动态动态动态'
      }
    ],
    touching: false, // 触摸后防止抖动
    duration: 600, // 延缓动画
    offsetOld: 0, // 保留距离状态 
    offset: 0, // 向左移动的距离 
    startX: 0, // X轴起点坐标
    startY: 0, // Y轴起点坐标
    startTime: 0, // 触摸起点时间
    width: 375 //默认屏幕宽度
  },
  /*
  * @获取设备宽度
  */
  onLoad() {
    const res = wx.getSystemInfoSync()
    this.setData({ width: res.windowWidth })
    swiper(this)
  },
})

index.wxml

<view class="page-swiper" bind:touchstart="handleStart" bind:touchmove="handleMove" bind:touchend="handleEnd">
  <view class="swiper-content {{touching?'overflow-hidden':''}}" style="width:{{width*list.length}}px;transform: translate3d({{offset ? offset : 0}}px, 0px, 0px);transition-duration: {{duration}}ms;">
    <view 
      class="content-slider" 
      wx:for-items="{{list}}" 
      wx:key="{{item}}" 
      data-index="{{index}}"
    >
    <scroll-view>
      {{item.title}}
    </scroll-view>
  </view>
  </view>
</view>

index.wxss

.page-swiper{
  width:100%;
  overflow-x:hidden;
}
.swiper-content{
  display:flex;
  min-height:100vh;
}
.swiper-content .content-slider{
  width:100vh;
  position: relative;
  top:0;
  left:0;
}
.swiper-content .content-slider:nth-child(odd){
  background-color:#f5f5f5;
}
.swiper-transform {
  transform: translate3d(0px, 0px, 0px);
  transition-duration: 0ms;
}

实现2(不推荐)

index.js

Page({
  data: {
    list: [
      {
        page: '',
        title: '展览展览'
      },
      {
        page: '',
        title: 'VIP专区VIP专区'
      },
      {
        page: '',
        title: '购票购票购票'
      },
      {
        page: '',
        title: '动态动态动态'
      }
    ],
    offsetOld: 0, // 保留距离状态 
    offset: 0, // 向左移动的距离 
    startX: 0, // X轴起点坐标
    startY: 0, // Y轴起点坐标
    startTime: 0, // 触摸起点时间
    width: 375 //默认屏幕宽度
  },
  /*
  * @获取设备宽度
  */
  onLoad() {
    const res = wx.getSystemInfoSync()
    this.setData({ width: res.windowWidth })
  },
  /*
  * @触摸起点
  * @获取起点时间,起点坐标
  */
  handleStart(e){
    const { timeStamp } = e // 起点时间
    const { clientX, clientY } = e.touches[0] //起点坐标
    this.setData({ 
      startX: clientX,
      startY: clientY,
      startTime: timeStamp
    })
  },
  /*
  * @触摸变换
  * @坐标轴
  * X -> 右, X轴自左向右自增
  * Y -> 下, Y轴自上向下自增
  *
  * @上下滑动(|Y| > |X|),终止计算
  * @左右滑动(|Y| < |X|),终点X坐标 - 起点X坐标 > 0
  * > 0;(页面向右滑动,偏移距离增大。偏移距离 = offsetOld + |X|)
  * < 0;(页面向左滑动,偏移距离减小。偏移距离 = offsetOld - |X|)
  *
  */
  handleMove(e){ // 坐标变换,触摸变换触发页面左右滑动
    const { clientX, clientY } = e.touches[0]
    let { startX, startY, offsetOld } = this.data
    let _X = clientX - startX,
        _Y = clientY - startY
    if(Math.abs(_X) <= Math.abs(_Y)) return
    this.setData({ offset: offsetOld + _X })
  },
  /*
  * @触摸结束
  *
  * @上下滑动(|Y| > |X|),终止计算
  * @左右滑动(|Y| < |X|)
  *
  * @快速滑动: 时间最长小于300ms,最短距离50触发滑动事件  T < 300 && |X| >= 50
  * @慢速滑动: T > 300 && |X| >= width/2
  * index = 0 终止右移(X > 0),并复原move效果
  * index = last 终止左移(X < 0),并复原move效果
  */
  handleEnd(e){ // 坐标变换终止
    const { timeStamp, target: { dataset: { index } } } = e // index 小圆点变换状态
    const { clientX, clientY } = e.changedTouches[0]
    let { list, startX, startY, startTime, width, offset, offsetOld } = this.data
    let T = timeStamp - startTime,
        _X = clientX - startX,
        _Y = clientY - startY,
        X = Math.abs(_X),
        Y = Math.abs(_Y)
    // if(X < Y) return
    if(X < Y || T < 300 && X < 50 || T >= 300 && X < Math.round(width/2) || index == 0 && _X > 0 || index == list.length - 1 &&  _X < 0) {
      this.setData({
        offset: offsetOld
      })
    }else {
      if(_X < 0) width = -width
        this.setData({
          offset: offsetOld + width,
          offsetOld: offsetOld + width,
        })
    }
  }
})

index.wxss

.page-swiper{
  width:100%;
  overflow-x:hidden;
}
.swiper-content{
  display:flex;
  min-height:100vh;
}
.swiper-content .content-slider{
  width:100vh;
  position: relative;
  top:0;
  left:0;
}
.swiper-content .content-slider:nth-child(odd){
  background-color:#f5f5f5;
}
.swiper-transform {
  transition: all 100ms ease;
  -webkit-transform: translate3d(0, 0, 0);
  -moz-transform: translate3d(0, 0, 0);
  -ms-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -ms-backface-visibility: hidden;
  backface-visibility: hidden;
  -webkit-perspective: 1000;
  -moz-perspective: 1000;
  -ms-perspective: 1000;
  perspective: 1000;
}

index.wxml

<view class="page-swiper" bind:touchstart="handleStart" bind:touchmove="handleMove" bind:touchend="handleEnd">
  <view class="swiper-content" style="width:{{width*list.length}}px">
    <view 
      class="content-slider {{startTime ? 'swiper-transform':''}}" 
      style="left: {{offset}}px" 
      wx:for-items="{{list}}" 
      wx:key="{{item}}" 
      data-index="{{index}}"
    >
    {{item.title}}
  </view>
  </view>
</view>

抽象为工具 swiper.js

function swiper(that) {
  that.handleStart = handleStart
  that.handleMove = handleMove
  that.handleEnd = handleEnd
}
/*
* @触摸起点
* @获取起点时间,起点坐标
*/
function handleStart(e){
  const { timeStamp } = e // 起点时间
  const { clientX, clientY } = e.touches[0] //起点坐标
  this.setData({ 
    startX: clientX,
    startY: clientY,
    startTime: timeStamp
  })
}
/*
* @触摸变换
* @坐标轴
* X -> 右, X轴自左向右自增
* Y -> 下, Y轴自上向下自增
*
* @上下滑动(|Y| > |X|),终止计算
* @左右滑动(|Y| < |X|),终点X坐标 - 起点X坐标 > 0
* > 0;(页面向右滑动,偏移距离增大。偏移距离 = offsetOld + |X|)
* < 0;(页面向左滑动,偏移距离减小。偏移距离 = offsetOld - |X|)
*
*/
function handleMove(e){ // 坐标变换,触摸变换触发页面左右滑动
  const { clientX, clientY } = e.touches[0]
  let { startX, startY, offsetOld } = this.data
  let _X = clientX - startX,
      _Y = clientY - startY
  if(Math.abs(_X) <= Math.abs(_Y)) return
  this.setData({ offset: offsetOld + _X })
}
/*
* @触摸结束
*
* @上下滑动(|Y| > |X|),终止计算
* @左右滑动(|Y| < |X|)
*
* @快速滑动: 时间最长小于300ms,最短距离50触发滑动事件  T < 300 && |X| >= 50
* @慢速滑动: T > 300 && |X| >= width/2
* index = 0 终止右移(X > 0),并复原move效果
* index = last 终止左移(X < 0),并复原move效果
*/
function handleEnd(e){ // 坐标变换终止
  const { timeStamp, target: { dataset: { index } } } = e // index 小圆点变换状态
  const { clientX, clientY } = e.changedTouches[0]
  let { list, startX, startY, startTime, width, offset, offsetOld } = this.data
  let T = timeStamp - startTime,
      _X = clientX - startX,
      _Y = clientY - startY,
      X = Math.abs(_X),
      Y = Math.abs(_Y)
  if(X < Y || T < 300 && X < 50 || T >= 300 && X < Math.round(width/2) || index == 0 && _X > 0 || index == list.length - 1 &&  _X < 0) {
    this.setData({
      offset: offsetOld
    })
  }else {
    if(_X < 0) width = -width
      this.setData({
        offset: offsetOld + width,
        offsetOld: offsetOld + width,
      })
  }
}
module.exports = swiper 

修改index.js

const swiper = require('~/util/swiper')
Page({
  data: {
    list: [
      {
        page: '',
        title: '展览展览'
      },
      {
        page: '',
        title: 'VIP专区VIP专区'
      },
      {
        page: '',
        title: '购票购票购票'
      },
      {
        page: '',
        title: '动态动态动态'
      }
    ],
    offsetOld: 0, // 保留距离状态 
    offset: 0, // 向左移动的距离 
    startX: 0, // X轴起点坐标
    startY: 0, // Y轴起点坐标
    startTime: 0, // 触摸起点时间
    width: 375 //默认屏幕宽度
  },
  /*
  * @获取设备宽度
  */
  onLoad() {
    const res = wx.getSystemInfoSync()
    this.setData({ width: res.windowWidth })
    swiper(this)
  }
})

© 著作权归作者所有

igoryuyu
粉丝 0
博文 15
码字总数 31758
作品 0
徐汇
高级程序员
私信 提问
Angular中使用Swiper

项目使用的Angular版本是V6.0.3 安装Swiper npm install swiper --save 或者 yarn add swiper --save 在angular.json文件添加swiper.js和swiper.css 安装模组定义档 npm install @types/swi......

小略子
2018/07/07
0
0
爬虫界的福利--touchRobot,机器模拟触碰滑动(已开源)

此插件能干什么? 一句话概括:通过程序主动触发移动端滑动、拖拽、触碰等操作 插件有什么用呢? 插件演示地址 (从网上扒了一个canvas绘图的demo,引入touchRobot,通过程序绘图) 注意,请在...

carr_y
05/12
0
0
Swiper v4.0.1 发布,支持硬件加速的触摸滑动库

Swiper v4.0.1 已发布,Swiper 是移动端使用的触摸滑动的一个开源库,可应用于移动网站、Web App、Native APP 和混合类 APP,支持硬件加速。 Swiper 专为 iOS 设计,但也支持 Android、Windo...

王练
2017/10/12
966
1
swiper.js-全屏动画切换效果实现

针对swiper.js的全屏动画切换,我们已经简单分析和介绍过一次: http://my.oschina.net/u/2352644/blog/487902 这个里面非常简单的分析了如何加入我们的动画效果,swiper现在已经出现了3.0版...

透笔度
2016/02/15
3.4K
0
图片/文本像素化工具库 - pixel-swiper

pixel-swiper 是一个用 canvas 实现的工具库,将图片(文本)像素化,附带粒子切换效果。 DEMO 1 DEMO 2 DEMO 3 DEMO 4 Browser <script src="yourStaticPath/pixelSwiper.js"></script> Defa......

KiloHaty
2018/06/26
278
0

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
7
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部