小程序视频滑动

小程序视频滑动效果


<!--index.wxml-->
<view class="container" catchtap="changePlayStatus" bindtouchstart="touchStart" bindtouchend="touchEnd" bindtouchcancel="touchCancel">
  <view class="animation-wrapper" animation="{{animation}}">
    <block wx:for="{{videos}}" wx:key="{{index}}">
      <view class="animation-image-wrapper">
        <image mode="aspectFill" class="animation-image" src="{{item.poster}}"></image>
      </view>
    </block>
  </view>
  <video class="vvideo" bindtimeupdate="bindtimeupdate" id="kdvideo" binderror="binderror" autoplay="{{autoplay}}" hidden="{{animationShow}}" objectFit="fill" src="{{videos[videoIndex].videoUrl}}" bindplay="bindplay" controls="{{controls}}" loop="true"></video>
  <image class="play-btn" wx:if="{{!playState && !animationShow}}" src="../../icons/play.png"></image>
  <progress class="progress" percent="{{percent}}" activeColor="#ffffff" backgroundColor="#A9A9A9" stroke-width="1"  wx:if="{{!animationShow}}" />
</view>
```
**//index.js**

//获取应用实例
import * as event from '../utils/event.js'
const app = getApp()
const windowHeight = wx.getSystemInfoSync().windowHeight

Page({
  data: {
    percent: 1,
    autoplay: true,
    controls: false,
    showFullscreenBtn: false,
    showPlayBtn: false,
    showFullscreenBtn: false,
    showCenterPlayBtn: false,
    enableProgressGesture: false,
    showProgress: false,
    playState: true,
    animationShow: false,
    currentTranslateY: 0,
    touchStartingY: 0,
    videos: [
      {
        videoUrl: "/video/124/102786/video/gnsw252jizltonrsi5rtm2cwgi2g2scdjjat2pi.mp4?v=1577685896",
        poster: "/video/124/102786/video_thum/pf2ug3kzlj4dkyrrifuuq3dqjmyfqz3ygjat2pi.jpg?v=1577685896"
      },
      {
        videoUrl: "/video/162/103466/video/hfxgwy3hoyvtm3kgobvwsl3qijhgks3iifat2pi.mp4?v=1575176526",
        poster: "/video/162/103466/video_thum/jnuvc2tehfwuuqlkljgtcy3limztqnszljat2pi.jpg?v=1575176526"
      },
      {
        videoUrl: "/video/3/103558/video/n5igyrdso5muywljifcxsyrvnvygmztfnr3t2pi.mp4?v=1577433921",
        poster:"/video/3/103558/video_thum/njegqm2qmv5hgztnkjrwiwdej53e43cqnvit2pi.jpg?v=1577433921"
      },
      {
        videoUrl:"/video/3/104902/video/ojdhg3sgkyyvi3ctlaysw2cnmjxgku3vjfit2pi.mp4?v=1583722798",
        poster: "/video/3/104902/video_thum/j4vvgrzsmfzfa6rsm5yuwzkigzfvs6dym5at2pi.jpg?v=1583722798"
      }
    ],
    videoIndex: 0,
    objectFit: "contain"
  },
  onLoad: function () {
    // 滑动
    this.videoChange = throttle(this.touchEndHandler, 200)
    // 绑定updateVideoIndex事件,更新当前播放视频index
    event.on('updateVideoIndex', this, function (index) {
      console.log('event updateVideoIndex:', index)
      setTimeout(() => {
        this.setData({
          animationShow: false,
          playState: true
        }, () => {
          // 切换src后,video不能立即播放,settimeout一下
          setTimeout(() => {
            this.vvideo.play()
          }, 100)
        })
      }, 500)
    })
  },
  bindplay() {
    console.log('--- video play ---')
  },
  binderror(err) {
    console.log(err)
  },
  bindtimeupdate(e) {
    let percent = (e.detail.currentTime / e.detail.duration) * 100
    this.setData({
      percent: percent.toFixed(2)
    })
  },
  onReady: function () {
    this.vvideo = wx.createVideoContext("kdvideo", this)
    this.animation = wx.createAnimation({
      duration: 500,
      transformOrigin: '0 0 0'
    })
  },
  // 播放暂停
  changePlayStatus() {
    console.log('changePlayStatus')
    let playState = !this.data.playState
    if (playState) {
      this.vvideo.play()
    } else {
      this.vvideo.pause()
    }
    this.setData({
      playState: playState
    })
  },
  touchStart(e) {
    let touchStartingY = this.data.touchStartingY
    console.log('------touchStart------')
    touchStartingY = e.touches[0].clientY
    this.setData({
      touchStartingY: touchStartingY
    })
  },
  touchMove(e) {
    // this.videoChange(e)
  },
  touchEndHandler(e) {
    let touchStartingY = this.data.touchStartingY
    let deltaY = e.changedTouches[0].clientY - touchStartingY
    console.log('deltaY ', deltaY)

    let index = this.data.videoIndex
    if (deltaY > 100 && index !== 0) {
      // 更早地设置 animationShow
      this.setData({
        animationShow: true
      }, () => {
        console.log('-1 切换')
        this.createAnimation(-1, index).then((res) => {
          console.log(res)
          this.setData({
            animation: this.animation.export(),
            videoIndex: res.index,
            currentTranslateY: res.currentTranslateY,
            percent: 1
          }, () => {
            event.emit('updateVideoIndex', res.index)
          })
        })
      })
    } else if (deltaY < -100 && index !== (this.data.videos.length - 1)) {
      this.setData({
        animationShow: true
      }, () => {
        console.log('+1 切换')
        this.createAnimation(1, index).then((res) => {
          console.log(res)
          this.setData({
            animation: this.animation.export(),
            videoIndex: res.index,
            currentTranslateY: res.currentTranslateY,
            percent: 1
          }, () => {
            event.emit('updateVideoIndex', res.index)
          })
        })
      })
    }
  },
  touchEnd(e) {
    console.log('------touchEnd------')
    this.videoChange(e)
  },
  touchCancel(e) {
    console.log('------touchCancel------')
    console.log(e)
  },
  createAnimation(direction, index) {
    // direction为-1,向上滑动,animationImage1为(index)的poster,animationImage2为(index+1)的poster
    // direction为1,向下滑动,animationImage1为(index-1)的poster,animationImage2为(index)的poster
    let videos = this.data.videos
    let currentTranslateY = this.data.currentTranslateY
    console.log('direction ', direction)
    console.log('index ', index)

    // 更新 videoIndex
    index += direction
    currentTranslateY += -direction * windowHeight
    console.log('currentTranslateY: ', currentTranslateY)
    this.animation.translateY(currentTranslateY).step()

    return Promise.resolve({
      index: index,
      currentTranslateY: currentTranslateY
    })
  }
})
function throttle(fn, delay) {
  var timer = null;
  return function () {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      fn.apply(context, args);
    }, delay);
  }
}



/**index.wxss**/
page {
  height: 100vh;
  width: 100vw;
  position: fixed;
}
.container {
  height: 100vh;
  width: 100vw;
}
.vvideo {
  height: 100vh;
  width: 100vw;
  position: absolute;
  top: 0;
  left: 0;
}
.play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  height: 128rpx;
  width: 128rpx;
}
.progress {
  position: absolute;
  left: 0;
  bottom: 60px;
  height: 4px;
  width: 100vw;
}
.animation-wrapper {
  position: relative;
  height: 100vh;
  width: 100vw;
  background-color: #000;
}
.animation-image {
  height: 100vh;
  width: 100vw;
  display: block;
}
.animationPre {
  transform: translateY(-100%);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值