项目需求:滑动屏幕,切换短视频,实现类似抖音等短视频平台的视频切换效果
最终效果图:滑动屏幕自动加载,切换视频和产品图片
分析:video是原生标签,层级太高,在全屏的情况下,其他组件均会被遮挡,所幸小程序考虑到这一点出了cover-view,cover-image 标签,能覆盖在原生组件上,如果要实现 cover-view 之间的嵌套,按上下顺序排列即可。
切换视频思路:小视频我们默认是每次请求返回随机视频索引,每次请求返回十个或二十个,用setStorageSync 和 getStorageSync 配合进行本地存储,切换下一个则直接判断当前视频id在返回列表中的索引,如果索引到尾部,再发送请求去获取新一轮的数组,这样更有利于减少数据库查询和交互,提高切换速度。
具体实现:放一个video视频组件,隐藏相关控件,并设置自动播放,宽高因为有默认值,故需要实时获取设备信息用以自适应
.shadow_img{position: fixed;bottom:0;left: 0;height: 100%;width: 100%;}
js:
let App = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
show_text:'下拉加载更多',
video_width:wx.getSystemInfoSync().windowWidth,
video_height:wx.getSystemInfoSync().windowHeight+45,
voide_info:[],
show_next:true,
//检测是否有滑动行为
lastX: 0,
lastY: 0,
show_video:'',
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/*上一个视频*/
before_video:function(){
let _this = this,
array_length="",
suoyin="",
id_array="",
video_id="",
next_id="",
before_id="",
cache_id_str = wx.getStorageSync('id_str'); //获取储存的视频id数组
video_id = _this.data.video_id;
array_length = cache_id_str.length;
suoyin = _this.indexOf(cache_id_str,video_id);
wx.showToast({
title: "视屏切换中",
icon: 'loading',
duration: 1500,
});
//如果到到达最开始位置,则重新请求获取新一轮的索引
//_get是封装的get请求,勿直接复制,可自行搭建request请求
if(suoyin == 0){
App._get('video/rand', {}, function(result) {
wx.setStorageSync('id_str', result.data.result);
});
before_id = cache_id_str[0];
}else{
before_id = cache_id_str[suoyin-1];
}
//获取视频信息
App._get('video/listById', {id:before_id}, function(result) {
_this.setData({
goods:result.data.result.list[0].goods,
store_info:result.data.result.list[0].store,
voide_info:result.data.result.list[0],
video_id:before_id,
show_next:true
})
if(result.data.result.list[0].goods){
_this.setData({
show_goods:true
})
}else{
_this.setData({
show_goods:false
})
}
});
},
/*下一个视频*/
after_video:function(){
let _this = this,
array_length="",
suoyin="",
id_array="",
video_id="",
next_id="",
cache_id_str = wx.getStorageSync('id_str');
video_id = _this.data.video_id;
array_length = cache_id_str.length;
suoyin = _this.indexOf(cache_id_str,video_id);
wx.showToast({
title: "视屏切换中",
icon: 'loading',
duration: 1500,
});
if(suoyin != array_length-1){
next_id = cache_id_str[suoyin+1];
}else{
next_id = cache_id_str[0];
}
App._get('video/listById', {id:next_id}, function(result) {
_this.setData({
goods:result.data.result.list[0].goods,
store_info:result.data.result.list[0].store,
voide_info:result.data.result.list[0],
video_id:next_id,
show_next:true
})
if(result.data.result.list[0].goods){
_this.setData({
show_goods:true
})
}else{
_this.setData({
show_goods:false
})
}
});
},
indexOf:function(cache_id_str,video_id){
for(var i =0;i Math.abs(ty)) {
//左右方向滑动
if (tx < 0)
show_video = "before"
else if (tx > 0)
show_video = "after"
}else {
//上下方向滑动
if (ty < 0)
show_video = "after"
else if (ty > 0)
show_video = "before"
}
//将当前坐标进行保存以进行下一次计算
_this.data.lastX = currentX
_this.data.lastY = currentY
_this.data.show_video = show_video
},
/**
* 触摸结束
*/
bindtouchend:function(){
let _this = this;
console.log(_this.data.show_video);
if(_this.data.show_next == true){
_this.setData({
show_next:false
})
if(_this.data.show_video == "before"){
_this.before_video();
}else{
_this.after_video();
}
}
},
})
代码有待优化,其实中间的播放上一个和下一个可以整合到一起的,有点懒,网友可自行整合
划重点:
1,小程序获取设备信息高度的有两个:windowHeight 和 screenHeight 两个,但是因为一个是屏幕高度,一个是可使用窗口高度,因状态栏的存在获取的高度适中有点问题,经测试,只能在windowHeight的基础上增加45,才能勉强达到类似全屏的效果(扩展:如果隐藏了顶部状态栏,则可以直接用screenHeight高度即可实现)
2,小程序不支持 Object.keys() toString() indexOf() 这三个js语法,所以检测索引位置我自己封装了一下,代码有体现,请勿混淆