美文网首页vue小程序问题
微信小程序 canvas生成小程序码海报并保存本地相册

微信小程序 canvas生成小程序码海报并保存本地相册

作者: 单抽律化娜 | 来源:发表于2019-02-13 15:22 被阅读54次
/// 获取屏幕缩放倍数
const ratepx = 750.0 / wx.getSystemInfoSync().windowWidth;

/// 获取canvas转化后的rpx
const rate = function(rpx) { 
  return rpx / ratepx
};

Page({

  /**
   * 页面的初始数据
   */
  data: {
    poster: ''
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {

  }, 
 
  /// 绘制文本
  drawText: function(options) {
    /// 获取总行数
    var allRow = Math.ceil(options.ctx.measureText(options.str).width / options.maxWidth);
    /// 限制行数
    var count = allRow >= options.maxLine ? options.maxLine : allRow,
      /// 当前字符串的截断点
      endPos = 0;
    /// 设置文字颜色
    options.ctx.setFillStyle(options.style ? options.style : '#353535');
    /// 设置字体大小
    options.ctx.setFontSize(options.fontSize ? options.fontSize : rate(20));
    /// 循环截断
    for (var j = 0; j < count; j++) {
      /// 当前剩余的字符串
      var nowStr = options.str.slice(endPos),
        /// 每一行当前宽度
        rowWid = 0,
        /// 每一行顶部距离
        y = options.y + (count == 1 ? 0 : j * options.height);
      /// 如果当前的字符串宽度大于最大宽度,然后开始截取
      if (options.ctx.measureText(nowStr).width > options.maxWidth) {
        for (var m = 0; m < nowStr.length; m++) {
          /// 计算当前字符串总宽度
          rowWid += options.ctx.measureText(nowStr[m]).width;
          if (rowWid > options.maxWidth) {
            /// 如果是最后一行
            if (j === options.maxLine - 1) {
              options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, y);
            } else {
              options.ctx.fillText(nowStr.slice(0, m), options.x, y);
            }
            /// 保留下次截断点
            endPos += m;
            break;
          }
        }
      } else { /// 如果当前的字符串宽度小于最大宽度就直接输出
        options.ctx.fillText(nowStr.slice(0), options.x, y);
      }
    }
  },

  /// 绘制海报 1、canvas对象 2、canvas宽 3、canvas高 4、绘制的内容
  draw: function(canvas, cavW, cavH, writing) {

    return new Promise((resolve, reject) => {

      if (!writing || !canvas) {
        reject();
        return;
      }

      /// 创建context
      var ctx = wx.createCanvasContext(canvas);
      ctx.clearRect(0, 0, rate(cavW), rate(cavH));

      /// 获取大的背景图
      let promise1 = new Promise(function(resolve, reject) {
        wx.getImageInfo({
          src: writing.bigImage,
          success: function(res) {
            resolve(res.path);
          },
          fail: function(err) {
            reject(err);
          }
        })
      });

      /// 获取头像图片
      let promise2 = new Promise(function(resolve, reject) {
        if (writing.avatar == '' || !writing.avatar) {
          resolve('默认头像图片地址');
          return;
        }
        wx.getImageInfo({
          src: writing.avatar,
          success: function(res) {
            resolve(res.path);
          },
          fail: function(fail) {
            resolve('默认头像图片地址');
          }
        })
      });

      /// 获取小程序码图片
      let promise3 = new Promise(function(resolve, reject) {
        wx.getImageInfo({
          src: writing.code,
          success: function(res) {
            resolve(res.path);
          },
          fail: function(err) {
            reject(err);
          }
        })
      });

      /// 同步回调
      Promise.all(
        [promise1, promise2, promise3]
      ).then(res => {

        /// 绘制底色
        ctx.setFillStyle('white');
        ctx.fillRect(0, 0, rate(cavW), rate(cavH));

        /// 绘制背景图
        ctx.drawImage(res[0], 0, 0, rate(622), rate(628));

        /// 直径
        const diameter = rate(54);
        /// 圆参数 
        const arc = {
          radii: diameter / 2,
          x: rate(40),
          y: rate(800)
        };

        /// 绘制文案内容   
        this.drawText({
          ctx: ctx,
          str: writing.content,
          maxLine: 3,
          maxWidth: rate(366),
          x: arc.x,
          y: rate(690),
          height: rate(36),
          fontSize: rate(26)
        })

        ctx.save();

        /// 绘制头像
        ctx.beginPath();
        ctx.arc(arc.x + arc.radii, arc.y + arc.radii, arc.radii, 0, Math.PI * 2, false)
        ctx.clip();
        ctx.drawImage(res[1], arc.x, arc.y, diameter, diameter);
        ctx.restore();

        /// 绘制姓名   
        this.drawText({
          ctx: ctx,
          str: writing.name,
          maxLine: 1,
          maxWidth: rate(300),
          x: rate(112),
          y: rate(836),
          height: rate(36)
        })

        /// 绘制小程序码
        ctx.drawImage(res[2], rate(458), rate(670), rate(122), rate(122));
        /// 绘制小程序名称 
        ctx.fillText("程序名", rate(488), rate(836))

        /// 绘图
        ctx.draw(false, () => {
          wx.canvasToTempFilePath({
            canvasId: 'poster',
            fileType: 'png',
            success: res => {
              this.setData({
                poster: res.tempFilePath
              })
              resolve();
            },
            fail: err => {
              reject();
            }
          })
        });
      }, err => {
        reject();
      })
    })
  } 
})

具体代码可以看 https://developers.weixin.qq.com/s/hhpCs9me7i65

相关文章

网友评论

    本文标题:微信小程序 canvas生成小程序码海报并保存本地相册

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