vue+Swiper模仿抖音页面播放
vue+Swiper模仿抖音页面播放开发需求又来了要模仿抖音做视频播放还要上下滑动。找了下资料Swiper可以。先上效果图,1是播放2是暂停3是滑动中原理主要是通过position:absolute 控制层级z-index来控制视频的播放,全局的video标签只有一个。上代码:<template><div class="wrap">...
·
vue+Swiper模仿抖音页面播放
开发需求又来了 要模仿抖音做视频播放还要上下滑动。 找了下资料Swiper可以。
先上效果图
原理主要是通过position:absolute 控制层级z-index来控制视频的播放,全局的video标签只有一个。
上代码:
<template>
<div class="wrap">
<div class="my-video works_wraps" v-show="show" :style="VideoItemHeightStyle">
<video class="video" :src="showVideo.Video.videoPath"
:poster="showVideo.Video.videoCover"
webkit-playsinline="true"
controlslist="nodownload"
playsinline="true"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
preload="metadata"
loop="loop"
@loadeddata="watchHandler"
ref="video"
>
<!--@pause="onpause"-->
<!--@play="onplay"-->
<source :src="showVideo.Video.videoPath" type="video/mp4">
</video>
</div>
<swiper :options="swiperOption" v-if="popularVideo.length > 0">
<swiper-slide v-for="(item, index) in popularVideo">
<div>
<div class="works_wrap" v-show="!item.show" @click="clickSwiper(index)">
<div class="poster">
<img class="pic" :src="item.Video.videoCover">
</div>
<div class="playWorks"></div>
<img class="play" src="../../../assets/images/find_play@2x.png" alt="">
</div>
<div class="side-bar">
<div class="avatar">
<img src="http://www.zhoubaba.club/assets/avatar/default.png" alt="" width="40" height="40"
@click.stop="chooseUser">
</div>
<div class="like" @click.stop="toggleLike(1)">
<img v-if="like" src="../../../assets/images/find_heart_r@2x.png" alt="">
<img v-if="!like" src="../../../assets/images/find_heart_w@2x.png" alt="">
<span class="likenum">2</span>
</div>
<div class="share" style="font-size: 30px;">
<img src="../../../assets/images/find_share@2x.png" alt="">
<span class="sharenum">5</span>
</div>
</div>
<div class="good-box" @click.stop="toGood">
<div class="good-img">
<img src="png" alt="">
</div>
<div class="text-wrap">
<p class="desc">紫色网格床垫紫色网格床垫紫色网格床垫</p>
<div><span class="price">¥1000.00</span><span class="old-price">原价:¥19946.00</span></div>
</div>
<div class="cart">
<img src="../../../assets/images/find_cart@2x.png" alt="">
</div>
</div>
<div class="play-video" v-if="item.show" @click="clickSwiper(index)"></div>
</div>
</swiper-slide>
</swiper>
</div>
</template>
<script>
import video_detail_controller from "./video_detail_controller";
export default video_detail_controller;
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
.works_wraps {
position: absolute;
z-index: 1;
left: 0;
top: 0;
right: 0;
height: 100%;
visibility: visible;
display: flex;
justify-content: center;
align-items: center;
background: none;
overflow: hidden;
.video {
object-fit: fill;
width: 100%;
height: 100%;
}
}
.up-enter-active, .up-leave-active {
transition: all .5s
}
.up-enter, .up-leave-to {
opacity: 0;
transform: translateY(100%);
}
.wrap {
background: #fff;
width: 100%;
height: 100%;
.icon-search {
position: absolute;
right: 10px;
top: 10px;
padding: 10px;
font-size: 24px;
z-index: 222;
}
.scroll-wrap {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}
.mack {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #000000;
opacity: 0.8;
z-index: 98;
display: none;
}
.works_wrap {
position: absolute;
z-index: 1;
left: 0;
top: 0;
right: 0;
height: 100%;
visibility: visible;
display: flex;
justify-content: center;
align-items: center;
background: none;
overflow: hidden;
.play {
position: absolute;
z-index: 11;
left: calc(55% - 3rem);
top: calc(50% - 3rem);
width: 3rem;
height: 3rem;
}
}
.swiper-slide .works_wrap .poster {
/*background: #000000;*/
position: relative;
z-index: 10;
width: 100%;
height: 100%;
visibility: visible;
display: flex;
justify-content: center;
align-items: center;
}
.swiper-slide .works_wrap .poster .pic {
width: 100%;
height: 100%;
vertical-align: middle;
}
.swiper-slide .works_wrap .playWorks {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 9;
background-size: auto 50px;
background: #fff;
}
.good-box {
position: absolute;
display: flex;
z-index: 10;
left: 0;
bottom: 5rem;
width: 85%;
height: 5rem;
background: #FFFFFF;
border-radius: 0 12px 12px 0;
padding: .5rem .8rem;
.good-img {
margin-right: .5rem;
width: 4rem;
height: 4rem;
flex: 0 0 4rem;
img {
width: 100%;
height: 100%;
}
}
.text-wrap {
flex: 1;
display: flex;
flex-direction: column;
text-align: left;
line-height: 2rem;
width: 70%;
font-weight: bold;
}
.desc {
font-size: 16px;
color: #333333;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.price {
font-size: 16px;
color: #f15353;
margin-right: .5rem;
}
.old-price {
text-decoration: line-through;
color: #8c8c8c;
font-size: 12px;
}
.cart {
flex: 0 0 1.5rem;
width: 1.5rem;
height: 1.5rem;
line-height: 5rem;
img {
width: 100%;
height: 100%;
}
}
}
.side-bar {
position: absolute;
z-index: 10;
right: 15px;
bottom: 7rem;
display: flex;
flex-direction: column;
height: 160px;
justify-content: space-between;
.avatar {
position: relative;
border-radius: 50%;
background: none;
border: 1px solid rgb(232, 232, 233);
img {
border-radius: 50%;
}
.follow {
text-align: center;
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%) translateY(50%);
width: 16px;
height: 16px;
font-size: 16px;
border-radius: 50%;
background: rgb(252, 52, 93);
}
}
}
.like {
position: relative;
img {
width: 40px;
height: 40px;
}
.likenum {
font-size: 10px;
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%) translateY(100%);
color: rgb(232, 232, 233);
}
}
.share {
position: relative;
img {
width: 40px;
height: 40px;
}
.sharenum {
font-size: 10px;
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%) translateY(100%);
color: rgb(232, 232, 233);
}
}
.side-bar > div {
width: 40px;
height: 40px;
font-size: 40px;
color: rgb(232, 232, 233);
transition: all .3s;
}
.play-video {
position: absolute;
z-index: 9;
top: 0;
width: 100%;
height: 100%;
left: 0;
}
</style>
import { Toast, MessageBox } from "mint-ui";
let videoFirst = 0; //第一次初始化
export default {
data() {
let that = this;
return {
swiperOption: {
direction: 'vertical',
observer: true,
width: window.innerWidth,
height : window.innerHeight,
watchOverflow: true,
autoHeight: true,
autoplay: false,
pagination: false,
on: {
reachEnd (){
if(videoFirst === 1){
that.popularVideo.push({"Video":{"userId":"4617f00b-295d-48b4-8d06-70a92b5e32e5","userAvatar":"/assets/avatar/default.png","userNickname":"95d-4","videoId":"d0a5e902-2912-45f6-848e-2f3d874519f4","videoCover":"http://image2.pearvideo.com/main/20181121/11335845-200032-0.png","videoDesc":"11月19日,盖茨发表长文向大家推荐美剧《硅谷》,称其是为数不多的好作品,自己惊讶于很少有现代流行文化作品能很好地向外界呈现硅谷。盖茨还放话,只要它续更,我愿意一直追下去!","videoPath":"https://dev6.yunzmall.com/attachment/videos/12/2019/07/Uq5OQi89qxi9zA95X9g5Uu8gUgA8gG.mp4"},"WSLCNum":{"shareNum":"3","watchNum":"27","commentNum":"17","likeNum":"12"}});
}
console.log(that.popularVideo,"popularVideo");
// 手指触碰拖动最后一张时执行
},
slideChangeTransitionEnd (){
// console.log(this.realIndex,"this");
that.$refs.video.pause();
that.showVideo = that.popularVideo[this.realIndex];
if(this.realIndex === 0){
that.popularVideo[this.realIndex].show = false;
that.popularVideo[this.realIndex+1].show = false;
} else {
that.popularVideo[this.realIndex-1].show = false;
that.popularVideo[this.realIndex].show = false;
that.popularVideo[this.realIndex+1].show = false;
}
that.show = false;
// that.clickSwiper(this.realIndex);
//切换结束时,告诉我现在是第几个slide
},
},
},
popularVideo: [],
showVideo: {"Video":{"userId":"4617f00b-295d-48b4-8d06-70a92b5e32e5","userAvatar":"/assets/avatar/default.png","userNickname":"95d-4","videoId":"d0a5e902-2912-45f6-848e-2f3d874519f4","videoCover":"http://image2.pearvideo.com/main/20181121/11335845-200032-0.png","videoDesc":"11月19日,盖茨发表长文向大家推荐美剧《硅谷》,称其是为数不多的好作品,自己惊讶于很少有现代流行文化作品能很好地向外界呈现硅谷。盖茨还放话,只要它续更,我愿意一直追下去!","videoPath":"https://dev4.yunzmall.com/attachment/videos/8/2019/07/B745SC4Rj073340O85rs54v04g5vt4.mp4"},"WSLCNum":{"shareNum":"3","watchNum":"27","commentNum":"17","likeNum":"12"}},
show: false,
like: false,
likeNum: 0,
isPlay: false,
amount_id: "",
};
},
activated() {
window.scroll(0, 0);
},
mounted(){
setTimeout(()=>{
this.popularVideo = [{"Video":{"userId":"4617f00b-295d-48b4-8d06-70a92b5e32e5","userAvatar":"/assets/avatar/default.png","userNickname":"95d-4","videoId":"d0a5e902-2912-45f6-848e-2f3d874519f4","videoCover":"https://image.pearvideo.com/cont/20181121/cont-1480090-11711388.jpg","videoDesc":"11月19日,盖茨发表长文向大家推荐美剧《硅谷》,称其是为数不多的好作品,自己惊讶于很少有现代流行文化作品能很好地向外界呈现硅谷。盖茨还放话,只要它续更,我愿意一直追下去!","videoPath":"https://dev4.yunzmall.com/attachment/videos/8/2019/07/B745SC4Rj073340O85rs54v04g5vt4.mp4"},"WSLCNum":{"shareNum":"3","watchNum":"27","commentNum":"17","likeNum":"12"}},{"Video":{"userId":"4617f00b-295d-48b4-8d06-70a92b5e32e5","userAvatar":"/assets/avatar/default.png","userNickname":"95d-4","videoId":"d0a5e902-2912-45f6-848e-2f3d874519f4","videoCover":"http://image2.pearvideo.com/main/20181121/11335845-200032-0.png","videoDesc":"11月19日,盖茨发表长文向大家推荐美剧《硅谷》,称其是为数不多的好作品,自己惊讶于很少有现代流行文化作品能很好地向外界呈现硅谷。盖茨还放话,只要它续更,我愿意一直追下去!","videoPath":"https://dev6.yunzmall.com/attachment/videos/12/2019/07/el9AIwcHBALAo2w9b29XXW1xBz9727.mp4"}},{"Video":{"userId":"4617f00b-295d-48b4-8d06-70a92b5e32e5","userAvatar":"/assets/avatar/default.png","userNickname":"95d-4","videoId":"d0a5e902-2912-45f6-848e-2f3d874519f4","videoCover":"http://image2.pearvideo.com/main/20181121/11335845-200032-0.png","videoDesc":"11月19日,盖茨发表长文向大家推荐美剧《硅谷》,称其是为数不多的好作品,自己惊讶于很少有现代流行文化作品能很好地向外界呈现硅谷。盖茨还放话,只要它续更,我愿意一直追下去!","videoPath":"https://dev5.yunzmall.com/attachment/videos/2/2019/05/LszWwVEewJeWWWcZ46nbcwNCqEWJqQ.mp4"},"WSLCNum":{"shareNum":"3","watchNum":"27","commentNum":"17","likeNum":"12"}}]
},300);
videoFirst = 1;
},
computed: {
VideoItemHeightStyle() {
let clientWidth = window.innerWidth;
let clientHeight = window.innerHeight;
return {
height: clientHeight + "px",
width: clientWidth + "px"
};
}
},
methods: {
clickSwiper(index) {
if (this.popularVideo[index].show && this.amount_id === this.popularVideo[index].Video.videoId) {
this.show = false;
this.popularVideo[index].show = false;
this.$refs.video.pause();
return;
}
this.show = true;
this.amount_id = this.popularVideo[index].Video.videoId;
this.$set(this.popularVideo[index], "show", true);
this.$refs.video.play();
// console.log(this.$refs.video);
},
watchHandler() {
// this.$axios
}
}
};
主要参考了这几篇博客:
https://www.cnblogs.com/mihoutaoguniang/p/5958394.html 基于html5,父级块中添加video,不能全屏播放的问题解决。
https://www.jianshu.com/p/5a770e984d5c 如何退出微信X5同层播放器?
http://smartued.com/index.php/FE/WeChatHtml5video.html H5 微信播放视频全屏问题踩坑实录
https://www.xuanfengge.com/h5-video-play.html 移动端HTML5视频播放优化实践
还有Swiper4的官方文档
更多推荐
已为社区贡献25条内容
所有评论(0)