先看整体效果
需求分析:
①要求水印每隔10秒钟出现一次
②水印每次出现的高度为随机值
②切换全屏也是一样
那么我们字幕可以给水印定位,然后充分用到定时器改变left值来完成
shuiyin() {
// 获取屏幕宽和高
var windowWidth = wx.getSystemInfoSync().windowWidth
var screenHeight = wx.getSystemInfoSync().screenHeight
console.log('屏幕宽和高',windowWidth, screenHeight);
clearInterval(this.data.test_left);
var flag = true; // 切换条件
var start = 0; // 起始值
let that = this;
// 获取动态水印显示什么内容
let nickName = wx.getStorageSync("userInfo").nickName;
let phone = wx.getStorageSync("phone") || "";
const date = new Date();
const y = date.getFullYear();
let m = date.getMonth() + 1;
m = m < 10 ? `0${m}` : m;
let d = date.getDate();
d = d < 10 ? `0${d}` : d;
let _timer = y + "-" + m + "-" + d;
// 判断是否是全屏状态来确定水印要运行的宽度
if (!that.data.controls_fullScreen) {
var num = windowWidth; // 加到屏幕宽度最大值(非全屏)
var _zNnm = Math.floor(Math.random() * (200 - 20 + 1)) + 10 // 随机高度
} else {
var num = screenHeight; // 全屏状态下手机高度就是水印要走的宽度
var _zNnm = Math.floor(Math.random() * ((windowWidth - 50) - 20 + 1)) + 10;
}
function test() {
if (flag) {
++start;
// 水印滚到了屏幕的最边界处停止滚动,并且计时10秒
if (start == num) {
flag = false;
clearInterval(that.data.test_left)
// 水印走完后开始计时10秒
that._waterMark()
}
}
that.setData({
left: start,
top: _zNnm,
shuiying_cont: nickName + "-" + phone + "-" + _timer,
});
}
this.data.test_left = setInterval(function () {
test(); // 每秒刷新30帧
}, 1000 / 30);
},
判断是否是全屏状态
// 微信小程序video组件内部方法,监听是否全屏
bindfullscreenchange(e) {
console.log(e.detail.detail.fullScreen);
let fullScreen = e.detail.detail.fullScreen; //值true为进入全屏,false为退出全屏
if (!fullScreen) {
//退出全屏
this.setData({
controls_fullScreen: false,
});
} else {
//进入全屏
this.setData({
controls_fullScreen: true,
});
}
this.shuiyin();
},
计时每隔10秒种出现一次水印
// 每隔10秒重新调用一次水印
_waterMark() {
setTimeout(()=> {
this.shuiyin()
},10000)
},
性能问题
此水印采用定时器每秒刷新30帧,性能消耗非常大,可能导致页面卡顿,体验很差
那么我们可以改良一下,丢弃定时器每秒刷新30帧,采用css动画来实现
实现思路。让每一次动画只执行完成一次就移除样式,js开始计时10秒重新添加当前动画样式,小编这里非全屏与动画保持一致 15秒后开始计时等待10秒下次出现的时间。全屏则为25秒后等动画结束开始等待10秒(与动画同步)
css部分
/* 非全屏状态下-15秒内匀速滚动完 */
.shuiyin_style {
opacity: 0.45;
white-space: nowrap;
z-index: 998;
position: absolute;
color: #b9b8b8;
font-size: 24rpx;
animation: mymove 15s linear;
/*Safari 和 Chrome:*/
-webkit-animation: mymove 15s linear;
}
/* 全屏状态下-25秒内匀速滚动完 */
.shuiyin_style_y {
opacity: 0.45;
white-space: nowrap;
z-index: 998;
position: absolute;
color: #b9b8b8;
font-size: 24rpx;
animation: mymove 25s linear;
/*Safari 和 Chrome:*/
-webkit-animation: mymove 25s linear;
}
/* 动画帧 */
@keyframes mymove {
from {
left: 0%
}
to {
left: 100%
}
}
/*Safari 和 Chrome:*/
@-webkit-keyframes mymove {
from {
left: 0%
}
to {
left: 100%
}
}
wxml部分
<!-- 非全屏状态下 -->
<text wx:if="{{!controls_fullScreen}}" class="{{shuiyin_style_display == true ? 'shuiyin_style' : 'shuiyin_display'}}" style="top: {{top}}px;">{{shuiying_cont}}</text>
<!-- 全屏状态下 -->
<text wx:else="{{controls_fullScreen}}" class="{{shuiyin_style_display == true ? 'shuiyin_style_y' : 'shuiyin_display'}}" style="top: {{top}}px;">{{shuiying_cont}}</text>
js部分
shuiyin() {
// 切换视频或者等先清除掉定时器
clearTimeout(this.data.__sy1)
clearTimeout(this.data.__sy2)
// 获取屏幕宽和高
var windowWidth = wx.getSystemInfoSync().windowWidth
var screenHeight = wx.getSystemInfoSync().screenHeight
console.log('屏幕宽和高', windowWidth, screenHeight);
let that = this;
// 获取当前用户信息水印显示内容
let nickName = wx.getStorageSync("userInfo").nickName;
let phone = wx.getStorageSync("phone") || "";
const date = new Date();
const y = date.getFullYear();
let m = date.getMonth() + 1;
m = m < 10 ? `0${m}` : m;
let d = date.getDate();
d = d < 10 ? `0${d}` : d;
let _timer = y + "-" + m + "-" + d;
if (!that.data.controls_fullScreen) {
var _zNnm = Math.floor(Math.random() * (200 - 20 + 1)) + 10
} else {
var _zNnm = Math.floor(Math.random() * (( windowWidth - 50) - 20 + 1)) + 10;
}
that.setData({
top: _zNnm,
shuiying_cont: nickName + "-" + phone + "-" + _timer,
shuiyin_style_display: true
});
if (!this.data.controls_fullScreen) { // 非全屏下调用
this.data.__sy1 = setTimeout(()=> {
that.setData({
shuiyin_style_display: false
},()=>{
console.log("开始计时下次水印出现的时间~非全屏");
that._waterMark()
});
},15000)
} else { //全屏下调用
this.data.__sy1 = setTimeout(()=> {
that.setData({
shuiyin_style_display: false
},()=>{
console.log("开始计时下次水印出现的时间~全屏");
that._waterMark()
});
},25000)
}
},
_waterMark() {
this.data.__sy2 = setTimeout(()=> {
this.shuiyin()
},10000)
},
结束语
至此两种实现方式就完成了,css实现的效果性能要比定时器性能提升一倍不止,而且丝滑流畅
在h5网页端缺点(微信小程序较完美)
倘若再 h5端
ios全屏下,水印层级权限过低,导致无法显示,(微信小程序较完美)有解决办法还请积极留言~