uniapp绘制分享海报

uniApp 分享海报

uniapp生成海报,带适配,文字多出省略号,圆角矩形

<template>
	<view>
		<view class="invite_img" @click="showposter">生成海报</view>
		<canvas canvas-id="poster" id="poster" class="poster-box"></canvas>
		<u-popup v-model="show" mode="center">
			<image :src="posterImg" class="posterImg" mode=""></image>
			<image src="../../static/images/poster_close.png" mode="" class="close" @click="close"></image>
			<view class="button" @click="saveposter">保存到相册</view>
		</u-popup>
	</view>
</template>

<script>


export default {
	data() {
		return {
			_w:0,
			userInfo: {
				//海报所需数据
				avatar_url: 'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',
				qRCodeImgUrl: 'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF',

				nickname: '笑一个吧123123哈哈哈哈哈哈哈哈哈',
				mobile: '182****1022',
				code: '123456'
			},
			bgImgUrl: 'https://img2.baidu.com/it/u=2556294903,542088888&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281', //海报背景
			finger: 'https://img1.baidu.com/it/u=3298452815,4076337725&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501', //海报手指图片
			show: false,
			posterImg: '',
			loading: false
		};
	},
	async onReady() {
		this.getSystemInfo(); //获取屏幕宽度适配比例
	},
	async onLoad() {
		this.showposter();
	},
	onShow() {
	
	},
	mounted() {
		
	},
	methods: {
		//将canvas转图片
		async showposter() {
			// if (this.detail.is_vip != 1) {
			// 	uni.showModal({
			// 		title: '您还不是会员',
			// 		content: '需要购买会员勋章后邀请,用户才能获得分销金',
			// 		cancelText: '前往购买',
			// 		confirmText: '知道了',
			// 		cancelColor: '#8392A6',
			// 		success: (res) => {
			// 		        if (res.confirm) {
			// 		            console.log('用户点击确定');
			// 		        } else if (res.cancel) {
			// 		           uni.navigateTo({
			// 		           	url: "/pages/vipDetail/vipDetail?id=" + this.detail.member_deal_list[0].id
			// 		           })
			// 		        }
			// 		    }

			// 	})
			// 	return
			// }

			uni.showLoading({
				title: '海报生成中...'
			});

			//  绘制海报所需数据    如果是本地图片使用this.getImageInfoUrl
			let bgImgUrl = await this.createImgUrl(this.bgImgUrl);
			let fingerUrl = await this.createImgUrl(this.finger);
			let avatar_url = await this.createImgUrl(this.userInfo.avatar);
			let qRCodeImgUrl = await this.createImgUrl(this.userInfo.qr_code);
			console.log('posterMsg', this.userInfo.avatar, this.userInfo.qr_code);
			this.posterCanvas({
				bgImgUrl,
				fingerUrl,
				headImgUrl: avatar_url,
				CodeImgUrl: qRCodeImgUrl,
				nickName: this.userInfo.nickname,
				phone: this.userInfo.mobile,
				code: this.userInfo.code
			});
		},
		//保存图片
		saveposter() {
			const that = this;
			uni.getImageInfo({
				src: this.posterImg,
				success: res => {
					console.log('res', res.path);
					uni.saveImageToPhotosAlbum({
						filePath: res.path,
						success: function() {
							uni.showToast({
								title: '保存成功'
							});
						},
						fail: function(err) {
							console.log('err1', err);
						}
					});
				},
				fail: err => {
					console.log('errr', err);
				}
			});
		},
		close() {
			this.show = false;
		},
		// 绘制海报
		posterCanvas({ bgImgUrl = '', headImgUrl = '', nickName = '', phone = '', CodeImgUrl = '', code = '', fingerUrl = '' }) {
			let that = this;
			let ctx = uni.createCanvasContext('poster', this);
			//填充白色背景
			ctx.fillStyle = '#FFFFFF';
			ctx.fillRect(0, 0, this.calculate(310), this.calculate(494.5));
			//头部背景图
			ctx.drawImage(bgImgUrl, 0, 0, this.calculate(310), this.calculate(200));
			ctx.restore();
			//头像
			console.log('头像');
			ctx.save()
			//ctx.drawImage(headImgUrl, this.calculate(16), this.calculate(182), this.calculate(68), this.calculate(68));
			this.circleImgTwo(ctx, headImgUrl, this.calculate(16), this.calculate(182), this.calculate(68), this.calculate(68), 10);
			ctx.restore();
			// 名字
			console.log('名字');
			this.dealWords({
				ctx,
				fontSize: 18,
				color: '#292F3E',
				word: nickName,
				maxWidth: this.calculate(210),
				x: this.calculate(93),
				y: this.calculate(210),
				maxLine: 1
			});
			ctx.restore();
			// 电话号码
			console.log('电话');
			ctx.setFillStyle('#6E717A');
			ctx.setFontSize(12);
			ctx.fillText(phone, this.calculate(93), this.calculate(246));
			ctx.restore();
			//绘制二维码
			console.log('二维码');
			ctx.drawImage(CodeImgUrl, this.calculate(75), this.calculate(265), this.calculate(160), this.calculate(160));
			ctx.restore();
			//绘制邀请码
			ctx.setFillStyle('#292F3E');
			ctx.setFontSize(12);
			ctx.fillText('专属邀请码:', this.calculate(88), this.calculate(445));
			ctx.restore();
			//邀请码
			ctx.setFillStyle('#FF0677');
			ctx.setFontSize(17);
			ctx.fillText(code, this.calculate(162), this.calculate(445));
			ctx.restore();
			// 提示语
			ctx.drawImage(fingerUrl, this.calculate(39), this.calculate(465), this.calculate(20), this.calculate(14));
			ctx.restore();
			ctx.setFillStyle('#5C6476');
			ctx.setFontSize(12);
			ctx.fillText('分享给你的好友,让TA跟你一起做任务', this.calculate(65), this.calculate(476));

			ctx.restore();
			ctx.draw();
			// 海报绘制完成
			// 转换成图片
			setTimeout(() => {
				uni.canvasToTempFilePath({
					x: 0,
					y: 0,
					width: that.calculate(310),
					height: that.calculate(494.5),
					// destWidth: this.calculate(930),
					// destHeight: this.calculate(1483.5),
					quality: 1,
					canvasId: 'poster',
					success: res => {
						console.log(res.tempFilePath, '生成图片');
						that.posterImg = res.tempFilePath;

						uni.hideLoading();

						that.show = true;
					},
					fail: err => {
						console.log('err', err);
						uni.showToast({
							title: '生成失败',
							icon: 'none'
						});
						uni.hideLoading();
					}
				});
			}, 1000);
		},

		// 获取系统适配
		getSystemInfo() {
			let _this = this;
			uni.getSystemInfo({
				success(res) {
					_this._w = res.windowWidth;
				}
			});
		},
		// 画布计算比例
		calculate(num) {
			let w = this._w;
			let n = parseInt((w * num) / 375);
			return n;
		},
		// 创建本地地址
		createImgUrl: url =>
			new Promise((resolve, reject) => {
				uni.downloadFile({
					url,
					success: val => resolve(val.tempFilePath),
					fail: err => {
						console.log('e', err);
						uni.showToast({
							title: '图片出现错误',
							icon: 'none'
						});
						reject(err);
					}
				});
			}),
		// 本地资源路径
		getImageInfoUrl: url =>
			new Promise((resolve, reject) => {
				uni.getImageInfo({
					src: url,
					success: val => resolve(val.path),
					fail: err => {
						console.log('e', err);
						reject(err);
					}
				});
			}),
			/*  绘制圆角矩形   需要在前面save一下   再用restore恢复
		 *  参数说明
		 *  ctx Canvas实例
		 *  img 图片地址
		 *   x  x轴坐标
		 *   y  y轴坐标
		 *   w  宽度
		 *   h  高度
		 *   r  弧度大小
		 */
		circleImgTwo(ctx, img, x, y, w, h, r) {
			// 画一个图形
			if (w < 2 * r) r = w / 2;
			if (h < 2 * r) r = h / 2;
			ctx.beginPath();
			ctx.moveTo(x + r, y);
			ctx.arcTo(x + w, y, x + w, y + h, r);
			ctx.arcTo(x + w, y + h, x, y + h, r);
			ctx.arcTo(x, y + h, x, y, r);
			ctx.arcTo(x, y, x + w, y, r);
			ctx.closePath();
			ctx.strokeStyle = '#FFFFFF'; // 设置绘制圆形边框的颜色
			ctx.stroke();
			ctx.clip();  //从原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)      需要在前面save一下
			ctx.drawImage(img, x, y, w, h);
		},
		//处理文字多出省略号显示
		dealWords(options) {
			options.ctx.setFontSize(options.fontSize); //设置字体大小
			options.ctx.setFillStyle(options.color); //设置字体颜色
			var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth); //实际总共能分多少行
			var count = allRow >= options.maxLine ? options.maxLine : allRow; //实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数

			var endPos = 0; //当前字符串的截断点
			for (var j = 0; j < count; j++) {
				var nowStr = options.word.slice(endPos); //当前剩余的字符串
				var rowWid = 0; //每一行当前宽度
				if (options.ctx.measureText(nowStr).width > options.maxWidth) {
					//如果当前的字符串宽度大于最大宽度,然后开始截取
					for (var m = 0; m < nowStr.length; m++) {
						rowWid += options.ctx.measureText(nowStr[m]).width; //当前字符串总宽度
						if (rowWid > options.maxWidth) {
							if (j === options.maxLine - 1) {
								//如果是最后一行
								options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 18); //(j+1)*18这是每一行的高度
							} else {
								options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 18);
							}
							endPos += m; //下次截断点
							break;
						}
					}
				} else {
					//如果当前的字符串宽度小于最大宽度就直接输出
					options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
				}
			}
		}
	}
};
</script>

<style lang="scss" scoped>
.header {
	background: url(../../static/images/memberCenter_bg.png) no-repeat;
	height: 520rpx;
	background-size: cover;
	background-position: center;
	padding-bottom: 30rpx;
	position: relative;
	::v-deep .u-navbar {
		background: rgba(0, 0, 0, 0) !important;
	}
}

.on ::v-deep .u-navbar {
	background: RGBA(196, 213, 255, 1) !important;
}

::v-deep .u-mode-center-box {
	background: none;
}

.userInfo {
	display: flex;
	align-items: center;
	padding-left: 40rpx;
	margin-top: 15rpx;

	.headerImg {
		height: 120rpx;
		width: 120rpx;
		border-radius: 50%;
		margin-right: 26rpx;
	}

	.username {
		font-size: 40rpx;
		font-family: PingFang SC;
		font-weight: bold;
		color: #292f3e;

		.vip {
			height: 36rpx;
			width: 36rpx;
			margin-left: 16rpx;
		}
	}

	.inviteed {
		margin-top: 10rpx;
		font-size: 24rpx;
		font-family: PingFang SC;
		font-weight: 500;
		color: rgba(92, 100, 118, 0.6);

		.inviteed_num {
			font-size: 32rpx;
			font-family: PingFang SC;
			font-weight: bold;
			color: rgba(92, 100, 118, 0.8);
		}
	}
}

.explain {
	// position: absolute;
	box-sizing: border-box;

	margin: 0 24rpx;
	margin-top: 48rpx;
	// top: 310rpx;
	// left: 24rpx;
	// right: 24rpx;
	// width: 702rpx;
	// height: 403rpx;
	background: #ffffff;
	padding: 29rpx 33rpx 33rpx 33rpx;
	box-shadow: 0px 0px 25rpx 0px rgba(83, 105, 161, 0.1);
	border-radius: 16rpx;

	.explain_title {
		font-size: 30rpx;
		font-family: PingFang SC;
		font-weight: bold;
		color: #292f3e;
		margin-bottom: 10rpx;
		// margin-top: 29rpx;
	}
}

.invite_img {
	height: 175rpx;
	margin: 0 24rpx;
	margin-top: 15rpx;
	.invite_img_cover {
		height: 175rpx;
		width: 100%;
	}
}

.buy_vip_title {
	font-size: 32rpx;
	font-family: PingFang SC;
	font-weight: bold;
	color: #292f3e;
	margin: 51rpx 0 0rpx 32rpx;
}

.buy_vip_item {
	// width: 686rpx;
	height: 196rpx;
	background: #fcfbf7;
	border: 2rpx solid #eaac3c;
	border-radius: 16rpx;
	margin: 0 32rpx;
	margin-top: 30rpx;
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 0 42rpx;
}

.vip_name {
	font-size: 36rpx;
	font-family: PingFang SC;
	font-weight: bold;
	color: #cc9512;
}

.vip_time {
	font-size: 26rpx;
	font-family: PingFang SC;
	font-weight: 500;
	color: #cc9512;
	margin-top: 20rpx;
}

.vip_money_num {
	font-size: 32rpx;
	font-family: PingFang SC;
	font-weight: bold;
	color: #292f3e;
}

.buy_button {
	margin-top: 24rpx;
	width: 160rpx;
	height: 56rpx;
	background: linear-gradient(90deg, #f2e098 0%, #f1c370 100%);
	border-radius: 28rpx;
	font-size: 24rpx;
	text-align: center;
	line-height: 56rpx;
	font-family: PingFang SC;
	font-weight: bold;
	color: #934b0c;
}

.buy_vip_name {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	align-items: center;
}

.buy_vip_money {
	display: flex;
	justify-content: space-between;
	flex-direction: column;
	align-items: center;
}

.poster-box {
	width: 620rpx;
	height: 989rpx;
	position: fixed;
	// left: 10rpx;
	left: 110vw;
	top: 0rpx;
	z-index: -1;
	// background-color: #fff;
	// border: 1px solid red;
	// z-index: -1;
}

.posterImg {
	width: 620rpx;
	height: 989rpx;
	border-radius: 20rpx;
}

.button {
	width: 400rpx;
	height: 88rpx;
	line-height: 88rpx;
	margin: 0 auto;
	text-align: center;
	font-size: 30rpx;
	font-family: PingFang SC;
	font-weight: 500;
	color: #262a32;
	background: #ffffff;
	border-radius: 16rpx;
	margin-top: 48rpx;
}
.close {
	height: 32rpx;
	width: 32rpx;
	position: absolute;
	top: 20rpx;
	right: 20rpx;
}
</style>

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你好!关于在UniApp分享海报的问题,你可以按照以下步骤进行操作: 1. 首先,你需要生成海报图像。你可以使用第三方库或工具来生成海报,例如使用Canvas API绘制图片和文字。UniApp中可以使用uni-app-canvas插件来实现这一功能。 2. 生成海报后,你需要将其保存为图片文件。可以使用uni-app的api之一uni.saveImageToPhotosAlbum()将海报保存到相册中。 3. 在分享按钮的点击事件中,你可以使用uni.share()方法来触发分享操作。在参数中,你可以指定分享的标题、内容以及海报图片的路径。 示例代码如下: ```javascript // 生成海报并保存 // 这里是使用 uni-app-canvas 插件生成海报的示例 import Canvas from 'uni-app-canvas' Canvas.createCanvas('canvas', this.$refs.canvas) const ctx = uni.createCanvasContext('canvas') // 在画布上绘制图片和文字等元素 ctx.draw(false, () => { uni.canvasToTempFilePath({ canvasId: 'canvas', success: (res) => { uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: () => { // 成功保存到相册后进行分享 uni.share({ title: '分享标题', content: '分享内容', imageUrl: res.tempFilePath, success: () => { console.log('分享成功') }, fail: (err) => { console.log('分享失败', err) } }) }, fail: (err) => { console.log('保存到相册失败', err) } }) }, fail: (err) => { console.log('生成海报失败', err) } }) }) ``` 这样,当用户点击分享按钮时,就会生成海报并保存到相册,然后触发分享操作。 希望能帮到你!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑一个吧*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值