vue实现滚动到视频离开可视区后出现小窗(类似b站小窗)


前言

最近在做的仿网易云播放器项目中,视频界面有个需求:当滚动条滚动到主视频界面离开可视窗口时,出现小窗继续播放。
HTML5 video 标签的画中画功能只能实现用户点击才会出现,滚动事件不能触发画中画
所以只能自己手写视频小窗播放

在这里插入图片描述


一、实现原理

创建一个主视频元素(以下简称mainVideo),和一个用于小窗播放的视频元素(以下简称miniVideo)。miniVideo 可以用 fixed 固定定位到想要的位置,然后隐藏。两个 video 共用同一个 src 视频地址。待 mainVideo 随页面滚动要一定位置而离开可视区域后显示 miniVideo ,同步播放时间播放状态mainVideo 进入可视区后隐藏 miniVideo, 同步播放时间播放状态

二、实现过程

1.创建出所需的元素和数据

html 代码如下(css样式就不贴了):

<!-- 主视频 -->
<div class="video">
      <video
        :src="url"   data 中的数据
        controls
        ref="video"
        class="player"
        :poster="detail.cover || detail.coverUrl"
        @play="isVideoPlay = true"   记录主视频的播放状态,这里也可以不用记录,后面
        @pause="isVideoPlay = false"     通过videoElement.paused 判断
      ></video>
</div>
<!-- 小窗视频 -->
<div class="miniVideo" v-show="showMiniVideo">
	 <video
	   :src="url"
	   ref="miniVideo"
	   class="player"
	   :poster="detail.cover || detail.coverUrl"
	 ></video>
	 <!-- 遮罩,参考b站小窗 -->
	 <div class="mask">
	   <i
	     class="iconfont"
	     :class="{
	       'icon-icon_play': !isMiniVideoPlay,  通过miniVideo的播放状态显示不同的按钮,如:播放,暂停
	       'icon-zanting2': isMiniVideoPlay,
	     }"
	     @click="miniVideoChangePlay(!isMiniVideoPlay)"  改变播放状态函数
	   ></i>
	 </div>
</div>

2.监听 mainVideo

利用 Intersection Observer API 实现

API 参考1
API 参考2

video API

vue代码如下(我写在 mounted 生命周期函数中):

 // 滚动 出现小窗播放
 let video = this.$refs.video;
 let miniVideo = this.$refs.miniVideo;
 let videoOnce = false; // 是否执行过一次
 let miniVideoOnce = false;
 // 网页支持播放视频时
 video.oncanplay = () => {
   let observer = new IntersectionObserver((entries) => {
     // 视频窗口出现在可视窗口时
     if (entries[0].isIntersecting) {
       if (!videoOnce) {
         // 隐藏小窗
         this.showMiniVideo = false;
         // 同步播放时间
         video.currentTime = miniVideo.currentTime;
         // 同步播放状态
         this.isVideoPlay = this.isMiniVideoPlay;
         this.isVideoPlay ? video.play() : video.pause();
         // 暂停小窗
         this.isMiniVideoPlay = false;
         miniVideo.pause();
         // 因为会出现执行两次的情况,所有用这个变量来判断是否执行过一次
         // 执行过一次后要在执行else里的动作才会解除执行过一次的状态
         // 避免出现视频已暂停还执行暂停而报错,或其他问题
         videoOnce = true;
         miniVideoOnce = false;
       }
     } else {
       if (!miniVideoOnce) {
         this.showMiniVideo = true;
         miniVideo.currentTime = video.currentTime;
         this.isMiniVideoPlay = this.isVideoPlay;
         this.isVideoPlay = false;
         this.isMiniVideoPlay ? miniVideo.play() : miniVideo.pause();
         video.pause();
         miniVideoOnce = true;
         videoOnce = false;
       }
     }
   });
   observer.observe(video);
 };

总结

有个缺点就是 miniVideo 隐藏或显示时,会有一瞬间的卡顿。

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用Vue.js和一些现成的JavaScript库来实现上下滚动轮播视频轮播放窗口。以下是一些可能有用的步骤: 1. 安装和导入Vue.js和相关的JavaScript库,例如swiper.js和video.js。 2. 在Vue组件中创建一个包含视频列表的容器,使用CSS将其设置为所需的大小和形状,并将其设置为可滚动的。例如: ```html <template> <div class="video-container"> <div class="video-list"> <div class="video-item" v-for="video in videos" :key="video.id"> <video :src="video.src" class="video-js" controls></video> </div> </div> </div> </template> <script> import Swiper from 'swiper'; import 'swiper/css/swiper.css'; import videojs from 'video.js'; import 'video.js/dist/video-js.css'; export default { data() { return { videos: [ { id: 1, src: 'path/to/video1.mp4' }, { id: 2, src: 'path/to/video2.mp4' }, { id: 3, src: 'path/to/video3.mp4' }, // ... ] } }, mounted() { // 初始化swiper轮播组件 new Swiper('.video-container', { direction: 'vertical', slidesPerView: 'auto', }); // 初始化video.js视频播放组件 videojs(document.querySelectorAll('.video-js')); } } </script> <style> .video-container { width: 100%; height: 400px; /* 设置容器高度 */ overflow: hidden; /* 设置容器可滚动 */ } .video-list { display: flex; flex-direction: column; height: 100%; /* 设置视频列表高度 */ } .video-item { flex: 1; display: flex; align-items: center; justify-content: center; background-color: #f5f5f5; } </style> ``` 3. 在mounted生命周期钩子中初始化swiper轮播组件和video.js视频播放组件。 4. 根据需要调整CSS样式以适应您的设计需求。 注意:此处只是一个简单的示例,您需要根据您的实际需求进行调整。同时,视频播放可能会涉及到一些版权问题,需要您自行处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值