• 小程序生成海报 详解


    效果图:

    <view class='poste_box' id='canvas-container' style='opacity:{{opacity}}'>
      <canvas canvas-id="myCanvas" style="100%;height:900rpx;" />
    
    
      <view class='wrapper_fuc'>
        <button style='background-color:#fff;' class='btnshare iconfont icon-guanyu' open-type='share'> 微信好友</button>
        <button style='background-color:#fff;' class='btn_item iconfont icon-guanyu' bindtap="saveShareImg"> 保存图片</button>
      </view>
    </view>
    
    
    
    
    page{
      background-color: #EDEEF2;
      background-image: url(https://www.cnblogs.com/images/cnblogs_com/520BigBear/1196074/t_dog.jpg);
      background-size: cover;
      background-position: center
    }
    .poste_box{
       85%;
      margin: auto;
      margin-top: 50rpx;
      background-color: #fff;
      border: 1rpx solid #ddd;
      box-shadow:0px 0px  10px 5px #D8D7DD;
    }
    .savePoste{
      background-color: #FF8427;
       90%;
      margin-left: auto;
      margin-right: auto;
      margin-top:30rpx;
      color: #fff;
    }
    .saveTitle{
      font-size: 25rpx;
      color: #666;
       90%;
      margin-left: auto;
      margin-right: auto;
      margin-top: 20rpx;
      text-align: center;
    }
    
    .wrapper_fuc{
      display: flex;
      justify-content: space-between
    }
    
    
    
    //我在js中注释的代码很重要,实际开发中绘制商品海报必然是用网络图片,
    但经过多次尝试网络图片是不可以直接绘制在canvas画布上的,就必须要把他缓存下来,弄一个本地路径
    wx.downloadFile
     
     
    Page({
      data: {
        opacity:0,
        cardInfo: {
          avater: "https://www.cnblogs.com/images/cnblogs_com/520BigBear/1196074/t_dog.jpg", //需要https图片路径
          qrCode: "https://www.cnblogs.com/images/cnblogs_com/520BigBear/1196074/t_love.jpg", //需要https图片路径
          TagText: "大熊", //标签
          Name: '大熊', //姓名
          Position: "程序员鼓励师", //职位
          Mobile: "13888888888", //手机
          Company: "熊野有限公司", //公司
        }
      },
    
      onLoad: function () {
        this.getAvaterInfo();
        let that = this
        setTimeout(function () {
          that.setData({
            opacity: 0.9
          });
        }, 1500);
      },
    
      /**
       * 先下载头像图片
       */
      getAvaterInfo: function () {
        wx.showLoading({
          title: '生成中...',
          mask: true,
        });
        var that = this;
        wx.downloadFile({
          url: that.data.cardInfo.avater, //头像图片路径
          success: function (res) {
            wx.hideLoading();
            if (res.statusCode === 200) {
              var avaterSrc = res.tempFilePath; //下载成功返回结果
              that.getQrCode(avaterSrc); //继续下载二维码图片
    
              
            } else {
              wx.showToast({
                title: '头像下载失败!',
                icon: 'none',
                duration: 2000,
                success: function () {
                  var avaterSrc = "";
                  that.getQrCode(avaterSrc);
                }
              })
            }
          }
        })
      },
    
      /**
       * 下载二维码图片
       */
      getQrCode: function (avaterSrc) {
        wx.showLoading({
          title: '生成中...',
          mask: true,
        });
        var that = this;
        wx.downloadFile({
          url: that.data.cardInfo.qrCode, //二维码路径
          success: function (res) {
            wx.hideLoading();
            if (res.statusCode === 200) {
              var codeSrc = res.tempFilePath;
              that.sharePosteCanvas(avaterSrc, codeSrc);
            } else {
              wx.showToast({
                title: '二维码下载失败!',
                icon: 'none',
                duration: 2000,
                success: function () {
                  var codeSrc = "";
                  that.sharePosteCanvas(avaterSrc, codeSrc);
                }
              })
            }
          }
        })
      },
    
      /**
       * 开始用canvas绘制分享海报
       * @param avaterSrc 下载的头像图片路径
       * @param codeSrc   下载的二维码图片路径
       */
      sharePosteCanvas: function (avaterSrc, codeSrc) {
        wx.showLoading({
          title: '生成中...',
          mask: true,
        })
        var that = this;
        var cardInfo = that.data.cardInfo; //需要绘制的数据集合
        const ctx = wx.createCanvasContext('myCanvas'); //创建画布
        var width = "";
        wx.createSelectorQuery().select('#canvas-container').boundingClientRect(function (rect) {
          var height = rect.height;
          var right = rect.right;
          width = rect.width * 0.8;
          var left = rect.left + 5;
          ctx.setFillStyle('#fff');
          ctx.fillRect(0, 0, rect.width, height);
    
          //头像为正方形
          if (avaterSrc) {
            ctx.drawImage(avaterSrc, left, 20, width, width);
            ctx.setFontSize(14);
            ctx.setFillStyle('#fff');
            ctx.setTextAlign('left');
          }
    
          //标签
          if (cardInfo.TagText) {
            ctx.fillText(cardInfo.TagText, left + 20, width - 4);
            const metrics = ctx.measureText(cardInfo.TagText); //测量文本信息
            ctx.stroke();
            ctx.rect(left + 10, width - 20, metrics.width + 20, 25);
            ctx.setFillStyle('rgba(255,255,255,0.4)');
            ctx.fill();
          }
    
          //姓名
          if (cardInfo.Name) {
            ctx.setFontSize(14);
            ctx.setFillStyle('#000');
            ctx.setTextAlign('left');
            ctx.fillText(cardInfo.Name, left, width + 60);
          }
    
          //职位
          if (cardInfo.Position) {
            ctx.setFontSize(12);
            ctx.setFillStyle('#666');
            ctx.setTextAlign('left');
            ctx.fillText(cardInfo.Position, left, width + 85);
          }
    
          //电话
          if (cardInfo.Mobile) {
            ctx.setFontSize(12);
            ctx.setFillStyle('#666');
            ctx.setTextAlign('left');
            ctx.fillText(cardInfo.Mobile, left, width + 105);
          }
    
          // 公司名称
          if (cardInfo.Company) {
            const CONTENT_ROW_LENGTH = 24; // 正文 单行显示字符长度
            let [contentLeng, contentArray, contentRows] = that.textByteLength(cardInfo.Company, CONTENT_ROW_LENGTH);
            ctx.setTextAlign('left');
            ctx.setFillStyle('#000');
            ctx.setFontSize(10);
            let contentHh = 22 * 1;
            for (let m = 0; m < contentArray.length; m++) {
              ctx.fillText(contentArray[m], left, width + 150 + contentHh * m);
            }
          }
    
          //  绘制二维码
          if (codeSrc) {
            ctx.drawImage(codeSrc, left + 160, width + 40, width / 3, width / 3)
            ctx.setFontSize(10);
            ctx.setFillStyle('#000');
            ctx.fillText("微信扫码或长按识别", left + 160, width + 150);
          }
          //画个圆 头部 圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆圆
        if (codeSrc) {
          ctx.beginPath();
          //ctx.arc(x,y,r,a,b,c) x:圆的x坐标, y:圆的y坐标, r:半径 ;后面默认就行
          ctx.arc(70, 70, 50, 0, 2 * Math.PI, false) //画一个圆形裁剪区域
          ctx.clip() //裁剪
          // ctx.drawImage(codeSrc, '左右偏移量', '上下偏移', '宽', '长')
          ctx.drawImage(codeSrc, 20, 20, width / 2, width / 2)
          ctx.setStrokeStyle('rgba(0,0,0,0)') //防止黑圈 设置透明
          ctx.stroke();
          ctx.restore();
          }
    
        }).exec()
    //注意一点的是保存图片时需要延迟,这是老版的写法,没有啥问题,新版写法可以通过draw回调画图成功后调用保存图片的api wx.canvasToTempFilePath。这个时候就不需要写延时保存图片。
    
        setTimeout(function () {
          ctx.draw();
          wx.hideLoading();
        }, 1000)
    
      },
    
      /**
       * 多行文字处理,每行显示数量
       * @param text 为传入的文本
       * @param num  为单行显示的字节长度
       */
      textByteLength(text, num) {
        let strLength = 0; // text byte length
        let rows = 1;
        let str = 0;
        let arr = [];
        for (let j = 0; j < text.length; j++) {
          if (text.charCodeAt(j) > 255) {
            strLength += 2;
            if (strLength > rows * num) {
              strLength++;
              arr.push(text.slice(str, j));
              str = j;
              rows++;
            }
          } else {
            strLength++;
            if (strLength > rows * num) {
              arr.push(text.slice(str, j));
              str = j;
              rows++;
            }
          }
        }
        arr.push(text.slice(str, text.length));
        return [strLength, arr, rows] //  [处理文字的总字节长度,每行显示内容的数组,行数]
      },
    
      //点击保存到相册
      saveShareImg: function () {
        var that = this;
        wx.showLoading({
          title: '正在保存',
          mask: true,
        })
        setTimeout(function () {
          wx.canvasToTempFilePath({
            canvasId: 'myCanvas',
            success: function (res) {
              wx.hideLoading();
              var tempFilePath = res.tempFilePath;
              wx.saveImageToPhotosAlbum({
                filePath: tempFilePath,
                success(res) {
                  // utils.aiCardActionRecord(19);
                  wx.showModal({
                    content: '保存成功!',
                    showCancel: false,
                    confirmText: '好的',
                    confirmColor: '#333',
                    success: function (res) {
                      if (res.confirm) { }
                    },
                    fail: function (res) { }
                  })
                },
                fail: function (res) {
                  wx.showToast({
                    title: res.errMsg,
                    icon: 'none',
                    duration: 2000
                  })
                }
              })
            }
          });
        }, 1000);
      },
    
    })

     友情链接  资源参考 :https://blog.csdn.net/qq_41629498/article/details/82052729

              https://www.jianshu.com/p/6204e9d9b277

              资源共享,一起学习,   一起进步  !  peace  & love

     
  • 相关阅读:
    android的原理,为什么我们不需要太多的剩余内存(转)
    简单制作RPM二进包实例(转)
    电源相关术语
    Linux 查找指定文件并删除
    Linux内核中的内存屏障(转)
    分压、分流原理
    Linux内核入门—— __attribute__ 机制
    如何手工释放linux内存
    多核编程中的负载平衡难题(转)
    linux2.6.26内核中ARM中断实现详解(转)
  • 原文地址:https://www.cnblogs.com/520BigBear/p/11075910.html
Copyright © 2020-2023  润新知