uniapp canvas生成海报

效果

在这里插入图片描述

封装组件,父组件 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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GPT3.5的PPO目标函数怎么来的:From PPO to PPO-ptx

给定当前优化的大模型 π \pi π&#xff0c;以及SFT模型 π S F T \pi_{SFT} πSFT​ 原始优化目标为: max ⁡ E ( s , a ) ∼ R L [ π ( s , a ) π S F T ( s , a ) A π S F T ( s , a ) ] \max E_{(s,a)\sim RL}[\frac{\pi(s,a)}{\pi_{SFT}(s,a)}A^{\pi_{SFT}}(s,a)] m…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 03:强化你的子系统

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

windows无法完成格式化

方法. 使用CMD格式化 请将U盘连接到电脑&#xff0c;并确保电脑能够正常识别。 1. 在搜索框中输入“命令提示符”。在左侧结果中的“命令提示符”上点击右键&#xff0c;选择“以管理员身份运行”。 2. 在新窗口中&#xff0c;键入“diskpart”并按“回车”&#xff0c;然后…

如何通过小猪APP分发轻松实现Web封装APP

你有没有想过将你的网站或者Web应用变成一个真正的APP&#xff1f;这听起来可能有点复杂&#xff0c;但其实在今天的技术环境下&#xff0c;这已经变得非常简单了。特别是有了像小猪APP分发这样的工具&#xff0c;你可以轻松地将你的Web应用封装成一个APP。 为什么要将Web应用封…

Golang | Leetcode Golang题解之第164题最大间距

题目&#xff1a; 题解&#xff1a; type pair struct{ min, max int }func maximumGap(nums []int) (ans int) {n : len(nums)if n < 2 {return}minVal : min(nums...)maxVal : max(nums...)d : max(1, (maxVal-minVal)/(n-1))bucketSize : (maxVal-minVal)/d 1// 存储 (…

如何在不丢失数据的情况下解锁安卓手机密码

手机是我们生活中必不可少的工具&#xff0c;可以帮助我们与朋友和家人保持联系&#xff0c;了解最新消息&#xff0c;甚至经营我们的业务。然而&#xff0c;当我们在 Android 手机或 iPhone 上设置密码时&#xff0c;我们经常会忘记密码&#xff0c;或者根本没有设置密码。当这…

安卓多媒体(音频录播、传统摄制、增强摄制)

本章介绍App开发常用的一些多媒体处理技术&#xff0c;主要包括&#xff1a;如何录制和播放音频&#xff0c;如何使用传统相机拍照和录像&#xff0c;如何截取视频画面&#xff0c;如何使用增强相机拍照和录像。 音频录播 本节介绍Android对音频的录播操作&#xff0c;内容包…

SpringBoot3整合SpringDoc实现在线接口文档

写在前面 在现目前项目开发中&#xff0c;一般都是前后端分离项目。前端小姐姐负责开发前端&#xff0c;苦逼的我们负责后端开发 事实是一个人全干&#xff0c;在这过程中编写接口文档就显得尤为重要了。然而作为一个程序员&#xff0c;最怕的莫过于自己写文档和别人不写文档…

c函数/2024/6/17

1.递归计算0--n的和 #include <stdio.h> int sum(int n);//递归求和函数 int main(int argc, const char *argv[]) {//(2)递归计算0--n的和int n0;printf("请输入n的值为:");scanf("%d",&n);printf("0--n的和为:%d",sum(n));return 0…

AI早班车

全球AI新闻速递 1.国内团队制作AI短片《凤鸣山海》亮相北京电影节 国内团队制作AI短片《凤鸣山海》亮相北京电影节“光影未来”电影科技单元。独特的中国玄幻题材&#xff0c;朱雀、玄武、白虎、青龙&#xff0c;四大神兽栩栩如生 2.字节跳动拒绝出售TikTok&#xff0c;如果败…

【数据结构初阶】--- 堆的应用:topk

堆的功能&#xff1a;topk 为什么使用topk 先举个例子&#xff0c;假如说全国有十万家奶茶店&#xff0c;我现在想找到评分前十的店铺&#xff0c;现在应该怎么实现&#xff1f; 第一想法当然是排序&#xff0c;由大到小排序好&#xff0c;前十就能拿到了。这是一种方法&…

三星(中国)投资公司线上入职测评笔试邀请数字推理语言逻辑真题题库

三星&#xff08;中国&#xff09;有限公司北京分公司 邀请您参加 SHL线上笔试 具体安排如下&#xff1a; 笔试时间&#xff1a;周三 9:00 笔试时长&#xff1a;1.5h ~ 2h 笔试内容及要求&#xff1a;数字推理限时30min&#xff1b;语言逻辑限时30min&#xff1b;性格测试不…

【机器学习】第5章 朴素贝叶斯分类器

一、概念 1.贝叶斯定理&#xff1a; &#xff08;1&#xff09;就是“某个特征”属于“某种东西”的概率&#xff0c;公式就是最下面那个公式。 2.朴素贝叶斯算法概述 &#xff08;1&#xff09;是为数不多的基于概率论的分类算法&#xff0c;即通过考虑特征概率来预测分类。 …

你对SSH协议了解吗

SSH&#xff08;Secure Shell&#xff09;协议&#xff0c;作为网络通信领域的一项核心技术&#xff0c;以其卓越的安全性能和广泛的应用范围&#xff0c;成为保障网络通信安全的重要工具。本文将深入剖析SSH协议的工作原理、核心特性以及在现代网络通信中的关键作用&#xff0…

HTML静态网页成品作业(HTML+CSS)——新媒体专业介绍介绍网页(1个页面)

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

经历的分享

我是三本计算机科学技术跨考上岸的学生&#xff0c;本科阶段技术能力并没有掌握多少&#xff0c;在选择导师时屡屡碰壁&#xff0c;我当时向许多计算机方向的导师&#xff0c;比如大数据方向,计算机视觉 迁移学习和图像处理方向的导师全都拒绝了我&#xff0c;最终学校给我分配…

SpringCloudStream原理和深入使用

简单概述 Spring Cloud Stream是一个用于构建与共享消息传递系统连接的高度可扩展的事件驱动型微服务的框架。 应用程序通过inputs或outputs来与Spring Cloud Stream中binder对象交互&#xff0c;binder对象负责与消息中间件交互。也就是说&#xff1a;Spring Cloud Stream能…

Sunny v1.3.0 官方版 (简洁且漂亮截图应用)

前言 Sunny是一款漂亮又实用的“截图&钉图”的软件&#xff0c;亦支持“屏幕识图”和“OCR”的软件。 一、下载地址 下载链接&#xff1a;http://dygod/source 点击搜索&#xff1a;Sunny 二、安装步骤 1、解压后将Sunny.exe发送到桌面快捷方式 2、启动桌面图标 3、正…

下载lombok.jar包,简化类的代码

Download (projectlombok.org) 去这个网站下载lombok.jar包 打开这个包文件的位置,拖到项目lib文件夹: 在这里右键添加为库(Add as library)。 添加这三个注解即可&#xff0c;类里面不需要其他东西了

手写操作系统

对喜欢操作系统的伙伴强推一门课程 从0开始实现了支持文件系统、任务切换和网络协议栈的操作系统。 具体见 &#xff1a;http://www.ziyuanwang.online/977.html