美文网首页vue
vue html2canvas 钉钉

vue html2canvas 钉钉

作者: hsqin | 来源:发表于2019-05-14 17:48 被阅读60次

    以前写过PC浏览器上的html2Canvas,这次是给公司开发钉钉应用,需要在钉钉应用里面上传图片后,并和其他图片、二维码一起,绘制成一个宣传海报。具体步骤见下图:


    1.png 2-上传之后.png 3-点击生成海报.png

    遇到的问题

    1,背景图片模糊问题

    • 不需要改插件,所有的图都用img标签,不用background即可解决

    2,图片跨域问题

    • 后台同事写了一个接口,将oss服务器的图片转换为一个同域下的图片。但是本地测试的时候,仍然有跨域,就使用了base64位做为img的src

    3,钉钉中下载图片问题

    • 这个项目是vue开发钉钉应用,生成的海报是一个base64位格式。钉钉的api中预览、下载均不支持base64,也不支持blob。所以,使用了a标签的download属性来下载blob格式的图片(blob://http://192.xxxxxx./xxxxxxx)

    4,生成的图片大小与左侧不一致,有空白

    • 左侧的imageWrapper区域,是最终绘制的源,要严格设置宽高,不能有空白,否则绘制出来的图也会有空白

    5,二维码生成后,无法在微信识别

    • 图中二维码大小是55x55,生成的时候,生成200x200或者更大的,但是给二维码的img设置成55x55即可

    document.getElementById("j_design_code").innerHTML = '';
    let qrDesCode = new QRCode('j_design_code', {
    width: 200,
    height: 200,
    text: 'xxxx', // 二维码内容
    render: 'table' // 设置渲染方式(有两种方式 table和canvas,默认是canvas)
    });

    用到的方法

    getBase64(img){
            function getBase64Image(img,width,height) {//width、height调用时传入具体像素值,控制大小 ,不传则默认图像大小
              var canvas = document.createElement("canvas");
              canvas.width = width ? width : img.width;
              canvas.height = height ? height : img.height;
    
              var ctx = canvas.getContext("2d");
              ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
              var dataURL = canvas.toDataURL();
              return dataURL;
            }
    
            var image = new Image();
            image.crossOrigin = 'Anonymous';
            image.src = img;
            var deferred=$.Deferred();
            if(img){
              image.onload =function (){
                deferred.resolve(getBase64Image(image));//将base64传给done上传处理
              }
              return deferred.promise();//问题要让onload完成后再return sessionStorage['imgTest']
            }
          },
    
    • base64转换为blob
    base64ToBlob(urlData) {
            var arr = urlData.split(',');
            var mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
            // 去掉url的头,并转化为byte
            var bytes = window.atob(arr[1]);
            // 处理异常,将ascii码小于0的转换为大于0
            var ab = new ArrayBuffer(bytes.length);
            // 生成视图(直接针对内存):8位无符号整数,长度1个字节
            var ia = new Uint8Array(ab);
    
            for (var i = 0; i < bytes.length; i++) {
              ia[i] = bytes.charCodeAt(i);
            }
    
            return new Blob([ab], {
              type: mime
            });
          },base64ToBlob(urlData) {
            var arr = urlData.split(',');
            var mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
            // 去掉url的头,并转化为byte
            var bytes = window.atob(arr[1]);
            // 处理异常,将ascii码小于0的转换为大于0
            var ab = new ArrayBuffer(bytes.length);
            // 生成视图(直接针对内存):8位无符号整数,长度1个字节
            var ia = new Uint8Array(ab);
    
            for (var i = 0; i < bytes.length; i++) {
              ia[i] = bytes.charCodeAt(i);
            }
    
            return new Blob([ab], {
              type: mime
            });
          },
    

    注意:返回的是 new Blob类型,不能直接用于img的src,需要用window.URL.createObjectURL(Blob) 转换为blob:http://192.xxxx/xx

    详细讲解

    • 项目中安装 html2canvas,我的是这个版本

    "html2canvas": "^1.0.0-rc.1",
    "jquery": "^3.3.1",

    • vue页面中引用

    import QRCode from 'qrcodejs2' --生成二维码
    import $ from 'jquery' --图片转base64的时候用到
    import html2canvas from 'html2canvas';

    • 上传操作
      • 上传是调用后台的接口,将本地图片传到oss服务器,返回给我一个http://xxxxx.png的图片 ,假设赋给变量 noteImg
    • 上传成功之后,得到base64位图,做为img的src
    uploadSuc{
            that.getBase64(that.noteImg)
                  .then(function (base64) {
                    that.uploadImgData = base64;
                  }, function (err) {
                    console.log(err);
                  });
    }
    
    //html中直接用uploadImgData作为src
    <div class="note-main">
          <img :src="uploadImgData" alt="">
    </div>
    
    • 3,点击‘生成海报’
    //生成海报并在右侧预览
    previewFun(){
            let that = this;
    
            html2canvas(that.$refs.imageWrapper,{
              backgroundColor: null,
              async: true,
              scale:5
            }).then((canvas) => {
              let dataURL = canvas.toDataURL("image/png");
    
              let tmpBlob = that.base64ToBlob(dataURL);
              that.designImgDataURL = window.URL.createObjectURL(tmpBlob);
              console.log('预览的海报blob图片  ',that.designImgDataURL);
            });
     },
    
    //html中代码
    <div class="flex-item design-right">
         <img class="design-img" :src="designImgDataURL" alt="">
         <div style="text-align: right;" v-show="designImgDataURL">
               <a :href="designImgDataURL" class="design-download" target="_blank" 
    :download="designRow.studentName+'.png'">点击下载</a>
          </div>
    </div>
    
    html结构.png

    相关文章

      网友评论

        本文标题:vue html2canvas 钉钉

        本文链接:https://www.haomeiwen.com/subject/mmheaqtx.html