普歌-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小时内删除。