记录经过?小功能点
简介
小程序页面增加水印
效果
因为所有页面都要加水印,所以肯定是要用自定义组件实现。
思考路程
第一种
最开始考虑的是canvas生成图片,转换成base64做一张背景图,然后才了解到水印不能直接在元素上作为背景作为页面的最底层,很容易被其他东西覆盖,所以水印一定是要要fixed在页面的最顶层。 canvas生成图片,但是要借用其他插件转成base64
第二种
可以采用DOM元素靠样式实现,也不需要依赖插件,感觉这个更加的不错。于是就代码撸起来,然后每个页面都能有水印了,看起来是成功了。但是!!当切换登录人以后发现有的页面水印上的登录人怎么还是上一个登录人的信息呢?原来component的生命周期事件是依赖于所在页面的,如果页面从未销毁过,Component有些事件就不会再次触发了。于是,我产生了第一种思路,如何能让组件监听到所在页面的声明周期,看小程序文档确实有这样的方法,但是依赖的基础库版本比较高,那用户是低版本基础库岂不是不会生效了。emmmm再想想,那登录的时候保证让打开过的所有页面销毁就可以了啊,当前跳转登录页使用的方法是wx.navigateTo(会保留当前页面,然后跳转,所以有些页面不销毁,组件获取用户id的方法就不会触发第二次了),那退出登录的时候调用wx.reLaunch(关闭所有页面,然后跳转页面)方法就ok
实现代码
- 使用canvas画图,使用upng.js插件将图片转化成base64 这里需要引入一些转base64的js,upng.js以及upng.js的依赖pako.min.js
import UPNG from './upng';
const CANVAS = 'water_mark_id';
Component({
data: {
text: '请勿外传',
imgBase64: '',
color:'rgba(0,0,0,0.5)'
},
attached() {
const { text, color } = this.data;
const ctx = wx.createCanvasContext(CANVAS, this);
ctx.rotate((335 * Math.PI) / 180);
ctx.setFontSize(20);
ctx.setFillStyle(color);
ctx.fillText(text, 0, 100);
ctx.draw(false, () => {
setTimeout(() => {
wx.canvasGetImageData({
canvasId: CANVAS,
x: 0,
y: 0,
width: 120,
height: 100,
success: (res) => {
const pngData = UPNG.encode([res.data.buffer], res.width, res.height);
const base64 = wx.arrayBufferToBase64(pngData);
this.setData({ imgBase64: 'data:img/jpg;base64,' + base64 });
},
fail: (err) => {
console.log(err);
}
}, this);
}, 2000);
});
}
});
复制代码
json文件
{
"component": true
}
复制代码
wxml文件
<view class="water-mark-mask" style="background:url('{{imgBase64}}')">
<canvas canvas-id="water_mark_id"></canvas>
</view>
复制代码
wxss文件
.water-mark-mask {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
pointer-events: none;
opacity: 0.1;
}
复制代码
- 使用DOM元素实现 (采用的是这一种)
js代码
Component({
data: {
text: '请勿外传',
// color: 'rgba(0,0,0,0.03)',
color: 'rgba(0,0,0,0.5)',
rows: [],
cols: []
},
// 组件在页面上挂载时触发,注意如果页面没卸载过,该事件就不会触发第二次
attached() {
const { windowWidth, windowHeight } = wx.getSystemInfoSync();
const rows = Math.ceil(windowWidth / (30 * this.data.text.length));
const cols = Math.ceil(windowHeight / 100);
this.setData({
rows: new Array(rows),
cols: new Array(cols)
});
},
})
复制代码
json文件
{
"component": true
}
复制代码
wxml文件
<view class='water-mark-mask'>
<view class='row' wx:for="{{rows}}" wx:key="index">
<view class='col' wx:for="{{cols}}" wx:key="index" style="color:{{color}}">{{text}}</view>
</view>
</view>
复制代码
wxss文件
.water-mark-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 9999;
display: flex;
flex-direction: row;
justify-content: space-between;
pointer-events: none; //无视鼠标事件,相当于鼠标事件透传下去一样
flex:1
}
.row{
display: flex;
flex-direction: column;
align-items: center;
}
.col{
transform: rotate(-45deg);
height: 200rpx;
}
复制代码
这样就好了,引用到页面就?了