canvas画不规则分享海报图

166 阅读1分钟

记录手撸canvas代码,本人菜鸟,勿喷!勿喷!勿喷!

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<meta
			name="viewport"
			content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
		/>
		<title>面对面邀请</title>
	</head>
	<body>
		<canvas id="imgCanvas"></canvas>
	</body>
</html>
<script>
	window.onload = function () {
		var imgHead = 'https://oss.mdweilai.cn/images/7293/headurl.jpeg?v=1644378033?v2';
		var shareTitleImg = 'https://oss.mdweilai.com/invite/face_invitation.png?v2';
		var imgCanvas = document.getElementById('imgCanvas');
		var cvs = imgCanvas;
		var c_width = 343;
		var c_height = 554;
		cvs.width = c_width;
		cvs.height = c_height;
		let nickName = '这里是昵称';
		let userId = '244789866';
		var ctx = cvs.getContext('2d');
		//创建image对象
		var imgObj = new Image();
		imgObj.src = imgHead + '?v=' + Math.random();

		//待图片加载完后,将其显示在canvas上
		imgObj.crossOrigin = 'anonymous';
		imgObj.onload = function () {
			var img_w = this.width;
			var img_h = this.height;
			console.log(img_w);
			console.log(img_h);
			var r_big = 44;
			var r_small = 28;
			if (img_w > img_h) {
				var d_h = r_small * 2;
				var d_w = Math.floor((d_h * img_w) / (img_h * 1));
			} else {
				var d_w = r_small * 2;
				var d_h = Math.floor((d_w * img_h) / (img_w * 1));
			}
			var width = d_w; // 640
			var height = d_h; // 640
			var movex = Math.floor(c_width / 2);
			// if (img_w > img_h) {
			// 	// movex=movex-((d_w-c_width)/2);
			// }

			var circle = {
				x: c_width / 2,
				y: r_big,
				r: r_big,
			};

			// 矩形背景色开始
			ctx.beginPath();
			ctx.fillStyle = 'white';
			drawRoundRect(ctx, 0, 40, 343, 514, 10);
			ctx.fill();
			//
			ctx.beginPath();
			ctx.fillStyle = '#FFF5F2';
			drawRoundRect(ctx, 0, 40, 343, 90, 10);
			ctx.fill();

			ctx.beginPath();
			ctx.fillStyle = '#ffffff';
			ctx.rect(0, 120, 343, 10);
			ctx.closePath();
			ctx.fill();

			// 头像外围圆
			ctx.beginPath();
			ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2, false);
			// ctx.clip(); //剪切路径
			ctx.closePath();
			ctx.fillStyle = '#FFF5F2';
			ctx.fill();

			// 头像 开始路径画圆,剪切处理
			ctx.beginPath();
			ctx.arc(circle.x, circle.y, r_small, 0, Math.PI * 2, false);
			ctx.save();
			ctx.clip(); //剪切路径
			ctx.closePath();
			ctx.drawImage(this, Math.floor(c_width / 2 - r_small), r_big - r_small, d_w, d_h);
			ctx.restore();

			// 昵称
			ctx.beginPath();
			ctx.font = '600 ' + 15 + 'px PingFangSC-Medium, PingFang SC';
			ctx.textAlign = 'center';
			ctx.fillStyle = '#000000DE';
			ctx.fillText(nickName, c_width / 2, 95);
			// ID
			ctx.font = '400 ' + 11 + 'px PingFangSC-Medium, PingFang SC';
			ctx.textAlign = 'center';
			ctx.fillStyle = 'rgba(0,0,0,0.54)';
			ctx.fillText(`ID:${userId}`, c_width / 2, 110);
			// 分享title
			shareFun(shareTitleImg)
				.then(res => {
					if (res == 'ok') {
						console.log('title ok');
						// 二维码边线
						ctx.beginPath();
						ctx.strokeStyle = 'rgba(65, 15, 0, 0.14)';
						drawRoundRect(ctx, (c_width - 230) / 2, 230, 230, 230, 10);
						ctx.stroke();
					}
				})
				.then(() => {
					// 二维码
					qrCodeFun().then(res => {
						if (res == 'ok') {
							ctx.save();
							ctx.font = '400 ' + 15 + 'px PingFangSC-Medium, PingFang SC';
							ctx.textAlign = 'center';
							ctx.fillStyle = '#410F00de';
							ctx.fillText('用要的识别二维码,即可成为密探', c_width / 2, 488);
							// 底部红色小标
							ctx.beginPath();
							ctx.fillStyle = '#FF736A38';
							drawRoundRect(ctx, c_width / 2 - 20, 518, 40, 4, 2);
							ctx.fill();
							ctx.save();
							//恢复状态
							ctx.restore();
							//导出
							var base64Img = imgCanvas.toDataURL('image/png');
							console.log(base64Img);
						}
					});
				});
		};

		// 分享title
		function shareFun(params) {
			return new Promise((resolve, reject) => {
				let titleImg = new Image();
				titleImg.src = params + '?v=' + Math.random();
				titleImg.crossOrigin = 'anonymous';
				titleImg.width = 246;
				titleImg.onload = function () {
					titleImg_w = this.width;
					ctx.drawImage(this, Math.floor(c_width / 2 - titleImg_w / 2), 180, 246, 30);
					resolve('ok');
				};
			});
		}
		function qrCodeFun(params) {
			return new Promise((resolve, reject) => {
				let qrCode = new Image();
				let qrCodeImg =
					'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANwAAADcCAAAAAA+MZBdAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAFxEAABcRAcom8z8AAAK8SURBVHja7Z1bchshEAB3U7plfL1cJdeSf+xSCi2a4WEnPen+sgSL6RpXYRYGzvtRlx9/uwPKKadcHZSjohyV2+PHc7KJe/N8+z9P9P2RLB/tT/HIKUdFOSrKUbmQu+f42Xvu/KAtb7//rB91cbY//1/k6qAcFeWolJa79Yt686nVd9Tt/C7b3nh/SkdOOSrKUVGOym29iU9Wx8VzsH5M6cgpR0U5KspR2TjOtet0Z1AereutUzpyylFRjopyVF6Mc7PjTjt+Hc3nXnm23TylI6ccFeWolJa7GAreck/+/q4uzvfnfIweu/db7vo825/if5bKUVGOinJUzv1vC2ffQ7o+p5xydJSjUlruxTiXnV9l51+93zS6fyWfp1c6cspRUY6KclQS63PZcWj0feNovfE88tKRU46KclSUo5LYb5ndVxIR7b8cfT6mdOSUo6IcFeWoXIxz0Xlco+d39eodnefavIT5/IPSkVOOinJUlKNysd8ye17lMVgejVPZ8fIInnd9jo9yVJSjUlruj/nc6viTfS85my/Qo99e6cgpR0U5KspRubivIJpH9cazaP/j6v5N96EoVwLlqChH5SKvYPR+nbb8aOqNrsvN5hMcT+WlI6ccFeWoKEflxfrcU9Vkk6PnWK6fe9Jrv3TklKOiHBXlqGw8D2X03K7Z+aLzOeXQKEdFOSob7xOP8sajvIGW9flf6cgpR0U5KspRucifS87w3n41X8zmu83eWxf3s3TklKOiHBXlqHzDfeLZds6g/vjvLx055agoR0U5Kl9wz2r7OZs3Ppp/EOf1lY6cclSUo6IclY3j3Gi+XLTutr6PpXTklKOiHBXlqGy8T3z1/p5snvkR1HtQOnLKUVGOSmk5wH3i82y8T/yp6U3ttO2ZV6AcGuWoKEflC+4T/3coHTnlqChHRTkqylF5B44y5JiJidlwAAAAAElFTkSuQmCC';
				qrCode.src = qrCodeImg;
				qrCode.crossOrigin = 'anonymous';
				qrCode.onload = function () {
					qrCode_w = this.width;
					var imgDom = document.createElement('img');
					ctx.drawImage(qrCode, Math.floor(c_width / 2 - qrCode_w / 2), 233, 222, 222);
					resolve('ok');
				};
			});
		}

		function drawRoundRect(cxt, x, y, width, height, radius) {
			cxt.beginPath();
			cxt.arc(x + radius, y + radius, radius, Math.PI, (Math.PI * 3) / 2);
			cxt.lineTo(width - radius + x, y);
			cxt.arc(width - radius + x, radius + y, radius, (Math.PI * 3) / 2, Math.PI * 2);
			cxt.lineTo(width + x, height + y - radius);
			cxt.arc(width - radius + x, height - radius + y, radius, 0, (Math.PI * 1) / 2);
			cxt.lineTo(radius + x, height + y);
			cxt.arc(radius + x, height - radius + y, radius, (Math.PI * 1) / 2, Math.PI);
			cxt.closePath();
		}
	};
</script>