canvas绘制微信海报分享

background-color: rgba(255, 255, 255, 0.5);

display: flex;

justify-content: center;

align-items: center;

}

.generate-qorcode-container .canvas {

margin: 0 auto;

}

.generate-qorcode-container generate-qorcode-save {

padding-top: 24rpx;

padding-bottom: 30rpx;

background-color: #fff;

}

.generate-qorcode-container .save-text {

width: 100%;

margin-bottom: 21rpx;

font-size: 26rpx;

line-height: 1.5;

color: #999;

text-align: center;

}

.generate-qorcode-container .save-btn-box {

width: 100%;

display: flex;

justify-content: center;

align-items: center;

}

.generate-qorcode-container .save-btn-box .save-btn {

width: 300rpx;

height: 60rpx;

line-height: 60rpx;

font-size: 25rpx;

border-radius: 8rpx;

text-align: center;

color: #fff;

background: -webkit-linear-gradient(left, #4a9eff, #24c1ff);

}




这里我们为了让加载可以居中,使用了position:relative属性,并且top/bottom/left/right均为0 ,这样可以在父元素未定宽高的情况下居中,并且使用了z-index,将整个loading,置于画面之上。



#### []( )2.4 最终效果



![](https://img-blog.csdnimg.cn/img_convert/b71a0c34b72d5be8600462463322f59d.png)



### []( )3 核心代码



#### []( )3.1 定义所需数据



**「背景图片」** **「logo」** **「二维码」** **「设备的图片像素比」** **「是否加载中」** **「canvs的宽」** **「canvas的高」**



data: {

bgImg: '/resources/images/bg.png',

logoImg :'/resources/images/juejin.png', 

QRCodeImg :'/resources/images/qrcode.png',

pixelRatio: 2,

loading: false,

canvasW:0,

canvasH:0

},




#### []( )3.2 初始化数据



通过微信官方提供的getSystemInfo方法,获取手机的图片像素比,屏幕的宽高,图片像素比在进行海报下载的时候会用到,主要是用来优化图片的像素,显示的更加清晰。



// 在组件完全初始化完毕

attached() {

let that = this

// 进入页面,出现开始加载的画面

that.setData({

  loading: true,

})

// 获取设备宽度,计算canvas宽高

wx.getSystemInfo({

  success: function (res) {

    // 这里没有设置canvas的宽高为100%

    that.setData({

      pixelRatio: res.pixelRatio, // 图片像素比

      canvasW:res.screenWidth * 0.8,

      canvasH:res.screenWidth * 0.8 *1.3

    })

  }

})

},




#### []( )3.3 开始绘制



##### []( )获取canvas对象



let that = this

const ctx = wx.createCanvasContext(‘qrcodeCanvas’, that)




##### []( )绘制背景图片



ctx.drawImage(that.data.bgImg, 0, 0, that.data.canvasW, that.data.canvasH)




效果



![](https://img-blog.csdnimg.cn/img_convert/aa1c5848b45908dc3fa49a3f33f61ac8.png)



##### []( )绘制二维码下面的白底



首先找出各个顶点的位置, 为了好看,使用arcTo函数加上一点圆角。半径为5。



// 设定起始位置,宽高

  let rect = {

    x:  ( that.data.canvasW-(that.data.canvasW*0.7))/2,

    y:100,

    width: that.data.canvasW*0.7,

    height: that.data.canvasW*0.7 *1.2

  }



  // 计算各个位置的坐标

  let ptA = that.point(rect.x + 5, rect.y)

  let ptB = that.point(rect.x + rect.width, rect.y)

  let ptC = that.point(rect.x + rect.width, rect.y + rect.height)

  let ptD = that.point(rect.x, rect.y + rect.height)

  let ptE = that.point(rect.x, rect.y)



  // 按照坐标开始绘制

  ctx.beginPath()

  ctx.moveTo(ptA.x, ptA.y)

  ctx.arcTo(ptB.x, ptB.y, ptC.x, ptC.y, 5)

  ctx.arcTo(ptC.x, ptC.y, ptD.x, ptD.y, 5)

  ctx.arcTo(ptD.x, ptD.y, ptE.x, ptE.y, 5)

  ctx.arcTo(ptE.x, ptE.y, ptA.x, ptA.y, )

  // 填充颜色,保存画笔位置

  ctx.strokeStyle = "#fff"

  ctx.stroke()

  ctx.setFillStyle('#fff')

  ctx.fill()

  ctx.save()

//辅助函数

point(x, y) {

  return {

    x,

    y

  }

},



效果



![](https://img-blog.csdnimg.cn/img_convert/089d4a1a3e23c4ef9665bcb49517535e.png)



#### []( )绘制logo框



这里主要是用到了两个圆,一个大一个小,半径相差1,这样头像就有了边框。



绘制大圆



ctx.beginPath()

ctx.arc(that.data.canvasW/2, 100,35, 0, Math.PI * 2, false)

ctx.setFillStyle(‘#eee’)

ctx.fill()

ctx.save()




绘制小圆 这里绘制小圆之后, 使用clip方法 ,使得之后的绘图都会被限制在被剪切的区域内。



// 画小圆

ctx.beginPath()

ctx.arc(that.data.canvasW/2, 100,34, 0, Math.PI * 2, false)

ctx.setFillStyle(‘#fff’)

ctx.fill()

ctx.clip()




绘制logo图片



ctx.drawImage(

that.data.logoImg,

that.data.canvasW / 2 - 34,

66,

68,

68

)

// 恢复画布

ctx.restore()




效果



![](https://img-blog.csdnimg.cn/img_convert/8c24ad04b9fcc8d2b662ff960079a5ad.png)



#### []( )绘制二维码



// 绘制二维码

ctx.drawImage(that.data.QRCodeImg,( that.data.canvasW -140 )/2,150, 140, 140)

// 说明文字

ctx.setTextAlign(‘center’)

ctx.setFontSize(14)

ctx.setFillStyle(‘#666’)

console.log(( that.data.canvasW -140 )/2)

ctx.fillText(‘长按小程序码,查看详情’, that.data.canvasW-150 , 320)




效果



![](https://img-blog.csdnimg.cn/img_convert/d92f20fa30c90b0b9619de9c691a1a5f.png)



#### []( )关闭加载动画



ctx.draw(true, () => {

that.setData({

  loading: false

})

})




#### []( )总结



至此使用canvas绘制海报的流程已经结束了,总体看来还是比较简单的,难一点的地方就是具体坐标的计算,建议大家在草稿纸上画个草图,方便计算坐标。



下面就开始实现用户下载的功能。



### []( )4\. 两步走下载图片



#### []( )4.1 canvasToTempFilePath



// 保存图片

save() {

  let that = this

  wx.canvasToTempFilePath({

    x: 0, // 起点横坐标

    y: 0, // 起点纵坐标

    width: that.data.canvasW, 

    height: that.data.canvasH, 

    destWidth: that.data.canvasW * that.data.pixelRatio, 

    destHeight: that.data.canvasH * that.data.pixelRatio, 

    canvasId: 'qrcodeCanvas',

    success: function (res) {

      //调取小程序当中获取图片

      wx.saveImageToPhotosAlbum({

        filePath: res.tempFilePath,

        success(res) {

          wx.showToast({

            title: '图片保存成功!',

            icon: 'none'

          })

        },

        fail: function (res) {

          console.log(res)

          if (res.errMsg === "saveImageToPhotosAlbum:fail auth deny" || res.errMsg === "saveImageToPhotosAlbum:fail:auth denied") {

            that.doAuth()

          }

        }

      })

    },

    fail: function (res) {

      console.log(res)

    }

  }, this)

},



#### []( )4.2 获取保存图片的权限



step1: 弹出授权对话框



step2: 打开seetting页面



step3: 判断



// 获取授权

doAuth() {

  wx.showModal({

    title: '获取授权',

    content: '同意重新授权保存图片?',

    cancelText: '不同意',

    confirmText: '同意',

    confirmColor: '#21c0ae',

    success: function (res) {

      if (res.confirm) {

        wx.openSetting({

          success(settingdata) {

            if (settingdata.authSetting["scope.writePhotosAlbum"]) {

              console.log("获取权限成功")

            } else {

              console.log("获取权限失败")

            }

          },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值