uniapp canvas生成海报

news2024/11/25 22:29:03

效果

在这里插入图片描述

封装组件,父组件 ref 调用 downImgUrl()函数,其他根据自己需求改

<template>
	<view>
		<view class="bgpart">

			<canvas class="canvas-wrap" canvas-id="canvasID" type="2d"></canvas>

			<view class="popPart">
				<view>
					<view class="share-list">
						<view class="share-item flexaround flexalign" @click="shareToFriend(1)">
							<view class="iconImg flexalign flexaround">
								<image src="/static/sharePop/share1.png" mode=""></image>
							</view>
							<text class="font26" style="margin-top: 16rpx;">微信</text>
						</view>
						<view class="share-item flexaround flexalign" @click="shareToFriend(2)">
							<view class="iconImg flexalign flexaround">
								<image src="/static/sharePop/share2.png" mode=""></image>
							</view>
							<text class="font26" style="margin-top: 16rpx;">朋友圈</text>
						</view>
						<view class="share-item flexaround flexalign" @click="downCli">
							<view class="iconImg flexalign flexaround" style="width: 88rpx;height: 88rpx;">
								<u-icon name="download" size="30"></u-icon>
							</view>
							<text class="font26" style="margin-top: 16rpx;">下载</text>
						</view>
					</view>
				</view>
				<view class="share-header flexalign flexaround" style="background: #fff;" @click="$emit('close')">
					取消
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		indexsettingPoster
	} from "@/api/all.js"
	export default {
		name: "sharePoster",
		props: {},
		data() {
			return {
				logo: '/static/logo.png',
				bgimg: '',
				detail: {},
				imgUrl:'',//完成海报图
				qrCode:''
			};
		},
		created() {
			
		},
		methods: {
			// 下载
			downCli() {
				if( this.imgUrl &&  this.imgUrl != ''){{
						uni.saveImageToPhotosAlbum({
							filePath: this.imgUrl,
							success: function () {
								console.log('save success'); 
								uni.showToast({
									icon:"none",
									title:'已下载'
								})
							}
						});
				}
			},
			async downImgUrl(e,url,type) {
				await indexsettingPoster({url:url}).then(res => {
					this.bgimg = res.data.posterThumb 
					this.qrCode = res.data.qrCode
				})
				let canW = 320;
				let canH = 450;
				let ctx = uni.createCanvasContext('canvasID', this);
				// ctx.setFillStyle("transparent"); //设置canvas背景颜色
				// ctx.fillRect(0, 0, 346, 500) //设置canvas画布大小
				ctx.drawImage(this.bgimg, 0, 0, canW, canH) //背景
				ctx.drawImage(this.logo, 18, 20, 36, 36) //logo
				// ctx.drawImage(e.dynamicQRcode, 255, 370, 70, 70) //二维码
				ctx.drawImage(this.qrCode, 230, 370, 70, 70) //二维码
				//绘制圆形头像
				this.drawCircular(ctx, e.headPortrait, 26, 398, 40, 40) 
				// 名字
				ctx.setFontSize(14)
				ctx.setFillStyle("#ffffff")
				ctx.fillText(e.nickName, 74, 424)
				
				// 绘制标题,多余文字自动换行
				ctx.setFontSize(26)
				ctx.setFillStyle("#2C3E68")
				ctx.textAlign = "center"
				let str = type ? e.teamName : e.dynamicTitle
				
				// 字符串总长度
				let _strLength = str.length > 24 ? 24 : str.length
				// 总结截取次数
				let _strNum = Math.ceil(_strLength / 8)
				// 每次开始截取字符串的索引
				let _strHeight = 0
				// 绘制的字体 x,y的初始位置
				let _strX = 345 / 2,
					_strY = 90
				let strIndex = 223
				// 开始截取
				for (let i = 0; i < _strNum; i++) {
					strIndex = _strY + i * 40
					ctx.fillText(str.substr(_strHeight + i * 9, 9), _strX, _strY + i * 34)
				}
				// 绘制内容
				ctx.setFontSize(13)
				ctx.setFillStyle("#4FB0FF")
				let cont = type ? e.teamContent : e.dynamicDescribe
				// 字符串总长度
				let _contLength = cont.length  > 120 ? 120 : cont.length
				// 总结截取次数
				let _contNum = Math.ceil(_contLength / 20)
				// 每次开始截取字符串的索引
				let _contHeight = 0
				// 绘制的字体 x,y的初始位置
				let _contX = 345 / 2,
					_contY = 180
				let contIndex = 223
				// 开始截取
				for (let i = 0; i < _contNum; i++) {
					contIndex = _contY + i * 20
					ctx.fillText(cont.substr(_contHeight + i * 20, 20), _contX, _contY + i * 22)
				}
				//详情图
				let img = type ? e.teamPics : e.dynamicPics //团队,动态
				img.split(',').forEach((el,index)=>{
					if(index == 0){
						ctx.drawImage( el , 50, 290, 70, 70) //二维码
					}else if(index == 1){
						ctx.drawImage( el , 130, 290, 70, 70) //二维码
					}else if(index == 2){
						ctx.drawImage( el , 210, 290, 70, 70) //二维码
					}
				})
				
				ctx.draw(false, () => {
					// 返回canvas图片信息
					uni.canvasToTempFilePath({
						canvasId: 'canvasID',
						success: (res) => {
							this.imgUrl = res.tempFilePath
						},
						fail: function(err) {
							console.log(err)
						}
					})
				})
			},
			// 绘制圆形头像
			drawCircular(ctx, url, x, y, width, height) {
				//画圆形头像
				var avatarurl_width = width;
				var avatarurl_heigth = height;
				var avatarurl_x = x;
				var avatarurl_y = y;
				ctx.save(); //先保存状态,已便于画完园再用
				ctx.beginPath(); //开始绘制
				ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math
					.PI * 2, false);
				ctx.setFillStyle("#FFFFFF")
				ctx.fill() //保证图片无bug填充
				ctx.clip(); //剪切
				ctx.drawImage(url, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); //推进去图片
				ctx.restore();
			},

		}
	}
</script>

<style scoped lang="scss">
.flexaround{
	display: flex;justify-content: space-around;
}
.flexalign{
	display: flex;align-items: center;
}
.font26{
	font-size: 26rpx;
	font-family: PingFang-SC-Medium;
}
	.canvas-wrap {
		margin: 20% 45rpx;
		width: calc(100% - 90rpx);
		height: 940rpx;
		// background-color: #fff;
	}

	.bgpart {
		width: 100vw;
		height: 100vh;
		background-color: rgba(0, 0, 0, 0.5);
		position: fixed;
		left: 0;
		top: 0;
		z-index: 99;

		.popPart {
			width: 100%;
			height: 360rpx;
			background-color: #f5f5f5;
			border-radius: 20rpx 20rpx 0 0;
			position: fixed;
			left: 0;
			bottom: 0;
			z-index: 99;
		}
	}

	.share-header {
		line-height: 80rpx;
	}

	.share-list {
		margin: 20rpx 0 60rpx 0;
		display: flex;
		/* flex-direction: row; */
		flex-wrap: wrap;

		.share-item {
			margin-top: 30rpx;
			min-width: 20%;
			flex-direction: column;

			.iconImg {
				background-color: #fff;
				border-radius: 50%;

				image {
					width: 88rpx;
					height: 88rpx;
				}
			}
		}
	}
</style>

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

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

相关文章

41、基于深度学习的自适应线性预测(matlab)

1、原理及流程 自适应线性预测是一种基于递归最小二乘法&#xff08;Recursive Least Squares, RLS&#xff09;的线性预测方法&#xff0c;用于自适应地估计线性系统的参数。下面是自适应线性预测的原理和流程&#xff1a; 原理&#xff1a; 自适应线性预测的核心思想是通过…

Java | Leetcode Java题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; class Solution {public int findPeakElement(int[] nums) {int n nums.length;int left 0, right n - 1, ans -1;while (left < right) {int mid (left right) / 2;if (compare(nums, mid - 1, mid) < 0 && compare(n…

转型AI产品经理(12):“希克定律”如何应用在Chatbot产品中

信息过载&#xff0c;这个对现代人来说是很常见的问题&#xff0c;信息获取变得越来越便捷的同时&#xff0c;也导致信息过载让我们无法及时做出有效决策&#xff0c;还可能演变成选择困难症。信息过载对用户体验的设计也有着显著的负面影响&#xff0c;如果我们的产品设计让人…

HTML静态网页成品作业(HTML+CSS)——美食火锅介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

笔记 | 软件工程06-2:软件设计-软件体系结构设计

1 软件体系结构的概念 1.1 软件体系结构的设计元素 1.2 不同的抽象层次 1.3 软件体系结构的不同视图 1.3.1 软件体系结构的逻辑视图&#xff1a;包图 1.3.2 软件体系结构的逻辑视图&#xff1a;构件图 1.3.3 软件体系结构的开发视图 1.3.4 软件体系结构的部署视图 1.3.4.1 描述…

UV胶带和UV胶水的应用场景有哪些不同吗?

UV胶带和UV胶水的应用场景有哪些不同吗? UV胶带和UV胶水的应用场景确实存在不同之处&#xff0c;以下是详细的比较和归纳&#xff1a; 一&#xff1a;按使用场景来看&#xff1a; UV胶带的应用场景&#xff1a; 包装行业&#xff1a;UV胶带在包装行业中常用于食品包装、药…

About Apple Pay

本文翻译整理自&#xff1a;About Apple Pay &#xff08;更新时间&#xff1a;2017-03-16&#xff09; https://developer.apple.com/library/archive/ApplePay_Guide/index.html#//apple_ref/doc/uid/TP40014764 文章目录 一、关于 Apple Pay1、使用 Apple Pay2、测试 Apple …

Kaggle比赛:成人人口收入分类

拿到数据首先查看数据信息和描述 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desk…

【机器学习300问】121、RNN是如何生成文本的?

当RNN模型训练好后&#xff0c;如何让他生成一个句子&#xff1f;其实就是一个RNN前向传播的过程。通常遵循以下的步骤。 &#xff08;1&#xff09;初始化 文本生成可以什么都不给&#xff0c;让他生成一首诗。首先&#xff0c;你需要确定采样的起始点。这可以是一个特殊的开…

深度学习:从理论到应用的全面解析

引言 深度学习作为人工智能&#xff08;AI&#xff09;的核心技术之一&#xff0c;在过去的十年中取得了显著的进展&#xff0c;并在许多领域中展示了其强大的应用潜力。本文将从理论基础出发&#xff0c;探讨深度学习的最新进展及其在各领域的应用&#xff0c;旨在为读者提供全…

外网怎么访问内网?

当我们需要在外网环境下访问内网资源时&#xff0c;常常会面临一些困扰。通过使用一些相关的技术与工具&#xff0c;我们可以轻松地实现这一目标。本文将介绍如何通过【天联】组网产品&#xff0c;解决外网访问内网的问题。 【天联】组网是一款由北京金万维科技有限公司自主研…

事务所管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;客户管理&#xff0c;评论管理&#xff0c;基础数据管理&#xff0c;公告信息管理 客户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;律师管理&#xff0…

示例:WPF中绑定枚举到ComboBox想显示成中文或自定义名称如何实现

一、目的&#xff1a;在开发过程中绑定的枚举不想显示成英文字段怎么办&#xff0c;这里通过TypeConverter的方式来实现绑定的枚举从定义的特性中读取 二、实现 首先定义如下枚举 [TypeConverter(typeof(DisplayEnumConverter))]public enum MyEnum{[Display(Name "无&q…

C++ -- 红黑树的基本操作

目录 摘要 基本规则 基本操作 利用Graphviz 库 总结 摘要 红黑树是一种自平衡的二叉搜索树&#xff0c;它在插入和删除节点时&#xff0c;通过颜色和旋转操作保持树的平衡&#xff0c;确保插入、删除和查找的时间复杂度都是 (O(log n))。红黑树的每个节点都有一个颜色属性…

CentOS 7 安装MySQL以及常见问题解决

访问网站&#xff1a;http://repo.mysql.com 找到适配CentOS 7版本的MySQL 的YUM仓库包rpm文件&#xff0c;如下图 下载后&#xff0c;找到安装包的位置 空白处右键&#xff0c;选择在终端打开 查看当前目录下文件 # 安装MySQL 5.7的YUM仓库包rpm -ivh mysql57-community-rele…

学生成绩评分 - Scala

文章目录 一、第1关&#xff1a;对学生成绩进行评分 一、第1关&#xff1a;对学生成绩进行评分 实训目标 掌握 Scala 中运算符嵌套的使用 了解 if-else if-else 语句的使用 实训分析 利用条件运算符的嵌套来完成此题&#xff1a;学习成绩 150 - 90 分的同学成绩评分为&#…

【安防视界新飞跃】液晶拼接屏:安防事业的“超级守护者”!

在守护安全的征途上&#xff0c;每一双“电子眼”都是智慧与科技的结晶。视频监控&#xff0c;这个安防领域的超级英雄&#xff0c;正以它敏锐的洞察力&#xff0c;24小时不间断地守望着我们的世界。而今&#xff0c;随着科技的飞跃&#xff0c;液晶拼接屏如同安防界的“变形金…

windows环境下,怎么查看本机的IP、MAC地址和端口占用情况

1.输入ipconfig,按回车。即查看了IP地址&#xff0c;子码掩码&#xff0c;网关信息。 2.输入ipconfig/all,按回车。即查看了包含IP地址&#xff0c;子码掩码&#xff0c;网关信息以及MAC地址 3.我们有时在启动应用程序的时候提示端口被占用&#xff0c;如何知道谁占有了我们需要…

JAVAFX打包部署真正能用的办法(jdk21,javafx23)IntelliJ IDEA

我之前创建了javafx项目&#xff0c;想打包试试。一试&#xff0c;全是坑&#xff0c;所以记录下来&#xff0c;为有缘人节约时间。直接构建工件是错误的&#xff0c;别尝试了&#xff0c;找不在JDK的。我也花了一天多的时间尝试了网上各种大神的办法&#xff0c;就没找到一个是…