canvas native canvas-uniapp

<template>
	<view class="demo">
		<view class="" v-show="!canvas_img" style="z-index:999;">
			<canvas :style="{ width: canvasW*2 + 'rpx', height: canvasH*2 + 'rpx' }" canvas-id="myCanvas" id="myCanvas01" style="z-index:99999999;"></canvas>
		</view>
		<view style="z-index:9999;position: absolute;">
			<image :src="canvas_img" mode="widthFix"  v-if="canvas_img" style="width:100vw;height:100vh"></image>
		</view>
	</view>
</template>
<script>
	export default {
    
    
		data() {
    
    
			return {
    
    
				canvasW: 0, // 画布宽
				canvasH: 0, // 画布高
				SystemInfo: {
    
    }, // 设备信息
				goodsImg: {
    
    }, // 商品主图信息
				ewmImg: {
    
    }, // 二维码图片信息
				ewmW: 100, // 二维码大小
				title1: '电动窗帘',
				title2: '十大品牌评选',
				isShow: false,
				canvas_img:"",
				goodsImgUrl:'../../static/poster/posterOne.png',//海报背景图
			}
		},
		async onLoad() {
    
    
			let that = this;
			// 获取设备信息,主要获取宽度,赋值给canvasW 也就是宽度:100%
			this.SystemInfo = await this.getSystemInfo();

			// 获取商品主图,二维码信息,APP端会返回图片的本地路径(H5端只能返回原路径)
			let goodsImgUrl = this.goodsImgUrl; // 主图本地路径,也可以用网络地址
			let ewmImgUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAADeklEQVR42u3cUVKEQAxF0dn/pnUL\njslLB/rcT0thhGNVaMDPjxTo4xAILIElsCSwBJbAksASWAJLAktgCSwJLIElsCSwBJbAksASWAJL\nAktgCSwJLIElsCSwBJbAksASWAKrZzeB/rKvzZ/5298lfdzAAgsssMACC6xnw0ps59sTmT7QFUyT\nxw0ssMACCyywwHonrFMDbxeIyufp2m/XcQMLLLDAAgsssMCqDu/phdM0XLDAAgsssMACC6yTB6iy\n3w0nGyywwAILLLDAAus/JzgBNL2gOrlNN6HBAgsssMACC6zqomJ6oH76171MARZYYIEFFlhgbW/D\nTeuzwzVYYIEFFlhggXX78J7eTmX7iYXK9AUBWGCBBRZYYIF1F6xvB97K9z9lsbcL8dUr72CBBRZY\nYIF1yb3CbYP5toXNyoB/9co7WGCBBRZYYF0Iq7LYmFjkTHzO9ELrs8CBBRZYYIEFFlhHdx9Alhi0\nuz5n1wKm4R0ssMACCyywwJo+0F0PDE5elKQvbq54ugEssMACCyywLoRVGTwnX3BIvzTRNaSfukEO\nFlhggQUWWGDtHd5PvVCQODGTFwcJuGCBBRZYYIEF1nuG9wqgyRcuJqGkjxVYYIEFFlhggXXv8N51\nshMHN3Fj201osMACCyywwAKrE9bksJ+4UEijTPzsFcM7WGCBBRZYYIE1thiYWIA9tZiZfuARLLDA\nAgsssMB6Hqyug9WFrPLHkACXuJjwdANYYIEFFlhgWceqLiqmT3Bi8E9ccCQWeMECCyywwAILrGfD\nmlzAfPo2uwZ8sMACCyywwALrnbASB7pr8E+8ELEZLlhggQUWWGCBddcCaeVkT6JMPKyXePAQLLDA\nAgsssMB6D6xJuIlhdhJr5fcFCyywwAILLLDuHd4TQ2viwcA0gvTDgNfdhAYLLLDAAgss/x/ryHY2\nYEosIO9EBhZYYIEFFlhgnYSVGGYrJzi9GJt4YHDyDxsssMACCyywwAJrYvjtQlB5SLALPVhggQUW\nWGCBBVbnkJ4YnBMvWewZzMECCyywwAILrO2wEkC7IKaH7smhHiywwAILLLDAej+s9MsUia9v/tmd\nQz1YYIEFFlhggSWBJbAElgSWwBJYElgCS2BJYAksgSWBJbAElgSWwBJYElgCS2BJYAksgSWBJbAE\nlgSWwBJYElgCS2BJX/cLbA821BMbPggAAAAASUVORK5CYII='
			
			// let ewmImgUrl = new Image();
			// ewmImgUrl.src = 'http://soutoupiao.com/upload/image/2021-08-28/1431480334745251841.png';
			// ewmImgUrl.crossOrigin = 'Anonymous'; // 支持跨域图片
			
			this.goodsImg = await this.getImageInfo(goodsImgUrl);
			this.ewmImg = await this.getImageInfo(ewmImgUrl);
			
			this.canvasW = this.SystemInfo.windowWidth; // 画布宽度
			console.log(this.canvasW)
			this.canvasH = this.SystemInfo
			.windowHeight; //this.goodsImg.height + this.ewmW + 10;  // 画布高度 = 主图高度+二维码高度 + 文字图片的间距(大概50)

			// 如果主图,二维码图片,设备信息都获取成功,开始绘制海报,这里需要用setTimeout延时绘制,否则可能会出现图片不显示。
			if (this.goodsImg.errMsg == 'getImageInfo:ok' && this.ewmImg.errMsg == 'getImageInfo:ok' && this.SystemInfo
				.errMsg == 'getSystemInfo:ok') {
    
    
				console.log('读取图片信息成功')
				uni.showToast({
    
    
					icon: 'loading',
					mask: true,
					duration: 1200,
					title: '海报绘制中',
				});
				setTimeout(() => {
    
    
					var ctx = uni.createCanvasContext('myCanvas', this);
					// 1.填充背景色,白色
					ctx.setFillStyle('#fff'); // 默认白色
					ctx.fillRect(0, 0, this.canvasW, this.canvasH) // fillRect(x,y,宽度,高度)

					// 2.绘制商品主图,二维码
					ctx.drawImage(goodsImgUrl, 0, 0, this.canvasW, this.canvasH) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
					ctx.drawImage(ewmImgUrl, this.canvasW-134, this.canvasW+140, this.ewmW, this.ewmW) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度,二维码的宽,高)

					// 4、标题
					ctx.setFontSize(40); // 字号
					ctx.setFillStyle('#fff'); // 颜色
					ctx.font = "bold 40px webfont"; //字粗
					ctx.fillStyle = "#FCFAF8"; //填充颜色
					ctx.shadowBlur = 2;
					ctx.shadowOffsetX = 2;
					ctx.shadowOffsetY = 2;
					ctx.shadowColor = "#000000";
					let width1 = (this.canvasW - 160) / 2;
					let width2 = (this.canvasW - 240) / 2;
					ctx.fillText(this.title1, width1, 130); // (文字,x,y)
					ctx.setFillStyle('#fff'); // 颜色
					ctx.fillText(this.title2, width2, 180); // (文字,x,y)

					// draw方法 把以上内容画到 canvas 中
					setTimeout(() => {
    
     //必须延迟执行 不然H5不显示
						ctx.stroke();
						ctx.draw(true, (ret) => {
    
    
							this.isShow = true // 显示按钮-保存图片到相册
							// uni.showToast({
    
    
							// 	icon: 'success',
							// 	mask: true,
							// 	title: '绘制完成',
							// });
							uni.canvasToTempFilePath({
    
     // 保存canvas为图片
								canvasId: 'myCanvas',
								quality: 1,
								complete: function(res) {
    
    
									// 在H5平台下,tempFilePath 为 base64, // 图片提示跨域 H5保存base64失败,APP端正常输出临时路径
									console.log(res.tempFilePath);
									that.$nextTick(()=>{
    
    
										that.canvas_img = res.tempFilePath;
									});
									uni.setStorageSync('filePath', res.tempFilePath); //保存临时文件路径到缓存
								},
							})
						});
					}, 200)

				}, 1000)

			} else {
    
    
				console.log('读取图片信息失败')
			}
		},

		methods: {
    
    
			// 获取图片信息
			getImageInfo(image) {
    
    
				return new Promise((req, rej) => {
    
    
					uni.getImageInfo({
    
    
						src: image,
						success: function(res) {
    
    
							req(res)
						},
					});
				})
			},

			// 获取设备信息
			getSystemInfo() {
    
    
				return new Promise((req, rej) => {
    
    
					uni.getSystemInfo({
    
    
						success: function(res) {
    
    
							req(res)
						}
					});
				})
			},
			imgs(){
    
    
				console.log(121)
			}
		}
	}
</script>

<style>
	@font-face {
    
    
		font-family: 'webfont';
		font-display: swap;
		src: url('//at.alicdn.com/t/webfont_6ks3jctruok.eot');
		/* IE9*/
		src: url('//at.alicdn.com/t/webfont_6ks3jctruok.eot?#iefix') format('embedded-opentype'),
			/* IE6-IE8 */
			url('//at.alicdn.com/t/webfont_6ks3jctruok.woff2') format('woff2'),
			url('//at.alicdn.com/t/webfont_6ks3jctruok.woff') format('woff'),
			/* chrome、firefox */
			url('//at.alicdn.com/t/webfont_6ks3jctruok.ttf') format('truetype'),
			/* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
			url('//at.alicdn.com/t/webfont_6ks3jctruok.svg#NotoSansHans-Black') format('svg');
		/* iOS 4.1- */
	}

	#font_span {
    
    
		font-family: "webfont" !important;
		font-style: normal;
		-webkit-font-smoothing: antialiased;
		-webkit-text-stroke-width: 0.2px;
		-moz-osx-font-smoothing: grayscale;
		font-weight: bold;
	}

	/* .btn{
		margin-left: 20rpx;
		margin-right: 20rpx;
		margin-bottom: 20rpx;
		width: 94%;
	} */
</style>

Guess you like

Origin blog.csdn.net/weixin_49295874/article/details/119968357