uniapp canvas generates poster applet code QR code

uniapp canvas generates super simple poster with small program code

Canvas official website link, you can read the official introduction first to understand better

uniapp official website canvas introduction

1. First customize a poster-generating component uni-xcxcanvas.vue and create a directory with the same name

Template file code:

<template>
	<view>
		<view :z-index="90" :show="share_qrcode_flag" :zoom="true" :custom-style="{ background: 'rgba(0,0,0,.6)' }"
			:duration="300">
			<view class="share_qrcode">
				<canvas canvas-id="myCanvas" class="canvas-view"></canvas>
				<image @longpress="this.showSaveImgWin = true" class="show-img-view"
					:src="canvasToTempFilePath"></image>
			</view>

		</view>
	</view>
</template>


<style lang="scss">
	.canvas-view {
		width: 690px;
		height: 1060px;
		position: fixed;
		top: -10000px;
		left: -10000px;
	}

	.show-img-view {
		width: 100%;
		height: 100%;
		border-radius: 10rpx;
	}
</style>

js code

<script>
	export default {
		name: 'tr-xqgenrate',
		props: {
			MyXqOption: {}
		},
		data() {
			return {
				ratio: 1,
				ctx: null, // 创建canvas对象
				canvasToTempFilePath: null, // 保存最终生成的导出的图片地址
				openStatus: true, // 声明一个全局变量判断是否授权保存到相册
				share_qrcode_flag: false,
				showSaveImgWin: false, //保存图片到相册
			};
		},
		mounted() {
			this.share_qrcode(this.MyXqOption)
		},
		methods: {
			Close() {
				this.share_qrcode_flag = false
				setTimeout(() => {}, 180)
			},
			share_qrcode(XqOption) {
				if (!this.canvasToTempFilePath) {
					this.createCanvasImage(XqOption);
				} else {}
				this.share_qrcode_flag = true;
			},
			
			// 生成海报
			async createCanvasImage(option) {
				var that = this
				if (!this.ctx) {
					uni.showLoading({
						title: '正在生成海报...'
					});
					let code = this.downloadFileImg(option.codeUrl); //小程序太阳码
					let cover = this.downloadFileImg(option.GoodsImage); //商品图片
					let headImg = '' //店铺头像
					let bgUrl = ''; //背景图片
					if (option.bgUrl) {
						bgUrl = new Promise(resolve => {
							uni.downloadFile({
								url: option.bgUrl,
								success: res => {
									console.log("res.tempFilePath====", res.tempFilePath)
									resolve(res.tempFilePath);
								},
								fail: erros => {
									uni.showToast({
										title: '请求错误请重试',
										icon: 'loading'
									});
								}
							});
						});
					}
					//headImg:头像,暂未使用,对应的result[0]
					Promise.all([headImg, code, cover, bgUrl]).then(result => {
						const ctx = uni.createCanvasContext('myCanvas', this);
						let canvasWidthPx = 620 * this.ratio,
							canvasHeightPx = 1060 * this.ratio,
							codeurl_width = 110, //小程序太阳码宽度
							codeurl_heigth = 110, //小程序太阳码高度
							codeurl_x = 545, //小程序太阳码在画布上的位置
							codeurl_y = 920, //小程序太阳码在画布上的位置
							coverurl_width = 690, //封面宽度
							coverurl_heigth = 1060, //封面高度
							coverurl_x = 0, //封面在画布上的位置
							coverurl_y = 0, //封面在画布上的位置
						//绘制圆角矩形
						ctx.save();
						ctx.translate(0, 0);
						//绘制圆角矩形的各个边
						this.drawRoundRectPath(ctx, 690, 1060, 10);
						ctx.fillStyle = option.fillStyle || '#ffffff';
						ctx.fill();
						ctx.restore();
						ctx.save();
						ctx.beginPath(); //开始绘制
						ctx.clip();
						ctx.restore();
						ctx.drawImage(result[2], coverurl_x, coverurl_y, coverurl_width,
							coverurl_heigth);
						ctx.drawImage(result[1], codeurl_x, codeurl_y, codeurl_width, codeurl_heigth);
						// 绘制矩形
						ctx.lineWidth = 2;
						// ctx.setStrokeStyle('rgba(0, 0, 0, 0.05)');
						ctx.setStrokeStyle('transparent');
						this.drawRoundRect(ctx, 30, 910, 620, 120, 10)
						ctx.stroke();
						ctx.closePath();
						ctx.draw(false, () => {
							uni.canvasToTempFilePath({
									canvasId: 'myCanvas',
									success: res => {
										that.canvasToTempFilePath = res.tempFilePath;
										//将图片地址返回到父类
										that.$emit("generateImageSuccessful", res
											.tempFilePath);
										that.showSaveImgWin = true
										//保存图片到相册
										that.saveShareImg(this.canvasToTempFilePath)
										
									},
									fail: err => {
										uni.showToast({
											title: '绘制失败'
										});
									},
									complete: () => {
										uni.hideLoading();
										uni.hideToast();
									},
								},
								this
							);
						});
					});
				}
			},

			drawRoundRect(ctx, x, y, width, height, radius) { //圆角
				ctx.beginPath();
				ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
				ctx.lineTo(width - radius + x, y);
				ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
				ctx.lineTo(width + x, height + y - radius);
				ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
				ctx.lineTo(radius + x, height + y);
				ctx.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
				ctx.closePath();
			},

			drawRoundRectPath(cxt, width, height, radius) {
				cxt.beginPath(0);
				//从右下角顺时针绘制,弧度从0到1/2PI
				cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);

				//矩形下边线
				cxt.lineTo(radius, height);

				//左下角圆弧,弧度从1/2PI到PI
				cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);

				//矩形左边线
				cxt.lineTo(0, radius);

				//左上角圆弧,弧度从PI到3/2PI
				cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);

				//上边线
				cxt.lineTo(width - radius, 0);

				//右上角圆弧
				cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);

				//右边线
				cxt.lineTo(width, height - radius);
				cxt.closePath();
			},


			// 保存到系统相册
			saveShareImg(canvasToTempFilePath) {
				uni.saveImageToPhotosAlbum({
					filePath: canvasToTempFilePath,
					success: () => {
						uni.showToast({
							title: '已保存到相册',
							duration: 2000
						});
					},
					fail: () => {}
				});
			}
		}
	};
</script>

2. Use the component uni-xcxcanvas

 @generateImageSuccessful: The component returns the result to the parent class

MYXqOption: Parent class data is rendered to the component

<uni-xcxcanvas  @generateImageSuccessful="generateImageSuccessful" :MyXqOption='MyXqOption'>
</uni-xcxcanvas>

The detailed code is as follows:

<view class="downloadBtn" @click="createImage">点击下载</view>

<block v-if="isDraw">
	<view style="z-index: 100;">
		<view @click.stop="closeMask" class="mask">
			<!-- //显示一下绘制完成后的路径  aspectFill scaleToFill  aspectFit  -->
			<image :src="tempImage" mode="widthFix" style="width: 90%;height: 100%;"
						:show-menu-by-longpress="true">
			</image>
			<uni-xcxcanvas  @generateImageSuccessful="generateImageSuccessful" :MyXqOption='MyXqOption'>
			</uni-xcxcanvas>
		</view>
	</view>
</block>
async createImage() { //生成海报
	this.isDraw = true

	this.MyXqOption= {
		codeUrl: this.qrCode,
		GoodsImage: this.postImgUrl,
		StoreHeadUrl: '',
		fillStyle: '#FFFFFF',
		money: 10,
		primaryMoney: '原价',
		Sold: 1,
		GoodsName: 'dfsdfa',
		StoreName: 'sdfad',
		SoreAddress: 'sdfa',
		SoldElementLeft: 62
    }
				
},
/** 绘制成功后的回调 - 返回一个临时路径 */
generateImageSuccessful(image) {
	// this.tempImage = image
	this.uploadBanner(image, 2)
},
uploadBanner(filePath) {
		var _this = this
		let random_name = 's' + _this.random_string(6) + '_' + new Date().getTime();
		let promise = new Promise(function(resolve, reject) {
			getOssParams().then((response) => {
				uni.getFileInfo({
					filePath: filePath,
					success: res => {
						uni.uploadFile({
							url: 'https://阿里云图片存储域名',
							filePath: filePath,
							name: 'file',
							formData: {
								name: filePath,
								key: random_name,
								policy: response.policy,
								signature: response.signature,
								OSSAccessKeyId: response.accessid,
								success_action_status: '200'
							},
							success: res => {
								_this.tempImage =
									'https://阿里云图片存储域名' +
									random_name
							},
							fail: uploadFileRes => {
								reject(uploadFileRes);
							},
							complete: () => {
	
							}
						});
					},
					fail: uploadFileRes => {
	
						reject(uploadFileRes);
					}
	
				});
			}).catch(err => {
	
			})
		});
	},
//获取随机字符
    random_string(len) {
		len = len || 32;
		var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
		var maxPos = chars.length;
		var pwd = '';
		for (let i = 0; i < len; i++) {
			pwd += chars.charAt(Math.floor(Math.random() * maxPos));
		}
		return pwd;
	},

Generate a poster as shown below: a background image, a small program sun code

 

Guess you like

Origin blog.csdn.net/u014724048/article/details/131782903