HTML使用canvas绘制海报(网络图片)

生成前:

 

生成后:

 

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">

		<title>媒体参会嘉宾邀请函生成链接</title>
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.10/lib/index.css" />

		<style>
			#app {
				width: 100vw;
				position: relative;
			}

			* {
				margin: 0;
				padding: 0;
			}

			[v-cloak] {
				display: none;
			}

			.bg {
				width: 100vw;
				height: 100vh;
				min-height: 100vh;
				position: relative;
				overflow: hidden;
			}


			#scream {
				width: 100%;
				height: 100%;

			}

			.closeImg {
				width: 34px;
				height: 34px;
			}

			.pop {
				position: absolute;
				top: 0;
				left: 0;
				height: 100%;
				width: 100%;
				background: rgba(0, 0, 0, 0.6);
				z-index: 98;
			}

			.saveImg {
				width: 100%;
				display: block;
			}

			.popImg {
				width: 100%;
				position: absolute;
				top: 0;
				left: 0;
				z-index: 9999;
			}

			.popImgClose {
				width: 100%;
				height: 100px;
				line-height: 100px;
				position: fixed;
				top: 0;
				left: 0;
				z-index: 19999;
				font-size: 36px;
				font-weight: 500;
				color: #fff;
				text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
				letter-spacing: 4px;
				text-align: center;
				background: rgba(0, 0, 0, 0.6);
			}

			.flex-between {
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 0 30px;

			}

			.inputName {
				max-width: 100%;
				border: none;
				background: transparent;
				font-size: 100px;
				font-family: Source Han Sans CN;
				font-weight: bold;
				color: #2274F6;
				position: absolute;
				left: 50%;
				top: 30.9%;
				transform: translate(-50%, -30.9%);
				text-align: center;
				outline: transparent;
				z-index: 1;
			}



			.inputName::-webkit-input-placeholder {
				color: #2274F6;
			}

			.inputName::-moz-placeholder {
				color: #2274F6;
			}

			.inputName::-moz-placeholder {
				color: #2274F6;
			}

			.inputName::-ms-input-placeholder {
				color: #2274F6;
			}


			#myCanvas {
				position: absolute;
				left: -9999px;
				top: -9999px;
			}

			.createImg {
				width: 200px;
				height: 200px;
				line-height: 200px;
				top: 50%;
				right: 10px;
				border-radius: 50%;
				position: fixed;
				font-size: 36px;
				font-family: PingFang SC;
				font-weight: bold;
				    color: #fff;
				    background: rgba(0, 0, 0, 0.5);
				opacity: 1;
				z-index: 9;
				text-align: center;
			}

			.van-notify {
				padding: 30px 20px;
				font-size: 40px;
			}
		</style>
	</head>


	<body>
		<div id="app" v-cloak>
			<img id="scream" :src="imgSrc+'?a='+new Date().getTime()" alt="The Scream" @load="afterLoad">
			<input autofocus="autofocus" type="text" name="input_name" v-model="name" class="inputName" maxlength="8"
				placeholder="点击输入姓名" />
			<div v-on:click='canvas' class="createImg">点击生成</div>
			<canvas id="myCanvas" :width="imgWidth" :height="imgHeight" ref="canvas">
				您的浏览器不支持 HTML5 canvas 标签。</canvas>
			<div class="pop" v-if='showImg' v-on:click="showImg = false">
			</div>
			<div class="popImgClose" v-if='showImg'>
				<div class="flex-between"> <span>长按保存至相册,关闭此行可重新输入姓名生成</span>
					<img :src="closeImg" class="closeImg" v-on:click="showImg = false" alt="">
				</div>

			</div>
			<div class="popImg" v-if='showImg'>
				<img class="saveImg" :src="saveImg" alt="">
			</div>
		</div>
		<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
		<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/vant@2.10/lib/vant.min.js"></script>
		<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js" type="text/javascript"></script>
		<script>
			new Vue({
				el: '#app',
				data: {
					context: {}, //canvas
					imgHeight: '1503', //图片高度
					imgWidth: '750', //图片高度
					name: '',
					saveImg: '', //保存图片
					showImg: false, //显示图片
					closeImg: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADEAAAAxCAMAAABEQrEuAAAAzFBMVEUAAAD///86kuEIAAAARHRSTlMAAQIDBAUGBxcYGhshIiRLTVBUVVdZW2lwcnN0dXeEhYiLjI2VlpeYmZqcnZ6foKGjpKanqKmrrK2ur7CztbbBxMXIzKPOVfAAAAHqSURBVEjHnZZ5W8IwDMZZr6l4X3hfoBPBDSZzoODBvv93soMm6452e9xfaZvf2jTp27Za//g2Orf7TgM/snfT2UyN3Z8kSQK3FhDP0u97S1pnSfr1RQ3Aeyu/K2l2kyaIeFy73Uv7ZG0mgQ0RL8rrVDboUDUG3LykJ/gtSZtuHxDTLNxTHkO1QQKQcTXCXwHAcRHApKwCYBDDWEuBGABSjoUD4OdyxgGJiggfAVBYshirgZDm+qmv+t9KMWIsoR4L8y2bwgCZZQibAFCZKx6p4ZhAtYaq592QKQ4OMc0DkbGAKLgsUoR8AMDMBcdmymnutJypsj+5rahZDAgBYMZrjiYgSwBo3eGki0T/vli9ANC5BixYE21xMmRBmskRgRiWvBmA26pl3z7DVIsjbhAHZrpUliYgLOQjrMkHw8rikMrQXiSTbFsx+5EFwSO6yjSWZWCMhfv5cHGJJoFF1cDiw/NSLX0oZNp5wINcpckoZLlAeWDUZNTWwhFFhSnGgupdUg2UvvyVJDxziKjJfbfiBqoUMtTkoVu4FKu0NS+wnhoXPYN6ZwhcSd5qFuLVARoySJED1RjZHgEuXK/HsnGn0RZEraQr7fPCpWha2Bq5luZOw3eJm27y73Zqti+6R43ePocPl+3/PK7+AKHzueY3wvW7AAAAAElFTkSuQmCC',
					imgSrc: 'https://eventimg.oss-cn-shen.aliyuncs.com/jintuoluo/invitation/invitation_2023.jpg',//海报背景
					toast: null
				},
				created() {
					this.toast = vant.Toast.loading({
						duration: 0, // 持续展示 toast
						forbidClick: true,
						message: '加载中...',
					});

				},

				methods: {
					canvas() {
						if (!this.name) {
							this.$notify({
								background: "#831E21",
								message: '请输入姓名',
							});
							return
						}
						let imgs = new Image();
						  imgs.setAttribute('crossorigin', 'anonymous');//解决网络图片跨域的问题
						imgs.src = this.imgSrc;
						let imgWidth = 0,
							imgHeight = 0,
							that = this;
						//获取图片宽高
						imgs.onload = function() {
							imgWidth = imgs.width
							imgHeight = imgs.height
							const canvas = that.$refs.canvas
							that.context = canvas.getContext("2d");
							that.context.drawImage(imgs, 0, 0, that.imgWidth, that.imgHeight);
							that.context.save();
							that.context.font = "bold 76px Source Han Sans CN";
							that.context.textAlign = "center";
							that.context.fillStyle = "#2274F6"
							that.context.fillText(that.name, that.imgWidth / 2, 516, 600);
							that.context.save();
							document.body.scrollTop = document.documentElement.scrollTop = 0
							var base64Img = canvas.toDataURL('image/jpeg');
							that.showImg = true;
							that.saveImg = base64Img;

						};
					},
					afterLoad() {
						vant.Toast.clear();
					},
				},
			})
		</script>

	</body>


</html>