8***@qq.com
8***@qq.com
  • 发布:2019-05-24 12:01
  • 更新:2024-07-16 18:14
  • 阅读:15221

uni-app全局水印

分类:uni-app

文章废话比较多,主要是想讲一下做这个功能所经历的一些事情,先上代码吧:
由于需要借助canvas生成图片,这里的代码是在应用的首页index.vue执行的,在App.vue无法实现,需要在index.vue中定义
代码写的比较乱,先将就着看,之后再整理

<!-- #ifdef APP-PLUS -->  
        <block v-if="showWatermark">  
            <canvas class="watermarkCans" canvas-id="watermarkCanvas"></canvas>  
        </block>  
        <!-- #endif -->

下面是js


    initWatermark(msg) {  
// #ifdef APP-PLUS  
    let _self = this;  
                let id = '1.23452384164.123412415';  
                if (plus.nativeObj.View.getViewById(id) !== null) {  
                    plus.nativeObj.View.getViewById(id).close();  
                }  
                let canvasInAppPlusContext = uni.createCanvasContext('watermarkCanvas');  
                canvasInAppPlusContext.rotate(-30 * Math.PI / 180);  
                canvasInAppPlusContext.setFontSize(uni.upx2px(28));  
                canvasInAppPlusContext.setFillStyle('rgba(200, 200, 200, 0.50)');  
                canvasInAppPlusContext.setTextAlign('left');  
                canvasInAppPlusContext.setTextBaseline('middle');  
                canvasInAppPlusContext.fillText(msg, -25, uni.upx2px(170));  
                canvasInAppPlusContext.draw(false, function() {  
                    uni.canvasToTempFilePath({  
                        canvasId: "watermarkCanvas",  
                        success: function(res) {  
                            _self.showWatermark = false;  
                            let path = res.tempFilePath;  

                            uni.getSystemInfo({  
                                success: function (res) {  
                                    //水印排列行数  
                                    let row = Math.floor(res.windowHeight / uni.upx2px(250));  
                                    let tarArr = [];  

                                    for(let i = 0; i < row; i++) {  
                                        for(let j = 0; j < 3; j++){  
                                            tarArr.push({  
                                                tag: 'img',  
                                                src: path,  
                                                position: {  
                                                    top: (uni.upx2px(255) * i) + 'px',  
                                                    left: (uni.upx2px(255) * j) + 'px',  
                                                    width: uni.upx2px(255) + 'px',  
                                                    height: uni.upx2px(255) + 'px'  
                                                }  
                                            });  
                                        }  
                                    }  

                                    var watermarkView = new plus.nativeObj.View(id, {  
                                        top:'70px',  
                                        left:'0px',  
                                        right: '0px',  
                                        bottom: '50px'  
                                    }, tarArr);  
                                    //拦截View控件的触屏事件,将事件穿透给下一层view  
                                    watermarkView.interceptTouchEvent(false);   
                                    watermarkView.show();  
                                }  
                            });  
                        }  
                    });  
                });           

// #endif  
// #ifdef H5  
let id = '1.23452384164.123412415';  
    if (document.getElementById(id) !== null) {  
        document.body.removeChild(document.getElementById(id));  
    }  

    let can = document.createElement('canvas');  
    can.width = uni.upx2px(250);  
    can.height = uni.upx2px(250);  

    let cans = can.getContext('2d');  

    cans.rotate(-30 * Math.PI / 180);  
    cans.font = uni.upx2px(28) + 'px';  
    cans.fillStyle = 'rgba(200, 200, 200, 0.50)';  
    cans.textAlign = 'left';  
    cans.textBaseline = 'Middle';  
    cans.fillText(msg, -25, uni.upx2px(170));  

    let div = document.createElement('div');  
    div.id = id;  
    div.style.pointerEvents = 'none';  
    div.style.top = '44px';  
    div.style.left = '-40px';  
    div.style.bottom = '50px';  
    div.style.right = '0px';  
    div.style.position = 'fixed';  
    div.style.zIndex = '100000';  
    // div.style.width = document.documentElement.clientWidth + 'px'  
    // div.style.height = document.documentElement.clientHeight + 'px'  
    div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat';  
    document.body.appendChild(div);  
    return id;  
// #endif  
  }

前两天在研究一个全局水印的功能,需要达到以下的效果:
1、根据给出的文字生成水印
2、水印需要在全局生效,不能跳转页面后消失
3、H5端和APP端都要兼容

根据以上的需求,我研究了以下几种方案:
1、封装水印组件。
做一个漂浮的div,定义z-index层级和pointer-event属性和背景平铺重复,在需要的页面中使用组件。这个实现起来很简单,兼容H5和APP,但是有一个问题需要在每一个页面中去单独引入,不符合全局水印的定义,而且项目要提供给项目组使用,很明显不是一个完美的方案。

2、往页面中插入一个div
实现方式和第一点类似,优点是只能在H5端生效,APP端没有body,这个方案直接被pass了

3、用native.js分别实现安卓和IOS端的效果
但是由于对原生开发不了解,这个方案直接就实现不了了

4、直接丢给原生开发做,再去引入插件
这明显不是个好点子,而且研究了这么久不能半半途而废

尝试了很多方法之后我就思考:有没有这样一个顶层的视图容器的东西,可以让我去插入内容,还不会影响事件的穿透,基于这个想法,我又做了一下尝试
1、应用生命周期
由于对移动开发和vue都不熟,尝试了很多vue的方法,生命周期钩子,createElement,render等等,都失败了。

2、webview
我了解到uni-app在APP端实质上也是一个webview,每一个页面其实是这个webview的子webview,我想在应用的onLaunch里边去获取到顶层的webview,往webview中添加子窗口的方式实现,因为各种原因,实现了一半,但是感觉好像有了苗头

3、plus.nativeObj.View
也就是我最终的实现方式,研究了好久,发现了这个宝藏对象。
plus.nativeObj:可以管理系统原生对象。
plus.nativeObj.View:原生控件对象可用于在屏幕上绘制图片或文本内容,当控件不再使用时需要调用close方法销毁控件。
链接:http://www.html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View
尝试了之后发现可以在屏幕上绘制内容,并且在整个应用生效,开心到爆炸,但是!!又遇到了一个问题,这些内容会形成类似遮罩层的东西,导致事件无法穿透。研究了一番,找到了这样一个方法:view.interceptTouchEvent(false),它可以拦截View控件的触屏事件。
接下来,就是文字生成水印图片的问题了,我用的canvas绘制了一个水印,转换成图片实现。期间遇到了一个问题,APP端的uni.canvasToTempFilePath事件需要放在cans.draw()的回调里去实现。

14 关注 分享
回梦無痕 9***@qq.com 3***@qq.com 1***@163.com s***@qq.com aliang888 DCloud_UNI_CHB y***@163.com Yao_yaoooooo 1***@qq.com Neemor 土豆鸡丁_o0 HRK_01 9***@qq.com

要回复文章请先登录注册

语文数学天才

语文数学天才

所以小程序里面做不到?
2019-06-09 23:07
8***@qq.com

8***@qq.com (作者)

这一篇是根据文本内容生成图片制作水印。另一篇根据图片路径生成水印:https://ask.dcloud.net.cn/article/35982
2019-06-03 13:33
3***@qq.com

3***@qq.com

怎么用啊?
2019-06-03 12:02