uniapp 微信小程序 使用canvas把页面转为图片保存到手机
发布于 3 年前 作者 xiuying01 4821 次浏览 来自 分享

用的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>

	&nbsp; &nbsp; &nbsp; &nbsp; ctx.strokeText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分

	&nbsp; &nbsp; &nbsp; &nbsp; initHeight += 11; //11为字体的高度

	&nbsp; &nbsp; &nbsp; &nbsp; lineWidth = 0;

	&nbsp; &nbsp; &nbsp; &nbsp; lastSubStrIndex = i;

	&nbsp; &nbsp; &nbsp; &nbsp; titleHeight += 30;

	&nbsp; &nbsp; &nbsp; }

	&nbsp; &nbsp; &nbsp; if (i == str.length - 1) { //绘制剩余部分

	&nbsp; &nbsp; &nbsp; &nbsp; ctx.strokeText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);

	&nbsp; &nbsp; &nbsp; }

	&nbsp; &nbsp; }

	&nbsp; &nbsp; // 标题border-bottom 线距顶部距离

	&nbsp; &nbsp; titleHeight = titleHeight + 10;

	&nbsp; &nbsp; return titleHeight

	&nbsp; },

	// 保存图片到本地,下面保存到手机百度CV的

	savePic() {

	&nbsp; &nbsp; uni.getSetting({

	&nbsp; &nbsp; 	//获取用户的当前设置

	&nbsp; &nbsp; 	success: res =&gt; {

	&nbsp; &nbsp; 		if (res.authSetting\['scope.writePhotosAlbum'\]) {

	&nbsp; &nbsp; 			//验证用户是否授权可以访问相册

					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

							});

						}

					});

	&nbsp; &nbsp; 		} else {

	&nbsp; &nbsp; 			uni.authorize({

	&nbsp; &nbsp; 				//如果没有授权,向用户发起请求

	&nbsp; &nbsp; 				scope: 'scope.writePhotosAlbum',

	&nbsp; &nbsp; 				success: () =&gt; {

	&nbsp; &nbsp; 					this.saveImageToPhotosAlbum();

	&nbsp; &nbsp; 				},

	&nbsp; &nbsp; 				fail: () =&gt; {

	&nbsp; &nbsp; 					uni.showToast({

	&nbsp; &nbsp; 						title: '请打开保存相册权限,再点击保存相册分享',

	&nbsp; &nbsp; 						icon: 'none',

	&nbsp; &nbsp; 						duration: 2000

	&nbsp; &nbsp; 					});

	&nbsp; &nbsp; 					setTimeout(() =&gt; {

	&nbsp; &nbsp; 						uni.openSetting({

	&nbsp; &nbsp; 							//调起客户端小程序设置界面,让用户开启访问相册

	&nbsp; &nbsp; 							success: res2 =&gt; {

	&nbsp; &nbsp; 								// console.log(res2.authSetting)

	&nbsp; &nbsp; 							}

	&nbsp; &nbsp; 						});

	&nbsp; &nbsp; 					}, 2000);

	&nbsp; &nbsp; 				}

	&nbsp; &nbsp; 			});

	&nbsp; &nbsp; 		}

	&nbsp; &nbsp; 	}

	&nbsp; &nbsp; });

	},

}

3.效果图如下

2 回复

你好棒棒哦

回到顶部