一、获取二维码
uni.request({
url: `https://api.weixin.qq.com/wxa/getwxacode?access_token=${getStorage("token")}`,
responseType: "arraybuffer",
method: "POST",
data: {
path: "/pages/index/index"
},
success(res) {
// 转换为 Uint8Array 类型的数组
const arrayBuffer = new Uint8Array(res.data)
// 转换为 Base64 编码的字符串
const base64 = uni.arrayBufferToBase64(arrayBuffer)
// 缓存至本地
state.image = base64
},
fail(err) {
console.log(err, "err")
}
})
代码仅作示例
以上代码作用就是,拿到后端给的base64格式的图片,用做绘图
二、绘制画布
const handleCanvas = () => {
//初始化画布
const ctx = uni.createCanvasContext('myCanvas');
ctx.setFillStyle("rgba(96, 216, 254, 1)")
ctx.fillRect(0, 0, uni.upx2px(750), uni.upx2px(1120))
//外边框
const mx = uni.upx2px(55)
const my = uni.upx2px(332);
const mwidth = uni.upx2px(640);
const mheight = uni.upx2px(640);
const mradius = uni.upx2px(32);
const mColor = "#DFF3FF"
_border(ctx, mx, my, mwidth, mheight, mradius, mColor)
// 内边框
const px = uni.upx2px(105)
const py = uni.upx2px(382);
const pwidth = uni.upx2px(540);
const pheight = uni.upx2px(540);
const pradius = uni.upx2px(32);
const pColor = "#FFF"
_border(ctx, px, py, pwidth, pheight, pradius, pColor)
//二维码
_QRCode(ctx, state.image)
// 绘制画布
ctx.draw()
}
// 绘制边框 参数分别为 画布对象 画布x轴起点 画布y轴起点 画布宽度 画布高度 圆角边框 背景色
const _border = (ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, color: string) => {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.arcTo(x + width, y, x + width, y + radius, radius);
ctx.lineTo(x + width, y + height - radius);
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
ctx.lineTo(x + radius, y + height);
ctx.arcTo(x, y + height, x, y + height - radius, radius);
ctx.lineTo(x, y + radius);
ctx.arcTo(x, y, x + radius, y, radius);
ctx.closePath();
ctx.fillStyle = color;
ctx.fill();
}
const _QRCode = (ctx, data) => {
// 获取文件管理器
const fsm = wx.getFileSystemManager();
// 将 base64 字符串转成 ArrayBuffer对象
const buffer = wx.base64ToArrayBuffer(data);
// 文件系统中的用户目录路径 (本地路径)
const fileName = wx.env.USER_DATA_PATH + '/share_img.png';
fsm.writeFileSync(fileName, buffer, 'binary'); // 写入文件, 同步方法
// 以上四行代码让其在真机上正常显示,因为canvas无法读取base64格式,需要先保存在文件管理器,拿到临时路径
ctx.drawImage(fileName, uni.upx2px(135), uni.upx2px(412), uni.upx2px(480), uni.upx2px(480))
}
1.复杂样式尽量使用图片引入 ctx.drawImage("换成你本地图片的相对路径",...)
2.需要其他样式或者图片,自行添加,我这个应该还有个背景图的,在等UI出图
3.画布绘制的顺序需要注意下,后面覆盖的图形会把前面的图形在视觉上覆盖掉,所以二维码方法要写在最后面
三、保存至相册
const handleSave = () => {
uni.showLoading({
title: '正在生成海报',
mask: true
})
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
uni.showToast({
title: '保存成功',
icon: 'none'
})
}
})
},
complete(result) {
uni.hideLoading()
},
})
}