普歌-uniapp中或⼩程序中使⽤背景⽔印(canvas实现+原⽣组件层级⾼的解
决)
⽼规矩前⾔:需求是这样的,在⼩程序上加⼀个⽔印效果,不过要在最下⾯加(层级最低的意思),⼤家都知道⽔印可以⽤很多个盒⼦拼成⼀个⽔印;也可以⽤⽣成,但canvas是原⽣组件,层级太⾼,会出现⼀系列问题。这⾥我⽤了我能想到的做法,有更好的⽅法请⼤佬们指教。
代码结构
这样虽然绘制出来了,在开发者⼯具中没有问题,但是在真机调试出现问题
<!-- ⽔印 --><view class ='water_top '> <canvas canvas-id ='watermarkCanvas ' style ='width :100%;height :100%'></canvas ></view ><script > export default { data () { return { } }, onLoad () { this .drowsyUserinfo ('⾼禄') }, methods : { drowsyUserinfo (name ) { const name_xx = name ; const ctx = uni .createCanvasContext ("watermarkCanvas"); //⽂字的旋转⾓度 ctx .rotate (45 * Math .PI / 180); ctx .setFontSize (16); //wx 设置⼀个⽂字⼤⼩ // 获取到名字的宽度 const textWidth = ctx .measureText (name_xx ).width ; // 每个名字带⼀个空字作为间距 const allTextWidth = textWidth + textWidth /name_xx .length ; //对斜对⾓线以左部分进⾏⽂字的填充 for (let j = 1; j < 15; j ++) { // for
循环代表纵向循环⽂字 ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , 0, 50 * j ); for (let i = 1; i < 20; i ++) { //这个for 循环代表横向循环, ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , allTextWidth * i , 50 * j ); } } //两个for 循环的配合,使得⽂字充满斜对⾓线的左下部分 //对斜对⾓线以右部分进⾏⽂字的填充逻辑同上 for (let j = 0; j < 15; j ++) { ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , 0, -50 * j ); for (let i = 1; i < 20; i ++) { ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , allTextWidth * i , -50 * j ); } } ctx .draw (); }, } }</script ><style lang ="scss " scoped > .water_top { position : fixed ; z-index : 1; opacity : 1; top : 0; right : 0; bottom : 0; left : 0; background-color : #3a72f5; } .home-container { position : relative ; z-index : 5; }</style >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
问题⼀:绘制后,真机调试出问题,canvas原⽣组件层级太⾼由于canvas是原⽣组件,所以原⽣组件不管设置了多少z-index,还是在最⾼层级
由于我这个是要作为背景的存在,
解决思路:先⽤canvas画出,⽤draw的回调进⾏转图⽚,然后转成图⽚渲染到页⾯
/** * 绘制⽔印 */ drowsyUserinfo (name ) { const name_xx = name ; const ctx = uni .createCanvasContext ("watermarkCanvas"); //⽂字的旋转⾓度 ctx .rotate ((45 * Math .PI ) / 180); ctx .setFontSize (16); //wx 设置⼀个⽂字⼤⼩ // 获取到名字的宽度 const textWidth = ctx .measureText (name_xx ).width ; // 每个名字带⼀个空字作为间距 const allTextWidth = textWidth + textWidth / name_xx .length ; //对斜对⾓线以左部分进⾏⽂字的填充 for (let j = 1; j < 15; j ++) { // for 循环代表纵向循环⽂字 ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , 0, 50 * j ); for (let i = 1; i < 20; i ++) { //这个for 循环代表横向循环, ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , allTextWidth * i , 50 * j ); } } //两个for 循环的配合,使得⽂字充满斜对⾓线的左下部分 //对斜对⾓线以右部分进⾏⽂字的填充逻辑同上 for (let j = 0; j < 15; j ++) { ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , 0, -50 * j ); for (let i = 1; i < 20;
i ++) { ctx .beginPath (); ctx .setFillStyle ("rgba(49, 106, 236,1)"); ctx .fillText (name_xx , allTextWidth * i , -50 * j ); } } ctx .draw (true , () => { uni .canvasToTempFilePath ( { x : 0, y : 0, canvasId : "watermarkCanvas", fileType : "png", quality : 1, success : (result ) => { this .canvasImg = result .tempFilePath ; }, fail : (err ) => { this .canvasImg = "error"; }, complete : () => { this .canvasFinsh = true ; }, }, this ); }); },
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
原生安卓app开发35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
注意事项:必须在draw回调画图,不然真机调试会出现 canvasToTempFilePath: fail canvas is empty
⽬前在真机上层级可以正常显⽰
问题⼆:虽然可以在真机可以显⽰,但是在加载的瞬间会先绘制canvas (导致会有⼏帧的层级最⾼问题),然后才会显⽰image
解决⽅案:把canvas先⽤定位移除屏幕,然后把要覆盖在canvas上⾯的元素加上v-if判断条件(渲染图⽚地址),最后⽤封装的请求
loading动画延长,造成加载数据的假象<!-- ⽔印 --><view class ='water_top'> <canvas v -if ="!canvasImg" canvas -id ='watermarkCanvas' style ='width:100%;height:100%;z-index:1'></canvas > <image v -else :src ="canvasImg" style ='width:100%;height:100%;z-index:1;position: absolute;'/>
</view >
1
2
3
4
5
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论