适用场景:
循环播放视频, 广告,等
我这里用一个签到送积分场景广告视频来实现该效果:
我们先来看一下效果:
wxml
<!--pages/daily-attendance/index.wxml-->
<view class="daily-attendance-top">
<image class="daily-attendance-img" src="http://ico.dongtiyan.com/tu-23.png"></image>
<view class="daily-attendance-desc">
<text>您已经累计签到</text>
<text> {{count}} </text>
<text>天, </text>
<text>获得</text>
<text> {{getCount}} </text>
<text>星球算力</text>
</view>
</view>
<view class="daily-attendance-con">
<!-- 日历 S -->
<view class="calendar">
<view class="daily-attendance-con-top">
<image src="http://ico.dongtiyan.com/tu-25.png" bindtap="handleCalendar" data-handle="prev"></image>
<view>{{cur_year || '--'}}年{{cur_month || '--'}}月</view>
<image src="http://ico.dongtiyan.com/tu-24.png" bindtap="handleCalendar" data-handle="next"></image>
</view>
<view class="period">
<block wx:for="{{weeks_ch}}" wx:for-idx="{{index}}" wx:key="index">
<view>{{item}}</view>
</block>
</view>
<view class="days">
<!-- 列 -->
<view class="culumns" wx:for="{{days.length/7}}" wx:for-index="i" wx:key="i">
<view wx:for="{{days}}" wx:for-index='j' wx:key="j">
<!-- 行 -->
<view class="rows" wx:if="{{j/7 == i}}">
<view class="rows" wx:for="{{7}}" wx:for-index="k" wx:key="k">
<!-- 每个月份的空的单元格 -->
<view class="cell" wx:if="{{days[j+k].date == null}}">
<text decode="{{true}}"> </text>
</view>
<!-- 每个月份有数字的单元格 -->
<view class="cell" wx:else>
<!-- 当前日期已签到 -->
<view wx:if="{{days[j+k].isSign == true}}" style="background-color: #FFB21E" class="cell">
<block wx:if="{{days[j+k].date == current_date}}">
<text>今</text>
</block>
<block wx:else>
<text>{{days[j+k].date}}</text>
</block>
</view>
<!-- 当前日期未签到 -->
<view wx:else>
<block wx:if="{{days[j+k].date == current_date}}">
<text>今</text>
</block>
<block wx:else>
<text>{{days[j+k].date}}</text>
</block>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 日历 E -->
<!-- 签到描述 S -->
<view class="sign-in-desc">每次成功签到赠送1体星球算力</view>
<!-- 签到描述 E -->
<!-- 签到按钮 S -->
<view class="sign-in-btn">
<block wx:if="{{defaults != 1}}">
<view class="sign-in" bindtap="chooseSignIn">签到</view>
</block>
<block wx:else>
<view class="sign-in">已签到</view>
</block>
</view>
<!-- 签到按钮 E -->
<!-- 签到规则 S -->
<view class="sign-in-rules">
<view>签到规则</view>
<view>1、每日签到可领取1星球算力;</view>
<view>2、签到打卡积分规则</view>
<view>①每日签到增加1分,当日重复签到不会重复计数</view>
<view>②连续签到7天会有额外算力,如:第7天,总积分为7分,额外增加3分,其余连续签到天数均无额外积分;</view>
<view>3、签到打卡奖励兑换规则</view>
<view>①签到打卡奖励兑换方法 在懂体验线上积分商城选择相应商品进行兑换购买,兑换成功后我们会在三个工作日邮递寄出。</view>
</view>
<!-- 签到规则 E -->
<!-- 装饰 S -->
<image class="decorate" src="http://ico.dongtiyan.com/tu-27.png"></image>
<!-- 装饰 E -->
</view>
<!-- 签到视频 S -->
<view class="mask-layer" hidden="{{signInDefaults}}"></view>
<view class="sign-in-video" hidden="{{signInDefaults}}">
<view class="total-time">{{currentTime}}</view>
<video class="video" id="video" src="{{video}}" autoplay="{{signInDefaults === false? true: false}}" controls="{{controls}}" loop="{{loop}}"></video>
<block wx:if="{{countDownNum != 0}}">
<view class="get-btn">{{countDownNum}} 秒后可领取</view>
</block>
<block wx:else>
<view class="get-btn" bindtap="chooseImmediatelyReceive">立即领取</view>
</block>
</view>
<!-- 签到成功 S -->
<view class="mask-layer" hidden="{{succeedDefaults}}"></view>
<view class="sign-in-succeed" hidden="{{succeedDefaults}}">
<view class="succeed-img">{{signInSuccessfully}}</view>
<view class="succeed-desc">
<text>每日签到可获得</text>
<text> 1 </text>
<text>星球算力</text>
</view>
<view class="confirm-btn" bindtap="chooseConfirm">确定</view>
</view>
<!-- 签到成功 E -->
wxss
.daily-attendance-top {
background: linear-gradient(#feb305, #fe850f);
text-align: center;
}
.daily-attendance-img {
height: 62rpx;
width: 275rpx;
margin-top: 40rpx;
}
.daily-attendance-desc {
font-size: 28rpx;
color: #A04B0C;
height: 108rpx;
background: linear-gradient(#FFAF4A, #FFD156);
border-radius: 20rpx;
margin: 59rpx 30rpx 0;
padding-top: 35rpx;
}
.daily-attendance-desc text:nth-child(2), .daily-attendance-desc text:nth-child(5) {
color: #F73A3F;
}
/* 打卡日历 */
.daily-attendance-con {
width: 100%;
background: #FDE28D;
position: absolute;
}
.calendar {
width: 92%;
background: #FFFFFF;
border-radius: 20rpx;
margin: -37rpx 30rpx 0;
position: relative;
z-index: 99;
}
.daily-attendance-con-top {
display: flex;
justify-content: center;
align-items: center;
padding: 38rpx 24rpx 51rpx;
}
.daily-attendance-con-top image {
width: 9rpx;
height: 17rpx;
}
.daily-attendance-con-top view {
margin: 0 57rpx;
font-size: 24rpx;
color: #A04B0C;
}
.period {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 40rpx 20rpx;
font-size: 24rpx;
color: #E1A172;
}
.days {
padding: 27rpx 27rpx 0;
border-radius: 20rpx;
color: #A04B0C;
font-size: 24rpx;
}
.culumns {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.culumns .rows {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 27rpx;
}
.culumns .rows .cell {
width: 48rpx;
height: 48rpx;
text-align: center;
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
}
/* 签到描述 */
.sign-in-desc {
font-size: 24rpx;
color: #A04B0C;
padding-top: 26rpx;
text-align: center;
}
.sign-in {
background-image: url("http://ico.dongtiyan.com/tu-26.png");
background-size: cover;
width: 549rpx;
height: 109rpx;
text-align: center;
line-height: 95rpx;
margin: 69rpx auto 63rpx;
font-size: 32rpx;
color: #FFFFFF;
}
/* 签到规则 */
.sign-in-rules {
background: #F7D66F;
margin: 0 30rpx 0;
border-radius: 20rpx;
padding: 40rpx;
font-size: 24rpx;
color: #A04B0C;
}
.sign-in-rules view:nth-child(1) {
margin-bottom: 30rpx;
}
.sign-in-rules view:nth-child(2) {
margin-bottom: 26rpx;
}
.sign-in-rules view:nth-child(4) {
margin-left: 38rpx;
}
.sign-in-rules view:nth-child(5) {
margin-left: 38rpx;
margin-bottom: 26rpx;
}
.sign-in-rules view:nth-child(7) {
margin-left: 38rpx;
}
.decorate {
width: 100%;
height: 139rpx;
}
/* 签到视频 */
.sign-in-video {
position: fixed;
z-index: 999;
left: 142rpx;
bottom: 328rpx;
}
.video {
width: 467rpx;
height: 518rpx;
border-radius: 20rpx;
}
video::-webkit-media-controls-timeline {
display: none;
}
.get-btn {
margin: 36rpx 32rpx 0;
background-image: url("http://ico.dongtiyan.com/tu-26.png");
background-size: 100% 100%;
height: 91rpx;
text-align: center;
line-height: 85rpx;
color: #FFFFFF;
font-size: 32rpx;
}
.total-time {
position: absolute;
z-index: 999;
color: #FFFFFF;
font-size: 20rpx;
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
text-align: center;
border-radius: 50%;
background: #000000;
opacity: 0.5;
right: 25rpx;
top: 26rpx;
}
/* 签到成功 */
.sign-in-succeed {
width: 467rpx;
height: 518rpx;
position: fixed;
z-index: 999;
left: 142rpx;
bottom: 328rpx;
border: 4rpx solid #FAC663;
background: #FFFFFF;
border-radius: 20rpx;
justify-content: center;
}
.succeed-img {
background-image: url('http://ico.dongtiyan.com/tu-28.png');
background-size: cover;
width: 322rpx;
height: 95rpx;
color: #FFFFFF;
font-size: 28rpx;
text-align: center;
margin: 47rpx auto 0;
line-height: 60rpx;
}
/* 签到描述 */
.succeed-desc {
font-size: 24rpx;
color: #000000;
text-align: center;
margin: 101rpx 0 126rpx;
}
.succeed-desc text:nth-child(2) {
color: #F73A3F;
}
/* 确定 */
.confirm-btn {
background-image: url('http://ico.dongtiyan.com/tu-26.png');
background-size: 100% 100%;
width: 311rpx;
height: 91rpx;
color: #FFFFFF;
text-align: center;
font-size: 32rpx;
line-height: 80rpx;
margin: 0 auto;
}
js
// pages/daily-attendance/index.js
const app = getApp()
const format = require('../../utils/util.js');
//打卡日历页面
var util = require('../../utils/util.js');
var timers
Page({
/**
* 页面的初始数据
*/
data: {
objectId: '',
cur_year: 0, // 年
cur_month: 0, // 月
current_date: 0, // 当前日
weeks_ch: [], // 周期
count: 0, // 签到天数
signInSuccessfully: "", // 签到状态
getCount: 0, // 获得星球算力
days: [], // 月日期列表
signUp: [{
date: '2020/6/21',
isSign: false,
}, {
date: '2020/6/20',
isSign: false,
}], //
video: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4", // 广告视频
autoplay: false, // 自动播放
controls: false, // 隐藏控件
loop: true, // 是否循环
timers: "", // 视频定时器
currentTime: 5, // 视频播放总时长
currentTimes: '',
timer: '', // 定时器
countDownNum: 5, // 倒计时初始值
signInDefaults: true, // 签到默认
succeedDefaults: true, // 成功默认
defaults: 0, // 默认按钮
},
/**
* 获取签到状态
*/
getsignInState: function () {
var _this = this;
wx.request({
url: app.globalData.apiUrl + 'api/user/user/sign_log',
data: {
token: wx.getStorageSync('token')
},
method: "POST",
header: app.globalData.header,
success: function (res) {
console.log(res)
_this.setData({
signUp: res.data.data,
defaults: res.data.status
})
_this.onJudgeSign()
},
fail: function (err) {
wx.showToast({
title: '请求超时, 请稍后再试~',
icon: 'none'
})
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
objectId: 1
})
/**
* 获取当前年月
*/
const date = new Date();
const cur_year = date.getFullYear();
const cur_month = date.getMonth() + 1;
const weeks_ch = ['日', '一', '二', '三', '四', '五', '六'];
this.calculateEmptyGrids(cur_year, cur_month);
this.calculateDays(cur_year, cur_month);
const current_date = date.getDate() < 10 ? '0' + date.getDate() : date.getDate(); //获取当前日
/**
* 获取当前用户当前任务的签到状态
*/
this.getsignInState()
this.setData({
cur_year: cur_year,
cur_month: cur_month,
weeks_ch: weeks_ch,
current_date: current_date
})
},
/**
* 获取当月共多少天
*/
getThisMonthDays: function (year, month) {
return new Date(year, month, 0).getDate()
},
/**
* 获取当月第一天星期几
*/
getFirstDayOfWeek: function (year, month) {
return new Date(Date.UTC(year, month - 1, 1)).getDay();
},
/**
* 计算当月1号前空了几个格子, 把它填充在days数组的前面
*/
calculateEmptyGrids: function (year, month) {
var that = this;
/**
* 计算每个月时要清零
*/
that.setData({
days: []
});
const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
if (firstDayOfWeek > 0) {
for (let i = 0; i < firstDayOfWeek; i++) {
var obj = {
date: null,
isSign: false
}
that.data.days.push(obj);
}
this.setData({
days: that.data.days
});
/**
* 清空
*/
} else {
this.setData({
days: []
});
}
},
/**
* 回执当月天数占的格子, 并把它放到days数组中
*/
calculateDays: function (year, month) {
var that = this;
const thisMonthDays = this.getThisMonthDays(year, month);
for (let i = 1; i <= thisMonthDays; i++) {
var obj = {
date: i,
isSign: false
}
that.data.days.push(obj);
}
this.setData({
days: that.data.days
});
},
/**
* 切换控制年月,上一个月,下一个月
*/
handleCalendar: function (e) {
const handle = e.currentTarget.dataset.handle;
const cur_year = this.data.cur_year;
const cur_month = this.data.cur_month;
if (handle === 'prev') {
let newMonth = cur_month - 1;
let newYear = cur_year;
if (newMonth < 1) {
newYear = cur_year - 1;
newMonth = 12;
}
this.calculateEmptyGrids(newYear, newMonth);
this.calculateDays(newYear, newMonth);
this.getsignInState();
this.setData({
cur_year: newYear,
cur_month: newMonth
})
} else {
let newMonth = cur_month + 1;
let newYear = cur_year;
if (newMonth > 12) {
newYear = cur_year + 1;
newMonth = 1;
}
this.calculateEmptyGrids(newYear, newMonth);
this.calculateDays(newYear, newMonth);
this.getsignInState();
this.setData({
cur_year: newYear,
cur_month: newMonth
})
}
},
// 匹配判断当月与当月哪些日子签到打卡
onJudgeSign: function () {
var _this = this;
var signs = _this.data.signUp;
var daysArr = _this.data.days;
for (var i = 0; i < signs.length; i++) {
var time = format.formatTime(signs[i].add_time, 'Y-M-D')
var current = new Date(time.replace(/-/g, "/"));
var year = current.getFullYear(); // 年
var month = current.getMonth() + 1; // 月
var day = current.getDate(); //日
day = parseInt(day);
for (var j = 0; j < daysArr.length; j++) {
if (year == _this.data.cur_year && month == _this.data.cur_month && daysArr[j].date == day && daysArr[j].isSign == false) {
daysArr[j].isSign = true;
var count = this.data.count + 1
var getCount = this.data.getCount + 1
}
}
_this.setData({
days: daysArr,
count: count,
getCount: getCount,
})
// console.log(this.data.days)
}
},
/**
* 签到
*/
chooseSignIn: function () {
this.setData({
signInDefaults: !this.data.signInDefaults,
})
this.countDown()
this.videoPlay()
},
/**
* 立即领取
*/
chooseImmediatelyReceive: function () {
var _this = this;
if (!wx.getStorageSync('token')) {
wx.showModal({
title: '提示',
content: '请先授权登录',
cancelColor: 'cancelColor',
success: function (res) {
if (res.confirm) {
wx.navigateTo({
url: '../my/my-login/index',
})
}
}
})
} else {
wx.request({
url: app.globalData.apiUrl + 'api/user/user/user_sign',
data: {
token: wx.getStorageSync('token')
},
method: "POST",
header: app.globalData.header,
success: function (res) {
_this.setData({
signInSuccessfully: res.data.msg
})
},
fail: function (err) {
wx.showToast({
title: "请求超时, 请稍后再试~",
icon: 'none'
})
}
})
this.setData({
signInDefaults: !this.data.signInDefaults,
succeedDefaults: !this.data.succeedDefaults
})
this.videoStop()
clearInterval(this.data.timers)
}
},
/**
* 领取确认
*/
chooseConfirm: function () {
var _this = this;
this.setData({
succeedDefaults: !this.data.succeedDefaults,
defaults: !this.data.defaults
})
this.onJudgeSign()
},
/**
* 倒计时
*/
countDown: function () {
var _this = this;
var countDownNum = _this.data.countDownNum; // 获取倒计时初始值
// 如果将定时器设置在外面,那么用户就看不到countDownNum的数值动态变化,所以要把定时器存进data里面
_this.setData({
timer: setInterval(function () { // 这里把setInterval赋值给变量名为timer的变量
//每隔一秒countDownNum就减一, 实现同步
countDownNum--;
// 然后把countDownNum存进data, 好让用户时间在倒计时
_this.setData({
countDownNum: countDownNum
})
if (countDownNum == 0) {
// 这里特别要注意,计时器是始终一直在走的,如果你的时间为0, 那么就要关掉定时器,不然相当好性能
// 因为timer是存在data里面的, 所以在关掉是,也要在data里取出后再关闭
clearInterval(_this.data.timer)
}
}, 1000)
})
},
/**
* 视频播放
*/
videoPlay: function () {
var videoplay = wx.createVideoContext('video')
videoplay.play()
this.videoCountDown()
},
/**
* 视频关闭
*/
videoStop: function () {
var videostop = wx.createVideoContext('video')
videostop.stop()
},
/**
* 视频倒计时
*/
videoCountDown: function () {
var _this = this;
var currentTime = this.data.currentTime;
timers = setTimeout(function () { // 这里把setInterval赋值给变量名为timer的变量
// 每隔一秒countDownNum就减一, 实现同步
currentTime--;
// 然后把countDownNum存进data, 好让用户时间在倒计时
_this.setData({
currentTime: currentTime
})
if(currentTime == -1) {
_this.setData({
currentTime: 5
})
}
this.videoCountDown()
}.bind(this), 1000, _this)
},
})
以上就是所有代码,有什么更好的实现方式请下面留言,互相交流,谢谢
如果对你有帮助,请关注一下博主的小程序支持一下, 在此谢谢了