使用canvas绘制海报

使用canvas绘制海报_第1张图片

想要绘制这样的海报

1.结构



	
	


//对于微信公众号,可以使用html2canvas将html转成图片然后设置一个图片蒙层,src是转成的图片地址。然后长按保存

	
		
			
				
					
					
						鱿鱼圈
						SquidTrade
					
				
				
					
						
						
						
						
						
						
						
					
					
						
							{{goodsDetail.title}}
							当前价 {{goodsDetail.now_price}}鱿鱼圈
						
						
							
						
					
				
			
			
			
			
		
	

import html2canvas from '@/common/html2canvas.min.js'

 2.数据

// 用来控制canvas遮罩层的显示与隐藏
posterInfo: {
	status: false,
	type:0,
	usercode:''
},
img:''   //保存到本地的海报地址
canvasW:0,
canvasH:0,

3.绘制

	generatePoster(){
		// #ifdef H5
		if(this.isweixin){
			let that = this
			this.$refs.poster.open()
			uni.showLoading({
				title:'海报生成中。。。'
			})
			setTimeout(() => {
				const dom = document.querySelector('.my-canvas') // 需要生成图片内容的 dom 节点
				html2canvas(dom, {
				  width: dom.clientWidth, //dom 原始宽度
				  height: dom.clientHeight,
				  scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
				  scrollX: 0,
				  useCORS: true, //支持跨域
				  scale: 2, // 设置生成图片的像素比例,默认是1,如果生成的图片模糊的话可以开启该配置项
				}).then((canvas) => {
				  // 生成成功
				  // html2canvas 生成成功的图片链接需要转成 base64位的url
				  // ownerFun.callMethod('receiveRenderData', canvas.toDataURL('image/png'))
				   that.img = canvas.toDataURL('image/png')
				   uni.hideLoading()
				   console.log(that.img,'图片生成成功')
				   console.log(canvas,'canvas')
				}).catch(err=>{
				  // 生成失败 弹出提示弹窗
				  // ownerFun.callMethod('_errAlert',`【生成图片失败,请重试】${err}`)
				  uni.hideLoading()
				  console.log(err,'图片生成失败')
				})
			  }, 300)
		}else{
			this.getPoster()
		}
		// #endif
		// #ifndef H5
		this.getPoster()
		// #endif
	},


// 生成海报
	async getPoster(){
		uni.showLoading({
			title: '海报生成中'
		});
		let that = this
		// 获取设备信息,主要获取宽度,赋值给canvasW 也就是宽度:100%
		this.SystemInfo = await this.getSystemInfo();
		this.canvasW = this.SystemInfo.windowWidth*0.8; // 画布宽度
		this.canvasH = this.SystemInfo.windowHeight*0.7; 
		this.posterInfo.status = true
		let logo = await this.downloadFile(this.logo)
		let imgUrl = !!this.goodsDetail.images[0]?this.goodsDetail.images[0]:this.imgUrl
		this.goodsImg = await this.downloadFile(imgUrl);
		this.ewmImg = await this.downloadFile(this.posterInfo.usercode);
		let typeUrl = this.type==1?"":''
		var context = uni.createCanvasContext('mycanvas',this)
		context.setFillStyle('#fff')
		context.fillRect(0,0,this.canvasW,this.canvasH)
		context.font = 'normal 400 12px PingFang SC-Bold, PingFang SC'
		context.setFillStyle('#999999');
		context.fillText('SquidTrade',80,60)
		context.setFontSize(12)
		context.setFillStyle('#999');
		context.fillText('当前价',20,that.canvasH-30)
		let priceWidth = context.measureText(this.goodsDetail.now_price).width + 80; //计算昵称宽度,绘制间隔距离
		context.setFontSize(12)
		context.setFillStyle('#333');
		context.fillText('鱿鱼圈',priceWidth,that.canvasH-30)
		
		// 绘制鱿鱼圈
		context.setFillStyle('#333')
		context.font = 'normal bold 16px PingFang SC-Bold, PingFang SC'
		context.fillText('鱿鱼圈', 80, 40);
		
		// 绘制商品名称
		// context.setFontSize(16);
		context.setFillStyle('#333');
		context.font = 'normal bold 16px PingFang SC-Bold, PingFang SC'
		context.fillText(this.goodsDetail.title,20,that.canvasH-54)
		// 绘制商品价格
			
		context.setFontSize(20)
		context.setFillStyle('#D50000');
		context.fillText(this.goodsDetail.now_price,60,that.canvasH-30)
		
		//绘制头像
		context.save()
		context.beginPath();
		context.arc(44, 44, 22, 0, 2 * Math.PI)
		context.clip();
		context.drawImage(logo.tempFilePath, 22, 22, 44, 44);
		context.restore();
		context.draw(true);
		// 商品图片
		context.drawImage(this.goodsImg.tempFilePath, 20, 80, that.canvasW-40, that.canvasH-170);
		context.draw(true);
		// 二维码
		context.drawImage(this.ewmImg.tempFilePath, that.canvasW-80, that.canvasH-80, 70, 70);
		context.draw(true);
		uni.hideLoading()
	},

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

	downloadFile(image) {
		return new Promise((req, rej) => {
			uni.downloadFile({
				url: image,
				success: function(res) {
					req(res)
				},
			});
		})
	},

4.点击保存按钮保存海报

    save(){
		let that = this
		uni.canvasToTempFilePath({
			fileType: 'jpg',
			canvasId: 'mycanvas',
			quality: 1,
			success: (res) => {
				that.img = res.tempFilePath
				console.log(res.tempFilePath,'海报地址')
				that.download()
				
			},
			fail: function(err) {
				console.log(err)
				// reject(err)
			}
		},this)
	},

	download(){
		let that = this
		console.log(this.img,'图片img')
		// 先下载图片
		uni.downloadFile({
			url:this.img,
			success: (res) => {
				console.log(res.tempFilePath,'下载后的图片地址')
				// #ifdef H5
				const imgUrl = res.tempFilePath;
				if(that.isweixin){
					uni.showToast({
						icon:'none',
						title:'请长按图片保存'
					})
					// that.preview(res.tempFilePath)
					// let canvas = document.querySelector('.my-canvas');
					// Canvas2Image.saveAsImage(canvas, this.canvasW, this.canvasH, 'png','商品分享');
				}else{
					var oA = document.createElement("a");
					oA.download = '下载图片'; // 设置下载的文件名,默认是'下载'
					oA.href = imgUrl;
					console.log(oA ,'按钮a')
					document.body.appendChild(oA);
					oA.click();
					oA.remove(); // 下载之后把创建的元素删除
				}
				// #endif
				// #ifdef MP-WEIXIN
				// 获取到图片本地地址后再保存图片到相册(因为此方法不支持远程地址)
				// that.preview()
				uni.saveImageToPhotosAlbum({
					filePath: res.tempFilePath,
					success: () => {
					uni.showToast({
							title: "保存成功!",
						});
					},
					fail: () => {
						uni.showToast({
							title: "保存失败",
						});
					},
				});
				// #endif
			},
		});
	},

css:

.my-canvas-box {
	width: 750rpx;
	height: 100%;
	position: fixed;
	left: 0;
	top: 0;
	background-color: rgba(0, 0, 0, 0.6);
	z-index: 99;
	&.hide {
		display: none;
	}
	&.show {
		display: block;
	}
	.canvas-tip {
		color: #ffffff;
		font-size: 24rpx;
		margin-top: 30rpx;
		text-align: center;
	}
	.my-canvas {
		width: 614rpx;
		height: 907rpx;
		background: #FFFFFF;
		border-radius: 24rpx;
		margin: 155rpx auto 0;
	}
	.btn{
		margin: 30rpx auto 0;
		width: 614rpx;
		height: 87rpx;
		line-height: 87rpx;
		background: #FFD14A;
		border-radius: 44rpx;
	}
}

.poster-pop{
	position: relative;
	.my-canvas{
		width: 614rpx;
		height: 907rpx;
		background: #FFFFFF;
		border-radius: 24rpx;
		.canvas-top{
			padding: 20rpx;
			image{
				width: 88rpx;
				height: 88rpx;
				border-radius: 50%;
				margin-right: 7rpx;
			}
		}
		.poster-centent{
			padding: 0 30rpx 30rpx;
		}
		.goodsimg{
			width: 555rpx;
			height: 555rpx;
			position: relative;
			image{
				width: 100%;
				height: 100%;
			}
			.goods-type{
				width: 97rpx;
				height: 97rpx;
				position: absolute;
				top:0;
				left:0
			}
		}
		.goodsmessage{
			margin-top: 38rpx;
			image{
				width: 140rpx;
				height: 140rpx;
			}
			.startprice{
				margin: 0 8rpx 0 14rpx;
			}
		}
	}
	.img-box{
		width: 614rpx;
		height: 907rpx; 
		border-radius: 24rpx;
		position: absolute;
		top: 0;
		left: 0;
	}
	.btn{
		margin: 30rpx auto 0;
		width: 614rpx;
		height: 87rpx;
		line-height: 87rpx;
		background: #FFD14A;
		border-radius: 44rpx;
		text-align: center;
	}
}

你可能感兴趣的:(#,uniapp,前端)