需求:
- 保存分享二维码图片,并带上logo,等其他信息
- 保存的二维码图片在页面上是不可见的(需要悄悄的画图)
- 解决方式:采用定位将canvas画布放在底部,在用一个同背景色的遮罩层挡住canvas画布
实现效果:
- 页面显示:
- 保存到相册后:
实现代码:
<!-- 遮挡canvas画布 -->
<view class="mask-box"></view>
<canvas v-show="true" class="canvas" canvas-id="saveQr"></canvas>
<script>
export default {
data() {
return {
qrImg: 'qr.png', // 二维码图片
saveLogo:'logo.png',// logo图片
qrcode:'很长的文字'
}
},
methods: {
// 点击保存二维码
saveImg() {
// 显示loading
uni.showLoading({
title:this.$t('loading.isSave')
})
// 画图
this.drawQR()
},
// 画圆角矩形
drawRound(ctx, x, y, w, h, r, fill, round) {
ctx.fillStyle = fill
ctx.fillRect(x, y, w, h)
ctx.beginPath()
ctx.fillStyle = round
ctx.moveTo(x, y)
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
ctx.moveTo(x + w, y)
ctx.arc(x + w - r, y + r, r, 0, Math.PI * 1.5, true)
ctx.moveTo(x + w, y + h)
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)
ctx.moveTo(x, y + h)
ctx.arc(x + r, y + h - r, r, Math.PI, Math.PI * 0.5, true)
ctx.fill()
ctx.closePath
},
// 画图并保存
drawQR() {
// 画笔
const ctx = uni.createCanvasContext('saveQr')
// 填充背景
ctx.fillStyle = '#0871EA'
ctx.fillRect(0, 0, 371, 533)
// 在画布中插入图片,需要等待图片加载完成,使用 uni.getImageInfo方法等待图片加载完成。
uni.getImageInfo({
src: this.saveLogo,
// 在complete回调中处理,解决IOS兼容问题
complete: res => {
// 画logo
ctx.drawImage(this.saveLogo, 92, 469, 192, 40)
// 画圆角矩形
this.drawRound(ctx, 16, 24, 343, 421, 8, '#ffffff', '#0871EA')
this.drawRound(ctx, 92, 85, 192, 24, 12, '#F5F7F9', '#ffffff')
// 画二维码边框
ctx.strokeStyle = '#F6F6F6'
ctx.strokeRect(88, 125, 200, 200)
// 二维码图片
uni.getImageInfo({
src: this.qrImg,
complete: res => {
// 画二维码
ctx.drawImage(this.qrImg, 88, 125, 200, 200)
// 文字样式
ctx.textAlign = 'center'
ctx.setTextBaseline('top')
ctx.fillStyle = "#162032"
// 插入文字
ctx.font = 'bold 14px sans-serif';
ctx.fillText('文字', 187.5, 50)
ctx.fillText('文字', 187.5, 350)
ctx.font = '12px sans-serif';
ctx.fillText('文字', 187.5, 92)
ctx.font = 'normal 14px sans-serif';
// 两行显示
ctx.fillStyle = "#717378"
ctx.fillText(this.qrcode.slice(0, 30), 187.5, 381)
ctx.fillText(this.qrcode.slice(30), 187.5, 400)
// 最后画出样式,画完后接收一个回调
ctx.draw(true, () => {
// 使用定时器,保存图片太快,导致图片空白
setTimeout(()=>{
// 画图完成 保存图片
uni.canvasToTempFilePath({
canvasId: 'saveQr',
success: res => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
this.$u.toast('保存成功')
},
fail: () => {
this.$u.toast('保存失败')
},
complete() {
uni.hideLoading() // 取消loading
}
})
}
}, this) // 传入this,解决部分兼容问题
},100)
})
}
})
}
})
},
}
}
</script>
<style lang="scss" scoped>
// 使用定位遮住canvas画布
.mask-box {
background-color: $uni-bg-color;
position: absolute;
top: 0;
left: 0;
width: 375px;
height: 533px;
z-index: -1;
}
.canvas {
position: absolute;
top: 0;
left: 0;
width: 375px;
height: 533px;
z-index: -10;
}
</style>