微信小程序中用canvas将文字转成图片,文字自动换行

阅读 (516)
onReady: function () {
  wx.showLoading({
      title: '生成图片中...',
    })
    var that = this
    
    const ctx = wx.createCanvasContext('canvas')
    ctx.setFillStyle("#999") // 颜色
    ctx.font = 'normal 18px sans-serif' //
    const text = "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。\nPHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高效率的选项。"
    const textX = 0 
    const textY = 23
    const lineHeight = 23
    const MAX_WIDTH = 360

    var rowLength = this.drawText(ctx, text, textX, textY, lineHeight, MAX_WIDTH)
    var canvasHeight = rowLength * lineHeight

    this.setData({
      canvasWidth: MAX_WIDTH,
      canvasHeight: canvasHeight
    })
    // 这里绘图渲染完后回调中再加上延时,最后再生成图片
    ctx.draw(true, function() {
       setTimeout(() => {
        // 保存文案图片
        wx.canvasToTempFilePath({
          x: 0,
          y: 0,
          width: MAX_WIDTH,
          height: canvasHeight,
          destWidth: MAX_WIDTH * 2,
          destHeight: canvasHeight * 2,
          canvasId: 'canvas',
          success: function (res) {
            console.log('res.tempFilePath', res.tempFilePath)
          },
          fail: function (err) {
            Util.toastLongText('生成失败,请稍后重试')
          }
        })
       }, 300)
    })
},
/**
 * params
 * @ctx           画布对象
 * @text           需要绘制的文本字符
 * @startX         第一行文本的起始X坐标
 * @startY         第一行文本的起始Y坐标
 * @lineHeight     文本行高
 * @MAX_WIDTH      单行文字最大宽度,超过临界值自动换行
 * return rowLength  返回绘制文本的行数
**/
drawText: function (ctx, text, startX, startY, lineHeight, MAX_WIDTH) {
    let lineArr = text.split("\n")  // 拆分出内容本身的行
    let rowArr = [] // 用来存储每一行的数据
    for (let i = 0; i < lineArr.length; i++) { // 先遍历内容本身的换行
      const lineStr = lineArr[i].split('')
      var rowStrArr = [] // 每一行的文字数组
      for (let j = 0; j < lineStr.length; j++) { // 再遍历每一行文字
        const currentStr = lineStr[j]
        rowStrArr.push(currentStr)
        const rowStr = rowStrArr.join('')
        // 判断当前文字宽度是否超出宽度,超出后换一行继续遍历
        if (this.measureText(rowStr, 18) > MAX_WIDTH) { // 在微信小程序现在的版本(v2.13.2)中,小程序的canvas还不支持measureText,这个方法重写了一个
          rowStrArr.pop() // 删除最后一个
          rowArr.push(rowStrArr.join('')) // 完成一行
          rowStrArr = [currentStr]
          continue
        }
        // 最后一个字母 直接添加到一行
        if (j === lineStr.length - 1) {
          rowArr.push(rowStr) // 完成一行
        }
      }
      rowArr.push('')
    }

    for (let i = 0; i < rowArr.length; i++) {
      ctx.fillText(rowArr[i], startX, startY + i * lineHeight)
    }
    console.log('rowArr', rowArr)
    return rowArr.length
},

measureText: function (text, fontSize=10) {
  text = String(text);
  var text = text.split('');
  var width = 0;
  text.forEach(function(item) {
      if (/[a-zA-Z]/.test(item)) {
          width += 7;
      } else if (/[0-9]/.test(item)) {
          width += 5.5;
      } else if (/\./.test(item)) {
          width += 2.7;
      } else if (/-/.test(item)) {
          width += 3.25;
      } else if (/[\u4e00-\u9fa5]/.test(item)) {  //中文匹配
          width += 10;
      } else if (/\(|\)/.test(item)) {
          width += 3.73;
      } else if (/\s/.test(item)) {
          width += 2.5;
      } else if (/%/.test(item)) {
          width += 8;
      } else {
          width += 10;
      }
  });
  return width * fontSize / 10;
}

 

更新于:2020-10-30 10:20:20
返回顶部