(wepy)小程序 canvas画出海报

在这里插入图片描述

<template>
<!--分享-->
<view>

    <canvas canvas-id="myQrcode" id="myQrcode" style=" border:1px solid #c3c3c3;width:750px;height:1334px;position:fixed;z-index:-1;top:-10000000px; opacity:0;pointer-events: none;"  catchtouchmove = "true"></canvas>

    <image style="width:520rpx;height:925rpx; " src="{{shareImg}}" ></image>
    <view style=" position:fixed; bottom:30rpx;left:0; width:100%;"@tap="saveImage">保存到本地</view>

      <button class="share-model-btn"
              @tap='setShareInfo'
              style=" position:fixed; height:20rpx; bottom:0;left:0; width:100%;"
              catchtouchmove = "true">
              生成海报
      </button>

</view>
</template>
  methods = {
  
     // 生成海报- 下载图片 -其他信息准备
    async setShareInfo () {
      wx.showLoading({
        title: '正在生成图片'
      })

      let that = this
      that.productImg = '图片路径'; // 图片路径 后端返回图片路径
      that.qrcode = '小程序码路径' ; // 小程序码,后端返回png图片路径。 注意:base64无法绘制
      that.productName = '橙子大甩卖橙子大甩卖橙子大甩卖橙子大甩卖橙子大甩卖';
      that.price = '100.00';
      that.oriPrice = '200.00';
      that.$apply()
      // 图片下载
      return new Promise(async (resolve, reject) => {
        that.productImg = await that.downLoadImg(that.productImg)
        that.qrcode = await that.downLoadImg(that.qrcode)
        resolve(that.productImg, that.qrcode)
        that.canvasCreat()
      })
    },

    // 保存图片
    saveImage() {
      let that = this
      // 获取用户是否开启用户授权相册
      // console.log('保存到本地')
      wx.getSetting({ success(res) {
        // 如果没有则获取授权
        if (!res.authSetting['scope.writePhotosAlbum']) {
          wx.authorize({
            scope: 'scope.writePhotosAlbum',
            success() {
              wx.saveImageToPhotosAlbum({
                filePath: that.data.shareImg,
                success() {
                  that.shareImgFlag = 0
                  that.$apply()
                  wx.showToast({
                    title: '保存成功'
                  })
                },
                fail() {
                  wx.showToast({
                    title: '保存失败',
                    icon: 'none'
                  })
                }
              })
            },
            fail() {

              // (ps:重新打开授权信息,微信api现在只能通过button才能打开授权设置)
            }
          })
        } else {
          // 已授权 直接保存
          wx.saveImageToPhotosAlbum({
            filePath: that.data.shareImg,
            success() {
              that.shareImgFlag = 0
              that.$apply()
              wx.showToast({
                title: '保存成功'
              })
            },
            fail() {
              wx.showToast({
                title: '保存失败',
                icon: 'none'
              })
            }
          })
        }
      }
      })
    }
  };
   // 下载图片,下载到本地,供绘图使用
  downLoadImg(url) {
    return new Promise(async (resolve, reject) => {
      let result = ''
      wx.getImageInfo({
        src: url,
        success (res) {
          result = res.path
          resolve(result)
        },
        fail(res) {
          // console.log(res, '失败')
          wx.showToast({
            title: '下载图片失败',
            icon: 'none'
          })
        }
      })
    })
  }
    // 绘制海报
  canvasCreat() {
    return new Promise(async (resolve, reject) => {
      const ctx = wx.createCanvasContext('myQrcode')
      ctx.setFillStyle('white')
      ctx.fillRect(0, 0, 750, 1334)
      ctx.stroke() // 不加这句会是下面的arc失效
      ctx.draw()

      let width = 750
      let proName = this.productName.slice(0, 42)
      
      let proPrice = ''
        proPrice = '¥ ' + this.price.toFixed(2)

        // 画出价格
        ctx.setFontSize(30)
        ctx.setTextAlign('left')
        if (wx.getStorageSync('theme') === 'blue') {
          ctx.setFillStyle('#3b99da')
        } else {
          ctx.setFillStyle('#DD2726')
        }
        ctx.fillText(
              proPrice,
              (width / 750) * 54,
              (width / 750) * 930
            )
    
      let origPrice = '¥ ' + this.oriPrice.toFixed(2)


      // 画出产品标题
      ctx.setFontSize(32)
      ctx.setFillStyle('#333333')
      ctx.setTextAlign('left')
      const nameWidth = ctx.measureText(proName).width
      this.wordsWrap(ctx, proName, nameWidth, 620, 56, 812, 40)


      // 画出产品图像
      ctx.drawImage(
        this.productImg,
        (width / 750) * 55,
        (width / 750) * 100,
        (width / 750) * 640,
        (width / 750) * 640
      )


      // 原价不为0 才绘画
      if (this.oriPrice !== 0) {
     // 画出原价
        ctx.setFontSize(24)
        ctx.setTextAlign('left')
        ctx.setFillStyle('#CCCCCC')
        ctx.fillText(
        origPrice,
        (width / 750) * 54,
        (width / 750) * 978
      )
      // 画出原价的横线
        let dis = (this.oriPrice.toFixed(2).length + 1) * 14
        ctx.beginPath()
        ctx.moveTo(
        (width / 750) * 50,
        (width / 750) * 970)
        ctx.lineTo(
        (width / 750) * 56 + (width / 750) * dis,
        (width / 750) * 970)
        ctx.setStrokeStyle('#CCCCCC')
        ctx.setLineWidth(1)
        ctx.setFillStyle('#CCCCCC')
        ctx.stroke()
      }
      ctx.draw(true)


      ctx.rect(270, 1035, 240, 240)
      ctx.setFillStyle('#ffffff')
      ctx.fill()

      ctx.drawImage(
        this.qrcode,
        (width / 750) * 270,
        (width / 750) * 1035,
        (width / 750) * 210,
        (width / 750) * 210
      )
        // 画出“扫一扫”
      ctx.setFontSize(26)
      ctx.setTextAlign('left')
      ctx.setFillStyle('#333333')
      ctx.fillText(
        '长按或扫一扫',
        (width / 750) * 298,
        (width / 750) * 1293
      )

      ctx.draw(true)
      let _this = this
      setTimeout(() => {
        wx.canvasToTempFilePath({
          x: 0,
          y: 0,
          width: (width / 750) * 1080,
          height: (width / 750) * 1920,
          destWidth: (width / 750) * 1080,
          destHeight: (width / 750) * 1920,
          canvasId: 'myQrcode',
          fileType: 'jpg',
          success(res) {
            wx.hideLoading()
            _this.moveFlag = 0
            _this.shareImg = res.tempFilePath
            _this.shareImgFlag = 1
            _this.$apply()
            // 绘画成功
          },
          fail (err) {
            wx.showToast({
              title: '生成失败,' + err,
              icon: 'none'
            })
          }
        })
      }, 1000)
    })
  }
  //  商品标题换行
  wordsWrap(ctx, name, nameWidth, maxWidth, startX, srartY, wordsHight) {
    let lineWidth = 0
    let lastSubStrIndex = 0
    for (let i = 0; i < name.length; i++) {
      lineWidth += ctx.measureText(name[i]).width
      if (lineWidth > maxWidth) {
        ctx.setFontSize(32)
        ctx.fillText(name.substring(lastSubStrIndex, i), startX, srartY)
        srartY += wordsHight
        lineWidth = 0
        lastSubStrIndex = i
      }
      if (i === name.length - 1) {
        ctx.fillText(name.substring(lastSubStrIndex, i + 1), startX, srartY)
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值