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

news2024/11/26 2:34:18

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

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AtcoderABC251场

A - Six CharactersA - Six Characters 题目大意 给定一个由小写英文字母组成的字符串S&#xff0c;S的长度在1到3之间。 打印一个长度为6的字符串&#xff0c;该字符串是S的重复。 思路分析 通过将S重复拼接6次&#xff08;如果给定原字符串最小的情况&#xff09;&#xf…

【LLM】利用RoPE不微调大模型以扩展Context长度(更新中)

note 文章目录 note一、扩展LLM的Context长度1. 常见方法2. PCW方法 二、NBCE方法三、RoPE方法四、FlashAttention方法Reference 一、扩展LLM的Context长度 1. 常见方法 扩展LLM的Context长度其实已有不少&#xff0c;但多数是通过结合检索或者摘要的方式来缩短样本的长Conte…

深入学习 Redis - 常用数据类型,结构认识

目录 一、Redis数据类型 Redis 数据类型结构简单认识 每个数据类型具体的编码方式 1.string 2.hash 3.list 4.set 5.zset 典中典&#xff1a;记数字&#xff01;&#xff01;&#xff01; 6.查看 key 对应 value 的实际编码方式 如果本文有帮助到你&#xff0c;不…

古风编曲用什么软件?水果编曲FL Studio21怎么样

古风编曲需要什么乐器&#xff1f;古风编曲多采用笙、箫、二胡、古筝、琵琶、唢呐、二胡、竹笛、马头琴等中国传统乐器。古风编曲用什么软件&#xff1f;市面上几款热门软件有FL Studio、Cubase、Logic Pro等。 古风编曲需要什么乐器 我们常说的古风歌曲&#xff0c;其实是一…

CocoaPods could not find compatible versions for pod ““:

添加新的 SDK 依赖抛出了如下异常,无法找到可兼容的版本依赖库; [!] CocoaPods could not find compatible versions for pod "HDSSup":In Podfile:HDSSupSpecs satisfying the HDSSup dependency were found, but they required a higher minimum deployment targe…

使用这些ai绘画生成器,再也不愁没有好看的壁纸了

你们最近有没有发现网上开始流行ai绘画&#xff1f;我总是能看到ai绘画出来的图片&#xff0c;犹如下面这些图片。 这些图片是不是好看到&#xff0c;可以作为头像使用了&#xff1f;它们确实是ai绘画出来的&#xff0c;不过现在ai绘画软件众多&#xff0c;你们知道哪一款好用吗…

nvm node yarn

nvm node 以及node 对应的版本的npm相关配置的整理 ##如何设置npm 全局node_modules 安装目录 你可以通过 npm 的配置来设置全局安装的 node_modules 目录。默认情况下&#xff0c;npm 全局安装的包会存储在操作系统的特定目录中&#xff0c;如在 Windows 上为 C:\Users\<…

MySQL日常操作记录

1.查看MySQL版本 select version();2.快速复制表结构&#xff0c;不包含相关主键及约束 create table user_test as select * from user where 12;3.uuid select uuid(),uuid_short();4.替换uuid()里的’-‘为’’ select replace(uuid(),-,);5.md5摘要 select md5(uuid()…

SCT52240双路 4A/4A 高速MOSFET/IGBT栅极驱动器, 可并联输出

SCT52240是是一款宽供电电压、双通道、高速、低测栅极驱动器&#xff0c;包括功率MOSFET&#xff0c;IGBT。单个通道能够提供高达4A拉电流和4A灌电流的轨到轨驱动能力&#xff0c;并实现轨到轨输出。高达24V宽电压范围提高功率器件开关瞬间栅极驱动的振铃幅值裕度。13ns输入输出…

Spring源码学习-核心注解,架构以及整体流程

目录 核心注解核心组件接口分析基础接口ResourceResourceLoaderResourceResourceLoader BeanFactory结构解析图示核心的子接口 BeanDefinition加载注册流程(xml形式的) BeanDefinitionReaderBeanDefinitionRegistryApplicationContext类结构图示结构解析 Aware接口类图xxAware是…

后端Long类型传到前端精度丢失的问题

问题出现&#xff1a;后端的Java Bean的id属性是用的Long类型对应数据库主键使用bigint类型&#xff0c;当使用JSON方式传递该数据给前端时&#xff0c;前端接收到的数据末尾会变成0。&#xff08;发生的精度丢失问题&#xff09; 问题原因&#xff1a;Java中的long能表示的范围…

域名下配置,dns TXT记录,防止任意邮件伪造

每日鸡汤&#xff1a;每个你想要学习的瞬间都是未来的你向自己求救 最近在做一个网页的项目&#xff0c;这个项目和之前的项目的区别是部署在海外的服务器上&#xff0c;为了方便国外的用户访问&#xff0c;所以在埋点统计这块我们就选择了谷歌统计。国内的项目一般使用百度统计…

管道泄漏监测系统:天然气管道泄漏监测

随着我国城市化进程的快速推进&#xff0c;城市燃气管网也不断扩张&#xff0c;规模日益庞大&#xff0c;地下管线错综复杂&#xff0c;城市燃气管网的建设和运营面临着越来越多的挑战。然而&#xff0c;很多城市在建设过程中过于注重地上设施&#xff0c;对地下管网的科学管控…

ORCA优化器浅析——​MD Accessor的三级缓存

分析​MD Accessor对元数据的缓存能力 set client_min_messageslog; set optimizer to on; set optimizer_print_optimization_stats to on; --执行SQLoptimizer_print_optimization_stats GUC会打印处ORCA优化器优化流程中的各步骤的统计数据。分析打印日志如下&#xff0c;由…

[分布式] Ceph实战应用

目录 一、建 CephFS 文件系统 MDS 接口服务端操作客户端操作 二、创建 Ceph 块存储系统 RBD 接口创建 Ceph 对象存储系统 RGW 接口OSD 故障模拟与恢复 一、建 CephFS 文件系统 MDS 接口 服务端操作 1&#xff09;在管理节点创建 mds 服务 cd /etc/ceph ceph-deploy mds creat…

流程图实现,基于vue2实现的流程图

1.基本思路 flex布局 伪元素实现竖直的连接线组件递归 2.效果图 2.1基础的&#xff08;未截全&#xff0c;大致长这样&#xff09; 2.2带有收缩功能的&#xff0c;可以展开和收缩并显示数量 3.待需要优化的点&#xff0c;根节点居中是基于整个流程图大小的来居中的&#xf…

【Spring Boot】Spring Boot的系统配置 — 实战:实现系统多环境配置

实战&#xff1a;实现系统多环境配置 在实际项目开发的过程中&#xff0c;需要面对不同的运行环境&#xff0c;比如开发环境、测试环境、生产环境等&#xff0c;每个运行环境的数据库、Redis服务器等配置都不相同&#xff0c;每次发布测试、更新生产都需要手动修改相关系统配置…

delete删除的数据如何恢复?delete删除的数据找回

在数字时代&#xff0c;我们经常处理大量的数据&#xff0c;无论是工作、学习还是个人生活。然而&#xff0c;数据的增多也带来了新的挑战&#xff0c;其中最令人头疼的便是数据丢失问题&#xff0c;例如因操作失误而删除了重要的文件或数据。本文将探讨如何恢复delete删除的数…

租赁小程序开发|在线租赁小程序开发|租赁系统源码

近年来&#xff0c;随着共享经济的兴起&#xff0c;租赁服务逐渐成为了人们生活中不可或缺的一部分。为了方便用户租赁物品或者服务&#xff0c;租赁小程序应运而生。租赁小程序开发具有许多功能优势&#xff0c;使其成为租赁行业的重要工具。本文将介绍一些租赁小程序开发的功…

研发效能认证学员作品:如何实现在DevSecOps的测试左移丨IDCF

作者&#xff1a;赵露润 &#xff08;现就职于赛意信息科技有限公司&#xff09; 研发效能&#xff08;DevOps&#xff09;工程师认证学员、PMP 认证、ITIL4 认证 前言 一个自主研发的ITDevOps系统&#xff0c;承载的主要功能有产品信息树管理&#xff0c;敏捷协同管理&…