uniapp使用canvas绘制卡片并下载到本地

4 篇文章 1 订阅
3 篇文章 0 订阅
该博客详细介绍了如何使用uniapp框架结合canvas组件,绘制包含图片、标题和简介的二维码,并最终将生成的图片保存到用户的相册。通过调整图片和文字的布局,确保内容始终以1.3:1的比例显示,同时对超出限制的简介进行省略号处理,实现美观且信息完整的二维码生成效果。
摘要由CSDN通过智能技术生成

效果:
在这里插入图片描述
简介最多显示3行,超过3行部分用省略号(…)代替。

代码:

<canvas style="width: 100%; height: 409px;" canvas-id="myCanvas"></canvas>
// 绘制图片
createImg (qrcode) {
	uni.showLoading({
		title: '生成中'
	})
	const that = this;
	const ctx = uni.createCanvasContext('myCanvas');
	
	uni.getImageInfo({
		src: 'http://www.test.com/demo.jpg', // 上半部分的图片地址
		success(info) {
			// 绘制图片, 原理:始终保持宽高比为1.3 : 1, 可以根据自己的情况调
			let draw_height = 225;

			if (info.height < info.width) {
				let width = info.width;
				ctx.drawImage(info.path, 0, 0, width, info.height, 0, 0, 293, draw_height);
			} else {
				let view_height = parseInt(info.width / 1.3); // 计算出可视区域的图片高度
				let height = info.height;
				if (info.height > draw_height) {
					height = parseInt((info.height - view_height) / 2); // 计算出图片绘制的y方向起点
				}
				ctx.drawImage(info.path, 0, height, info.width, view_height, 0, 0, 293, draw_height);
			}
			ctx.setFillStyle('#ffffff');
			ctx.fillRect(0, draw_height, 293, 150);

			// 绘制标题
			ctx.setFillStyle('#333333');
			ctx.setFontSize(13);
			//标题加粗
			ctx.fillText('标题', 19.5, 250);
			ctx.fillText('标题', 20, 249.5);

			// 绘制描述
			ctx.setFillStyle('#777777');
			
			// 绘制简介,超过3行用省略号(...)代替
			that.toFormateStr(ctx, that.circleDetail.content, 260, 3, 20, 275, 20);
			
			// 绘制底部矩形
			ctx.setFillStyle('#f5f5f5');
			ctx.fillRect(0, 338, 293, 71);
			
			// 绘制底部信息提示
			ctx.setFontSize(11.5);
			ctx.setFillStyle('#777777');
			ctx.fillText('达人SHOW-互动式社群新零售', 20, 368);
			ctx.fillText('扫码查看更多内容', 20, 392);
			
			// 绘制二维码
			ctx.setFillStyle('#ffffff');
			ctx.fillRect(220, 345, 56, 56);
			// qrcode:二维码url地址
			ctx.drawImage(qrcode, 224, 349, 48, 48); 
			ctx.draw(true);
			uni.hideLoading();
		}
	})
}


/**
*  	绘制换行文字
* 	@param	ctx: canvas绘图上下文
* 	@param	str: 需要绘制的文本内容
* 	@param	draw_width: 绘制的文字宽度
* 	@param	lineNum: 最多行数,比如最多显示(lineNum)3行,多出部分用'...'表示
* 	@param	startX: 绘制文字的起点 X 轴坐标
* 	@param	startY: 绘制文字的起点 Y 轴坐标
*	@param	steps: 每一行文字之间的间隔
* */ 
toFormateStr (ctx, str, draw_width, lineNum, startX, startY, steps ) {
	// 测量文本源尺寸信息(宽度)
	var strWidth = ctx.measureText(str).width;
	var startpoint = startY, keyStr = '', sreLN = strWidth / draw_width;
	// 计算文本源一共能生成多少行
	var liner = Math.ceil(sreLN);
	// 等比缩放,计算一行文本显示多少个字符
	let strlen = parseInt(str.length / sreLN);
				
	// 若文本不足一行,则直接绘制,反之大于传入的最多行数(lineNum)以省略号(...)代替
	if (strWidth  < draw_width) {
		ctx.fillText(str, startX, startpoint);
	} else {
		for (var i = 1; i < liner + 1; i++) {
			let startPoint = strlen * (i-1);
			if (i < lineNum || lineNum == -1) {
				keyStr = str.substr(startPoint, strlen);
				ctx.fillText(keyStr, startX, startpoint);
			} else {
				keyStr = str.substr(startPoint, strlen-5) + '...';
				ctx.fillText(keyStr, startX, startpoint);
				break;
			}
			startpoint = startpoint + steps;
		}
	}
}

保存到相册(canvas绘制的图):

saveImg () {
	uni.showLoading({
		title: '正在下载'
	})
	const baseW = 293, baseH = 409;
	uni.canvasToTempFilePath({
		x: 0,
		y: 0,
		width: baseW * 2,
		height: baseH * 2,
		destWidth: baseW * 2,
		destHeight: baseH * 2,
		quality: 1,
		canvasId: 'myCanvas',
		success: function(res) {
			// 在H5平台下,tempFilePath 为 base64
			uni.saveImageToPhotosAlbum({
				filePath: res.tempFilePath,
				success: function (data) {
					uni.hideLoading();
					uni.showToast({
						title: '已保存至相册!',
						icon: 'success',
						duration: 2000
					});
				}
			})
		} 
	})
}

很多方法都是直接用的uniapp官方API,盘就完了!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值