uniapp 微信小程序 使用canvas把页面转为图片保存到手机
用的popup组件包裹的内容
1.先写入canvas组件
2.在methods中写入方法,并在onReady中调用绘制文本的方法
onReady() {
this.capture()
},
methods: {
capture() {
// canvas绘制文本
const ctx = uni.createCanvasContext('secondCanvas',this)
// canvas布局
ctx.setFontSize(20)
ctx.setTextAlign('center')
ctx.fillText('缴费凭证', 162, 40)
ctx.setFillStyle('\#f95455')
ctx.fillText( '¥' + this.information.Total + '.00', 162, 75)
ctx.setFontSize(14)
ctx.setFillStyle('\#999999')
ctx.fillText('缴费类型', 95, 100)
ctx.fillText('缴费方式', 230, 100)
// 绘制矩形,在矩形中添加文本
ctx.setFillStyle('rgba(225,225,225,0)')
ctx.setFontSize(11)
ctx.strokeStyle = "\#333333";
ctx.moveTo(24,120)
ctx.lineTo(172,120)
ctx.lineTo(172,150)
ctx.lineTo(24,150)
ctx.lineTo(24,120)
ctx.closePath();
ctx.fill();
this.drawText(ctx,this.information.GBTypeName, 90, 120, 20, 160)
ctx.setFillStyle('\#333333')
ctx.setFontSize(13)
ctx.fillText(this.information.Paytype==1?'现金缴费':'晋享生活', 230, 120)
ctx.setFontSize(14)
ctx.setTextAlign('left')
ctx.setFillStyle('\#999999')
ctx.fillText('姓名',25,165)
ctx.setTextAlign('right')
ctx.setFillStyle('\#333333')
ctx.fillText(this.record.HName,300,165)
ctx.setTextAlign('left')
ctx.setFillStyle('\#999999')
ctx.fillText('手机号',25,195)
ctx.setTextAlign('right')
ctx.setFillStyle('\#333333')
ctx.fillText(this.record.Mobile,300,195)
ctx.setTextAlign('left')
ctx.setFillStyle('\#999999')
ctx.fillText('房号',25,225)
ctx.setTextAlign('right')
ctx.setFillStyle('\#333333')
ctx.fillText(this.record.RoomAddress,300,225)
ctx.setTextAlign('left')
ctx.setFillStyle('\#999999')
ctx.fillText('收费单位',25,255)
ctx.setTextAlign('right')
ctx.setFillStyle('\#333333')
ctx.fillText('国网晋中电力有限公司',300,255)
// 绘制虚线
ctx.setLineDash(\[2, 4\], 5);
ctx.beginPath();
ctx.moveTo(25,280);
ctx.lineTo(300, 280);
ctx.stroke();
ctx.setTextAlign('left')
ctx.setFillStyle('\#999999')
ctx.fillText('付款时间',25,310)
ctx.setTextAlign('right')
ctx.setFillStyle('\#333333')
ctx.fillText(this.information.PayTime,300,310)
ctx.setTextAlign('left')
ctx.setFillStyle('\#999999')
ctx.fillText('流水号',25,340)
ctx.setTextAlign('right')
ctx.setFillStyle('\#333333')
ctx.fillText(this.information.ID,300,340)
// canvas画布转为图片 ,有时draw调用不成功,写了个定时器
ctx.draw(setTimeout(()=>{
uni.canvasToTempFilePath({
x:0,
y:0,
width:325,
height:375,
destWidth:325,
destHeight:375,
fileType:'jpg',
canvasId: 'secondCanvas',
success: (res) => {
uni.hideLoading()
// // 保存当前绘制图片
this.tempFilePath = res.tempFilePath
},
fail: function(err) {
console.log(err, '图片生成失败')
}
})
},500))
},
// 控制绘制文本换行,百度CV的
drawText: function (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {
var lineWidth = 0;
var lastSubStrIndex = 0; //每次开始截取的字符串的索引
for (let i = 0; i < str.length; i++) {
lineWidth += ctx.measureText(str\[i\]).width;
if (lineWidth > canvasWidth) {
//因为我这个在矩形中的文本进行的换行,用的ctx.strokeText,不行用在矩形中添加文本的用ctx.<span style="font-size: 16px;">fillText</span>
ctx.strokeText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
initHeight += 11; //11为字体的高度
lineWidth = 0;
lastSubStrIndex = i;
titleHeight += 30;
}
if (i == str.length - 1) { //绘制剩余部分
ctx.strokeText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
}
}
// 标题border-bottom 线距顶部距离
titleHeight = titleHeight + 10;
return titleHeight
},
// 保存图片到本地,下面保存到手机百度CV的
savePic() {
uni.getSetting({
//获取用户的当前设置
success: res => {
if (res.authSetting\['scope.writePhotosAlbum'\]) {
//验证用户是否授权可以访问相册
uni.saveImageToPhotosAlbum({
filePath: this.tempFilePath,
success: function(res2) {
uni.hideLoading();
uni.showToast({
title: '保存成功,请从相册选择再分享',
icon: 'none',
duration: 2000
});
},
fail: function(err) {
uni.hideLoading();
uni.showToast({
title: '保存失败',
icon: 'none',
duration: 2000
});
}
});
} else {
uni.authorize({
//如果没有授权,向用户发起请求
scope: 'scope.writePhotosAlbum',
success: () => {
this.saveImageToPhotosAlbum();
},
fail: () => {
uni.showToast({
title: '请打开保存相册权限,再点击保存相册分享',
icon: 'none',
duration: 2000
});
setTimeout(() => {
uni.openSetting({
//调起客户端小程序设置界面,让用户开启访问相册
success: res2 => {
// console.log(res2.authSetting)
}
});
}, 2000);
}
});
}
}
});
},
}
3.效果图如下