微信小程序-uni 使用 canvas 画图生成图片 自定义转发

<template>
    <div class="box">
      <canvas :style="{ width: '424px', height: '338px' }" canvas-id="firstCanvas" id="firstCanvas" class="myCanvas"></canvas>
      <button open-type="share">转发</button>
    </div>
</template>

<script>
export default {
  data() {
    return {
      tempFilePath: '' // 图片路径
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    async init() {
      await this.drawing()
    },
    async drawing() {
      const width = 424 // 设计稿2倍像素
      const height = 338 // 设计稿2倍像素
      var ctx = uni.createCanvasContext('firstCanvas') // 获取canvas 上下文
      ctx.setFillStyle('#1A1A1A') // 设置画笔颜色
      ctx.fillRect(0, 0, width, height) // 填充背景色 x,y,w,h

      // drawingImg // 获取图片信息
      // 一下 * 2 均为设计稿2倍像素
      const p1 = await this.drawingImg('https://images.snsports.cn/share_bj.png')
      ctx.drawImage(p1, 0, 0, width, 102 * 2) // 渲染图片 imgUrl,x,y,w,h
      const p2 = await this.drawingImg('https://images.snsports.cn/share_title.png')
      ctx.drawImage(p2, 43 * 2, 21 * 2, 126 * 2, 49 * 2)
      const p3 = await this.drawingImg('https://images.snsports.cn/share_icon.png')
      ctx.drawImage(p3, 172 * 2, 12 * 2, 20 * 2, 23 * 2)

      // 赛事头像
      ctx.save()
      ctx.arc(107 * 2, 97 * 2, 21 * 2, 0, 2 * Math.PI) // 圆形边框
      ctx.strokeStyle = '#1A1A1A' // 设置绘制圆形边框的颜色
      ctx.stroke() // 绘制出圆形,默认为黑色,可通过 ctx.strokeStyle = '#FFFFFF',设置想要的颜色
      ctx.clip()
      const p4 = await this.drawingImg('https://images.snsports.cn/Fnc16mRJhlgjt8HI75K778MkEKuA?imageView2/1/w/0/h/0')
      ctx.drawImage(p4, 86 * 2, 76 * 2, 42 * 2, 42 * 2)
      ctx.restore()
      // 赛事名称
      let name = '"激扬青春•快乐健康"2019年海南省青少年足球赛省'
      name = name.split('')
      const name1 = name.splice(0, 15).join('')
      const name2 = name.splice(0, 15).join('')
      const name3 = name.splice(0, 15).join('')
      console.log(ctx.measureText(name1).width) // 渲染文章将用到多少宽度
      ctx.setFillStyle('#fff')// 文字颜色:默认黑色
      ctx.setFontSize(24)// 设置字体大小
      ctx.textAlign = 'center' // 文字居中 以设置的x轴点为中心点
      if (!name2 && !name3) { // 判断当一行文章显示的位置
        ctx.fillText(name1, 107 * 2, 147 * 2)
      } else if (!name3) { // 判断当两行文章显示的位置
        ctx.fillText(name1, 107 * 2, 140 * 2)
        ctx.fillText(name2, 107 * 2, 156 * 2)
      } else { // 判断当三行文章显示的位置
        ctx.fillText(name1, 107 * 2, 132 * 2)
        ctx.fillText(name2, 107 * 2, 147 * 2)
        ctx.fillText(name3, 107 * 2, 162 * 2)
      }
      // ctx.fill()
      ctx.draw()
      new Promise((resolve, reject) => {
        uni.canvasToTempFilePath({ // 将canvas转为图片
          x: 0, // 转为图片的起点
          y: 0, // 转为图片的起点
          width: width, // 从起点开始的宽度
          height: height, // 从起点开始的高度
          destWidth: width * 2, // 生成图片的宽
          destHeight: height * 2, // 生成图片的高
          canvasId: 'firstCanvas',
          success: res => {
            resolve(res.tempFilePath)
          },
          fail(err) {
            reject(err)
            console.log(err)
          }
        })
      }).then(res => {
        this.tempFilePath = res // 生成图片的路径
        console.log(this.tempFilePath)
      }).catch(() => {
        console.log('xxx')
      })
    },
    drawingImg(src) {
      return new Promise((resolve, reject) => {
        uni.getImageInfo({
          src,
          success(img) {
            resolve(img.path)
          },
          fail(err) {
            reject(err)
          }
        })
      })
    }
  }
}
</script>

<style scoped lang="scss">
.box{
  display: flex;
  flex-direction: column;
  align-items: center;
}
.myCanvas{
  
}
button{
  margin-top: 30rpx;
}
</style>

案例中 圆设计图宽高为 212px 76px 没设置 2 倍图片时分享出去图片非常模糊

小程序中cnavas不能使用 rpx。如果需要兼容,可通过获取屏幕宽高自己进行计算
 

效果图1:


效果图2:没设置2倍图时

 

 效果图3: 二倍图

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值