欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

小程序用canvas生成图片

程序员文章站 2024-02-11 17:11:04
...

效果如图
小程序用canvas生成图片
wxml

  <button bindtap='saveImageToPhotosAlbum' class="save">生成图片</button>
  <canvas canvas-id='share' wx:if="{{canvasHidden}}" style='width:{{screenWidth}}px;height:1500rpx; opacity: 0;'></canvas>

js

 data: {
 	canvasHidden:false
 },
// 线上的图片要先下载下来
 wx.getImageInfo({   //  获取二维码到本地
          src: 发请求后,后台返回的图片, 线上的图片,
          success: function (res) {
            //  console.log(res.path)
            _this.setData({
              canvasCode: res.path
            })
          }
        })
        
//  获取微信头像到本地
 wx.getImageInfo({   //  小程序获取图片信息API
              src: 发请求后,后台返回的图片,线上的微信头像,
              success: function (res) {
                _this.setData({
                  headImg: res.path
                })
              }
            })
    
    // 获取产品图
        wx.getImageInfo({   //  小程序获取图片信息API
          src:发请求后,后台返回的图片,
          success: function (res) {
            _this.setData({
              detailsBanner: res.path
            })
          }
        })

  // 生成canvas图片
  saveImageToPhotosAlbum: function () {
     that.setData({
            canvasHidden:true
          })
    var that = this;
    var unit = that.data.screenWidth / 375
    var avatarUrl = that.data.headImg
    var banner = that.data.detailsBanner
    var code = that.data.canvasCode
    var canvaBg = '/images/share.bg.png'
    var nickName = that.data.cacheMember.nickName
    var context = wx.createCanvasContext('share')
    context.setFillStyle('#5ebdff')
    context.fillRect(0, 0, 375 * unit, 1320 * unit)
    context.setFillStyle('#fff')
    context.fillRect(unit * 15, unit * 118, unit * 345, unit * 610)
    var description = that.data.detailsContent.prizeDesc
    var wxappName = `抽奖说明${description}`
    context.save()
    context.beginPath()
    context.arc(unit * 164 + (unit * 50) / 2, unit * 15 + (unit * 50) / 2, (unit * 50) / 2, 0, 2 * Math.PI)
    context.clip()
    context.drawImage(avatarUrl, unit * 164, unit * 15, unit * 50, unit * 50)
    context.restore()
    context.drawImage(banner, unit * 25, unit * 130, unit * 325, unit * 164.6)
    context.drawImage(code, unit * 158, unit * 490, unit * 80, unit * 80)
    context.setFontSize(15);
    context.setFillStyle('#333333');
    if (that.data.detailsContent.lotteryPrizes.length > 0) {
      let str = `一等奖:${that.data.detailsContent.lotteryPrizes[0].name} X ${that.data.detailsContent.lotteryPrizes[0].copies}`;
      // that.drawText(context, str, 30*unit, (250 + 70)*unit, 22, 290*unit);// 调用行文本换行函数
      that.dealWords({
        ctx: context,//画布上下文
        fontSize: 16,//字体大小
        word: str,//需要处理的文字
        maxWidth: 290 * unit,//一行文字最大宽度
        x: 30 * unit,//文字在x轴要显示的位置
        y: (250 + 90) * unit,//文字在y轴要显示的位置
        maxLine: 1//文字最多显示的行数
      })
    }
    if (that.data.detailsContent.lotteryPrizes.length > 1) {
      let er = `二等奖:${that.data.detailsContent.lotteryPrizes[1].name} X ${that.data.detailsContent.lotteryPrizes[1].copies}`;
      // that.drawText(context, str, 30*unit, (250 + 70)*unit, 22, 290*unit);// 调用行文本换行函数
      that.dealWords({
        ctx: context,//画布上下文
        fontSize: 16,//字体大小
        word: er,//需要处理的文字
        maxWidth: 290 * unit,//一行文字最大宽度
        x: 30 * unit,//文字在x轴要显示的位置
        y: (250 + 120) * unit,//文字在y轴要显示的位置
        maxLine: 1//文字最多显示的行数
      })
    }
    if (that.data.detailsContent.lotteryPrizes.length > 2) {
      let san = `三等奖:${that.data.detailsContent.lotteryPrizes[2].name} X ${that.data.detailsContent.lotteryPrizes[2].copies}`;
      // that.drawText(context, str, 30*unit, (250 + 70)*unit, 22, 290*unit);// 调用行文本换行函数
      that.dealWords({
        ctx: context,//画布上下文
        fontSize: 16,//字体大小
        word: san,//需要处理的文字
        maxWidth: 290 * unit,//一行文字最大宽度
        x: 30 * unit,//文字在x轴要显示的位置
        y: (250 + 150) * unit,//文字在y轴要显示的位置
        maxLine: 1//文字最多显示的行数
      })
    }
    context.setFontSize(15);
    context.setFillStyle('#999');
    that.dealWords({
      ctx: context,//画布上下文
      fontSize: 16,//字体大小
      word: wxappName,//需要处理的文字
      maxWidth: 300 * unit,//一行文字最大宽度
      x: 30 * unit,//文字在x轴要显示的位置
      y: (540 + 70) * unit,//文字在y轴要显示的位置
      maxLine: 3//文字最多显示的行数
    })
    context.setTextAlign('left')
    context.setFontSize(15);
    context.setFillStyle('#999');
    if (that.data.detailsContent.lotteryPrizes.length == 1) {
      if (that.data.detailsContent.type == 'PEOPLE') {
        context.fillText(`满${that.data.detailsContent.lotteryNumber}人 自动开奖`, unit * 30, unit * 405)
      } else if (that.data.detailsContent.type == 'TIME') {
        context.fillText(`${that.data.detailsContent.lotteryTime} 自动开奖`, unit * 30, unit * 405)
      }
    }
    else
      if (that.data.detailsContent.lotteryPrizes.length == 2) {
        if (that.data.detailsContent.type == 'PEOPLE') {
          context.fillText(`满${that.data.detailsContent.lotteryNumber}人 自动开奖`, unit * 30, unit * 435)
        } else if (that.data.detailsContent.type == 'TIME') {
          context.fillText(`${that.data.detailsContent.lotteryTime} 自动开奖`, unit * 30, unit * 435)
        }
      }
      else
        if (that.data.detailsContent.lotteryPrizes.length == 3) {
          if (that.data.detailsContent.type == 'PEOPLE') {
            context.fillText(`满${that.data.detailsContent.lotteryNumber}人 自动开奖`, unit * 30, unit * 465)
          } else if (that.data.detailsContent.type == 'TIME') {
            context.fillText(`${that.data.detailsContent.lotteryTime} 自动开奖`, unit * 30, unit * 465)
          }
        }
    context.setTextAlign('center')    // 文字居中
    context.setFillStyle('#fff')  // 文字颜色
    context.setFontSize(16)         //  字体大小
    context.fillText(nickName, unit * 200, unit * 85)
    context.setTextAlign('center')    // 文字居中
    context.setFillStyle('#fff')  // 文字颜色
    context.setFontSize(20)         //  字体大小
    context.fillText('邀请你来参加抽奖', unit * 200, unit * 110)
    context.setTextAlign('center')    // 文字居中
    context.setFillStyle('#999999')  // 文字颜色
    context.setFontSize(14)         // 字体大小
    context.fillText('长按识别小程序参与抽奖', unit * 200, unit * 590)
    // 文字居中
    context.setFillStyle('#e42626')  // 文字颜色
    context.setFontSize(16)
    context.setTextAlign('left')       // 字体大小
    context.fillText(`${that.data.detailsContent.sponsorName} 赞助`, unit * 30, unit * 330)
    //把画板内容绘制成图片,并回调 画板图片路径
    context.draw(false, function () {
      wx.canvasToTempFilePath({
        canvasId: 'share',
        success: function (res) {
          that.setData({
            shareImgPath: res.tempFilePath,  // 这个就是生成的canvas图片    然后就可以在页面上显示这张图片了
            canvasHidden: false
          })
          if (!res.tempFilePath) {
            wx.showModal({
              title: '提示',
              content: '图片绘制中,请稍后重试',
              showCancel: false
            })
          }
        }
      })
    });
  },
//  处理文字换行和多出省略号显示的方法
  dealWords: function (options) {
    options.ctx.setFontSize(options.fontSize);//设置字体大小
    var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);//实际总共能分多少行
    var count = allRow >= options.maxLine ? options.maxLine : allRow;//实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数

    var endPos = 0;//当前字符串的截断点
    for (var j = 0; j < count; j++) {
      var nowStr = options.word.slice(endPos);//当前剩余的字符串
      var rowWid = 0;//每一行当前宽度    
      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, options.y + (j + 1) * 25);    //(j+1)*18这是每一行的高度        
            } else {
              options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 25);
            }
            endPos += m;//下次截断点
            break;
          }
        }
      } else {//如果当前的字符串宽度小于最大宽度就直接输出
        options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 25);
      }
    }
  },


相关标签: canvas生成图片