视频滑动切换组件

价值君
• 阅读 661

适用于微信小程序(H5的话改一改也能用)的视频滑动切换组件

以前用过小程序提供的video-swiper组件, 其中的问题和bug也不做过多描述了。视频滑动切换组件
为了项目进度,当时也没过多思考,没用使用video-swiper,而是用swiper和swiper-item简单实现了功能,后来自己测出来了个问题,但是客户没有反馈,测试也没有提bug,所以这个问题就耽搁,现在抽空重新写个demo,等以后遇到类似的项目,再拿出来修改。
新写的这个demo就是参考了以前用过的轮播图组件的思想做的一个视频滑动切换组件,如果有其他问题,请大家不要吝啬,指点出来,谢谢!

还是直接上代码!!!
//index.ts
const randomColor: string[] = ['a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

interface BaseEvent extends WechatMiniprogram.BaseEvent {
  touches: Array<WechatMiniprogram.TouchDetail>
}

Page({

  /**
   * 页面的初始数据
   */
  data: {
    distance: 0,
    list: <Array<string>>[],
    windowInfo: <WechatMiniprogram.WindowInfo>{},
  },

  loadMoreColor() {
    if (this.loading) return
    this.loading = true
    //视频集合
    let list = [
      ''
    ]
    // for (let i = 0; i < 10; i++) {
    //   let color = '#'
    //   for (let n = 0; n < 6; n++) {
    //     color += randomColor[Math.floor(Math.random() * randomColor.length)]
    //   }
    //   console.log(color);

    //   list.push(color)
    // }

    setTimeout(() => {
      this.setData({
        list: [...this.data.list, ...list]
      }, () => {
        this.currentIndex === 0 && this.createVideoContext()
        this.loading = false
      })
    }, 2000);
  },

  createVideoContext() {
    this.videoExample && this.videoExample.stop && this.videoExample.stop()
    this.videoExample = wx.createVideoContext(`video_${this.currentIndex}`)
    this.videoExample.play()
  },

  videoExample: <Record<string, any> | null>null,  //video实例
  loading: false, //数据加载
  currentIndex: 0,  //当前swiper
  startLocation: <number>0,   //手指摁下位置
  endLocation: 0,      //手指抬起位置
  isTouchmove: false,    //是否有滑动操作
  inertiaRollState: true,   //惯性滚动效果是否结束  true结束  false未结束

  //触摸开始
  touchstart(e: BaseEvent) {
    if (!this.inertiaRollState) return
    //记录滑动初始位置
    this.startLocation = e.touches[0].clientY
  },

  //触摸移动
  touchmove(e: BaseEvent) {
    //如果swiper当前位置是0且是下拉的动作
    if ((this.currentIndex <= 0 && e.touches[0].clientY - this.startLocation > 0) || !this.inertiaRollState) return;
    console.log('touchmove');

    this.isTouchmove = true
    this.endLocation = e.touches[0].clientY
    //e.touches[0].clientY - this.startLocation手指滑动的距离
    //this.currentIndex * this.data.windowInfo.screenHeight已经卷上去的距离
    //distance一共卷上去的距离
    let distance = e.touches[0].clientY - this.startLocation - (this.currentIndex * this.data.windowInfo.screenHeight)
    this.setData({
      distance: this.currentIndex < this.data.list.length - 1 ? distance : Math.abs(distance) > this.currentIndex * this.data.windowInfo.screenHeight + 50 ? -(this.currentIndex * this.data.windowInfo.screenHeight + 50) : distance
    })
  },

  //触摸结束
  touchend() {
    //moveDistance手指滑动距离  大于0(moveState为true)时是下拉, 小于0(moveState为false)时是上拉
    let moveDistance = this.endLocation - this.startLocation
    let moveState = moveDistance > 0
    this.endLocation = 0
    this.startLocation = 0
    //如果swiper当前位置是0且是下拉的动作
    if ((this.currentIndex <= 0 && moveState) || !this.isTouchmove) return;
    this.isTouchmove = false
    this.inertiaRollState = false
    //手指滑动的距离不小于1/4, swiper执行切换
    if (Math.abs(moveDistance) >= this.data.windowInfo.screenHeight / 4) {
      let currentIndex = moveState ? this.currentIndex - 1 : this.currentIndex + 1
      if (currentIndex < this.data.list.length) {
        //如果加载到最后一个视频, 去拉取新的列表
        currentIndex === this.data.list.length - 1 && this.loadMoreColor()
        this.currentIndex = currentIndex
        this.inertiaRoll(moveState, -(this.currentIndex * this.data.windowInfo.screenHeight), true)
        return
      }
    }

    this.inertiaRoll(moveState, -(this.currentIndex * this.data.windowInfo.screenHeight))
  },
  touchcancel() { },

  /**
   * moveState滑动状态   为true时是下拉, 为false时是上拉
   * distance滑动距离的终点位置
  */
  inertiaRoll(moveState: boolean, distance: number, swiper = false) {
    let baseNum = Math.abs(this.data.distance - distance) / 10
    let intervalId = setInterval(() => {
      //下拉 值越来越大(从负无穷越来越接近于0)    上拉 值越来越小(负无穷)   
      let _d = moveState ? this.data.distance + baseNum : this.data.distance - baseNum
      if ((moveState && _d >= distance) || (!moveState && _d <= distance)) {
        //滑动切换完成
        this.setData({
          distance
        }, () => {
          swiper && this.createVideoContext()
          this.inertiaRollState = true
        })
        clearInterval(intervalId)
      } else {
        this.setData({
          distance: _d
        })
      }
    }, 10)
  },


  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    this.setData({
      windowInfo: wx.getWindowInfo()
    })
    this.loadMoreColor();
  }
})
<!--index.wxml-->
<view class="container" style="height: {{windowInfo.screenHeight}}px;">
  <view class="list-view" catchtouchstart="touchstart" catchtouchmove="touchmove" catchtouchend="touchend" catchtouchcancel="touchcancel" style="margin-top: {{distance}}px;">
    <view wx:for="{{list}}" wx:key="index" style="height: {{windowInfo.screenHeight}}px; background-color: {{item}};" class="list-item">
      <video id="{{'video_' + index}}" src="{{item}}" loop style="width: 100%; height: 100%;"></video>
    </view>
    <view style="height: 50px; line-height: 50px; text-align: center;">加载中...</view>
  </view>
</view>
/**index.wxss**/
.container {
  width: 100%;
  overflow: hidden;

  .list-view {
    .list-item {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
    }
  }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
梦
4年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Easter79 Easter79
3年前
Taro小程序自定义顶部导航栏
微信自带的顶部导航栏是无法支持自定义icon和增加元素的,在开发小程序的时候自带的根本满足不了需求,分享一个封装好的组件,支持自定义icon、扩展dom,适配安卓、ios、h5,全面屏。我用的是京东的Taro多端编译框架写的小程序,原生的也可以适用,用到的微信/taro的api做调整就行,实现效果如下。!在这里插入图片描述(https://i
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(