实现上下滑刷视频效果-微信小程序

<view class="page">
  <view class="swiper_out">
    <swiper class="swiper-box" duration="300" circular="{{circular}}" current="{{current}}" vertical="{{true}}" bindanimationfinish="swiperChange" bindtap="tabVideo">
      <swiper-item class="flexVerticalCenterColumn" wx:if="{{videoObjList[0].id}}" item-id="{{videoObjList[0].index}}">
        <video bindplay="eventPlay" id="video0" class="video" style="height: calc({{windowHeight}}px);" src="{{videoObjList[0].url}}" controls></video>
        <view class="video_name flexCenter" style="height: {{topHeight}}rpx;">{{videoObjList[0].content}}</view>
      </swiper-item>
      <swiper-item class="flexVerticalCenterColumn" wx:if="{{videoObjList[1].id}}" item-id="{{videoObjList[1].index}}">
        <video bindplay="eventPlay" id="video1" class="video" style="height: calc({{windowHeight}}px);" src="{{videoObjList[1].url}}" controls></video>
        <view class="video_name flexCenter" style="height: {{topHeight}}rpx;">{{videoObjList[1].content}}</view>
      </swiper-item>
      <swiper-item class="flexVerticalCenterColumn" wx:if="{{videoObjList[2].id}}" item-id="{{videoObjList[2].index}}">
        <video bindplay="eventPlay" id="video2" class="video" style="height: calc({{windowHeight}}px);" src="{{videoObjList[2].url}}" controls></video>
        <view class="video_name flexCenter" style="height: {{topHeight}}rpx;">{{videoObjList[2].content}}</view>
      </swiper-item>
    </swiper>
  </view>
</view>
.page {
  width: 100%;
  height: 100%;
}

.swiper_out {
  width: 100%;
  height: 100%;
}

.swiper-box {
  width: 100%;
  height: 100%;
}

.swiper {
  width: 100%;
  height: 100%;
  margin: 0 auto;
}

.video_out{
  width: 100%;
  position: relative;
}

.video {
  width: 100%;
  height: 100%;
}

.video_name{
  width: 100%;
  color: #ffffff;
  padding: 0 30rpx;
  box-sizing: border-box;
  background-color: #000000;
}

.video_container {
  width: 100%;
  height: 100%;
}
const app = getApp()
var main = require("../../../utils/util.js");
Page({

  /**
   * 页面的初始数据
   */
  data: {
    height: app.globalData.height + 5, //状态栏高度
    topHeight: app.globalData.topHeight, //获取整个标题栏高度
    ktxStatusHeight: app.globalData.ktxStatusHeight, //获取屏幕状态栏高度
    navigationHeight: app.globalData.navigationHeight, //获取屏幕导航栏高度
    bottomLift: app.globalData.bottomLift, //获取ios安全区高度
    windowWidth: app.globalData.windowWidth, //获取屏幕宽度
    windowHeight: app.globalData.windowHeight, //获取屏幕高度
    // white: true, //空白遮盖
    indicatorDots: false, //是否显示画板指示点
    vertical: true, //是否竖直
    autoplay: false, //是否自动切换
    interval: 5000, //自动切换的间隔
    duration: 500, //滑动动画时长毫秒
    shortVideoList: [], //短视频列表
    circular: false,
    // 当前播放视频的数据
    videoInfo: {
      index: 0,
    },
    // 滑块
    current: 0,
    // 播放状态
    playStatus: false,
    videoObjList: {
      0: {},
      1: {},
      2: {},
    },// 播放视频数组
    paging: {
      page: 1,
      size: 9
    },
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // main.showLoading('')
    this.setData({
      bottomLift: app.globalData.bottomLift, //获取ios安全区高度
    })
    this.pageStatus = 0 // 页面初始化状态
    this.videoKey = "video" // 视频id key
    this.videoList = [] // 渲染的视频
    this.residueVideoList = [] // 取余的数组
    this.videoIndex = 0 // 当前视频的位置
    this.loadingVideo = 0
  },

  // 获取视频列表
  getVideoList() {
    setTimeout(() => {
      let oldVideoLength = this.videoList.length
      // 这段模拟异步数据的获取
      let pageList = []
      var rows = []
      rows = main.getloc('shortVideoList')// 获取一级页面缓存视频列表
      rows.sort(function () {
        return Math.random() - 0.5 // 随机返回正或负值 达到排序的目的
      })
      pageList = rows
      pageList = pageList.map(v => {
        // v.videoUrl = ase.decrypt(v.videoUrl || "") // 视频链接加密 防止链接被盗用
        return v
      })
      // 无数据的情况
      if (pageList.length < 1 && this.data.paging.page == 1) {
        return
      }
      // 如果数据少于1重新拿分页为1的数据
      if (pageList.length < 1 && this.data.paging.page != 1) {
        this.setData({
          ['paging.page']: 1,
        })
        this.getVideoList()
        return
      }
      // 滑块数量
      let itemNumber = Object.keys(this.data.videoObjList).length || 3
      // 重新计算数组的排列
      const videoData = this.formArrayVideo(this.videoList, this.residueVideoList, pageList, itemNumber)
      // 渲染的数组
      this.videoList = videoData.list.map((v, index) => {
        return {
          ...v,
          index
        }
      })
      // 取余的数组
      this.residueVideoList = videoData.residue
      // 避免去重后数据保持不变产生死循环
      if (oldVideoLength != this.videoList.length) {
        this.setData({
          circular: true,
        })
        // 开始渲染
        this.lazyVideo()
      }
      // 第一次播放
      if (this.pageStatus == 0) {
        // 第一次初始化加载完毕
        this.pageStatus = 1
        // 滑块位置
        const current = this.data.current
        // 开始播放
        this.currentPlay(current, current)
      }
      this.setData({
        ['paging.page']: this.data.paging.page + 1,
      })
    }, 300)
    //   }
    // })
  },

  // swiper切换
  swiperChange(e) {
    if (e.detail.source == "touch") {
      // 旧的滑块位置
      const oldCurrent = this.data.current
      // 当前滑块的位置
      const current = e.detail.current
      if (oldCurrent == current) return;
      this.setData({
        current
      })
      // 当前视频在列表中的索引
      this.videoIndex = parseInt(e.detail.currentItemId)
      // 开始渲染
      this.lazyVideo()
      // 开始播放
      this.currentPlay(oldCurrent, current)
    }
  },

  // 加载视频
  lazyVideo() {
    const videoList = this.videoList // 渲染的数组
    const videoIndex = this.videoIndex // 当前播放的视频在数组里的索引
    const current = this.data.current // 滑块位置
    const lastVideo = videoList[videoIndex - 1] || {}
    const lastTwoVideo = videoList[videoIndex - 2] || {}
    const nowVideo = videoList[videoIndex] || {}
    const nextVideo = videoList[videoIndex + 1] || {}
    const nextTwoVideo = videoList[videoIndex + 2] || {}
    if (videoIndex == 0) {
      this.setData({
        circular: false,
        ['videoObjList.0']: nowVideo,
        ['videoObjList.1']: nextVideo,
        ['videoObjList.2']: nextTwoVideo,
      })
    } else if (videoIndex == videoList.length - 1) {
      console.log('滑动到了最后一页')
      this.setData({
        circular: false,
        ['videoObjList.0']: lastTwoVideo,
        ['videoObjList.1']: lastVideo,
        ['videoObjList.2']: nowVideo,
      })
      // 获取视频列表
      // this.getVideoList()
    } else {
      if (current == 0) {
        this.setData({
          circular: true,
          ['videoObjList.0']: nowVideo,
          ['videoObjList.1']: nextVideo,
          ['videoObjList.2']: lastVideo,
        })
      }
      if (current == 1) {
        this.setData({
          circular: true,
          ['videoObjList.0']: lastVideo,
          ['videoObjList.1']: nowVideo,
          ['videoObjList.2']: nextVideo,
        })
      }
      if (current == 2) {
        this.setData({
          circular: true,
          ['videoObjList.0']: nextVideo,
          ['videoObjList.1']: lastVideo,
          ['videoObjList.2']: nowVideo,
        })
      }
    }
    this.setData({
      videoInfo: nowVideo
    })
  },

  // 播放视频的逻辑
  currentPlay(oldCurrent, current) {
    // 获取上一个视频实例
    const oldVideoObj = this.getVideoObj(this.videoKey, oldCurrent)

    // 暂停上一个视频实例
    this.pauseVideo(oldVideoObj)
    // 获取当前视频实例
    const videoObj = this.getVideoObj(this.videoKey, current)
    // 播放当前视频实例
    this.playVideo(videoObj)
  },

  // 播放/或暂停视频
  tabVideo() {
    let playStatus = this.data.playStatus
    let current = this.data.current
    // 获取当前视频实例
    const videoObj = this.getVideoObj(this.videoKey, current)
    if (!playStatus) {
      // 播放停视频实例
      this.pauseVideo(videoObj)
    } else {
      // 播放当前视频实例
      this.playVideo(videoObj)
    }
    this.setData({
      playStatus: !playStatus
    })
  },

  // 视频开始播放
  eventPlay() {
    this.setData({
      playStatus: false
    })
  },

  // 播放视频
  playVideo(videoObj) {
    videoObj && videoObj.play()
  },

  // 暂停视频
  pauseVideo(videoObj) {
    videoObj && videoObj.pause()
  },

  // 销毁实例
  deleteVideoObJ(videoObj) {
    videoObj && videoObj.stop()
  },

  // 获取视频实例
  getVideoObj(key, index) {
    return wx.createVideoContext(key + index)
  },

  // 格式化数组取渲染数组及余数组
  formArrayVideo(oldList = [], residueList = [], newlist = [], itemNumber = 3) {
    // 原数组
    let onwList = oldList.concat(residueList, newlist)
    // 倍数
    const ints = Math.floor(onwList.length / itemNumber)
    // 最新数组
    const list = onwList.slice(0, ints * itemNumber) || []
    // 缓存余下的数组
    const residue = onwList.slice(ints * itemNumber, onwList.length) || []
    if (list.length < 1) {
      return {
        list: onwList,
        residue: [],
      }
    } else {
      return {
        list,
        residue,
      }
    }
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    this.videoObj0 = this.getVideoObj(this.videoKey, 0)
    this.videoObj1 = this.getVideoObj(this.videoKey, 1)
    this.videoObj2 = this.getVideoObj(this.videoKey, 2)

    // 获取视频列表
    this.getVideoList()
  },

})

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值