uniapp canvas 生成海报 小程序码 二维码

uniapp  canvas 生成超简单海报带小程序码

canvas官网链接,可以先看下官方介绍,更好理解

uniapp官网canvas介绍

一、首先自定义一个生成海报的组件 uni-xcxcanvas.vue,创建同名目录

模板文件代码:

<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代码

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

二、使用组件 uni-xcxcanvas

 @generateImageSuccessful:组件返回结果返回到父类

MYXqOption:父类数据渲染到组件

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

详细代码如下:

<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;
	},

生成海报如下图:一个背景图、一个小程序太阳码

猜你喜欢

转载自blog.csdn.net/u014724048/article/details/131782903