uni-app项目中画布实现海报


前言

关于uni-app中使用画布的文档很少,也不是很详细,正好在最近的项目中用到了画布,不过比较简单的。此文由此而来


一、canvas的概述?

Canvas通过Javascript在网页上来绘制2D图形。Canvas是逐像素进行渲染的。开发者可以通过javascript脚本实现任意绘图。可以通过多种方法使用canvas元素绘制路径、矩形、圆形、字符以及添加图像。
在项目中,你可能会遇到一些常用的功能。比如分享图片、海报等等。

二、drawImage 相关参数介绍

1.描述

drawImage 方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。drawImage函数有三种函数原型:

drawImage(image, dx, dy) 
drawImage(image, dx, dy, dw, dh) 
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

第一个参数image可以用HTMLImageElement,HTMLCanvasElement或者HTMLVideoElement作为参数。
dx和dy是image在canvas中定位的坐标值
dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值
sx和sy是image所要绘制的起始位置
sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值

2.图解

在这里插入图片描述

3.项目的实际使用

在这里插入图片描述

// 1.创建元素
<view class="">
	<u-button type="primary" text="生成海报" @click="btn"></u-button>
	<canvas class="canvas" :style="{width: canvasW + 'px', height: canvasH + 'px'}" canvas-id="myCanvas"></canvas>
</view>
// 2.相关代码
<script>
	export default {
		data() {
			return {
				canvasW: 300,
				canvasH: 270,
				objInfo: {
					userImg: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.63fl.com%2Fwp-content%2Fuploads%2F2021%2F12%2F2021121605474891.jpg&refer=http%3A%2F%2Fwww.63fl.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1662689694&t=d7a22a71afa6d8d3988f81b25158aa1c',
					name: '诗仙-李白',
					des: '国耻未雪,何由成名?'
				}
			}
		},

		methods: {
			// 获取图片信息
			getImageInfo(image) {
				return new Promise((req, rej) => {
					uni.getImageInfo({
						src: image,
						success: function(res) {
							req(res)
						},
					});
				})
			},
			btn() {
				this.poster();
			},
			async poster() {
				var _this = this;
				var info = await _this.getImageInfo(_this.objInfo.userImg)
				if (info.errMsg == 'getImageInfo:ok') {
					uni.showToast({
						icon: 'loading',
						mask: true,
						duration: 3000,
						title: '海报绘制中',
					});
					var name = _this.objInfo.name;
					var qrcode = info.path;
					var des = _this.objInfo.des
					setTimeout(() => {
						// 创建画布对象
						const ctx = uni.createCanvasContext('myCanvas', this)
						// 清除背景
						ctx.clearRect(0, 0, _this.canvasW, _this.canvasW)
						// 绘制背景
						ctx.fillStyle = "#fff";
						ctx.fillRect(0, 0, _this.canvasW, _this.canvasW);
						// 绘制文本
						ctx.font = "17px Medium"; // 字体大小
						ctx.fillStyle = '#111'; //字体填充颜色
						var widthText1 = ctx.measureText(des).width;
						var start1 = (_this.canvasW - widthText1) / 2;
						ctx.fillText(des, start1, 30);

						ctx.font = '14px Regular'; // 字体大小
						ctx.fillStyle = '#666'; // 字体填充颜色
						var widthText2 = ctx.measureText(name).width;
						var start2 = (_this.canvasW - widthText2) / 2;
						ctx.fillText(name, start2, 60)
						var widthImg1 = (_this.canvasW - 162) / 2;
						// 图片
						// drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
						// dx和dy是image在canvas中定位的坐标值
						// dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值
						// sx和sy是image所要绘制的起始位置
						// sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值
						ctx.drawImage(qrcode, 0, 0, info.width, info.height, widthImg1, 80, 162,
							162 * info.height / info.width)
						ctx.stroke();
						// 绘制裁剪头像为圆形
						let radius, diameter
						let width = 162; // 头像宽度
						let height = 162; // 头像高度
						let x = widthImg1; // 头像显示位置
						let y = 80; // 头像显示位置
						if (width > height) {
							radius = height / 2;
						} else {
							radius = width / 2;
						}
						diameter = radius * 2;
						ctx.beginPath();
						ctx.arc(x + radius, y + radius, radius, 0, Math.PI * 2, false);
						ctx.clip();
						ctx.strokeStyle = "#ff6352"; // 改变边框颜色
						ctx.stroke();
						ctx.draw(true, (ret) => {
							uni.showToast({
								icon: 'success',
								mask: true,
								title: '绘制完成',
							});
							uni.canvasToTempFilePath({ // 保存canvas为图片
								width: _this.canvasW,
								height: _this.canvasH,
								destWidth: _this.canvasW * 2, //此处需放大2倍,不然保存的图失真
								destHeight: _this.canvasH * 2,
								canvasId: 'myCanvas',
								quality: 1,
								complete: function(res) {
									// 在H5平台下,tempFilePath 为 base64, // 图片提示跨域 H5保存base64失败,APP端正常输出临时路径
									_this.canvasImg = res.tempFilePath
								},
							})
						})
					}, 1000)
				}
			}
		}
	}
</script>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值