canvas绘制海报中封装的方法

封装的方法

//  * 获取图片信息用来绘制
//* @param {  String } src - 图片的路径 本地路径或者网络都可以
//* /
getImageInfo(src) {
	return new Promise(r => {
		uni.getImageInfo({
			src,
			success: (res) => {
				r(res)
			},
		})
	})
},
//  * 绘制不会换行的文字
//* @param { Object } ctx - canvas组件的绘图上下文
//* @param { String } text - 需要被绘制的文字
//* @param { String } text- 需要被绘制的文字的大小
//* @param { String } color -文字的颜色
//* @param { Number } x - 文字的x坐标
//* @param { Number } y - 文字的y坐标
//* @param { Number } maxWidth - 文字最多可以多宽
//* @param { Boolean } bold - 是否粗体
//* /
drawText(ctx, text, fontSize, color, x, y, maxWidth, bold) {
if (bold) {
		ctx.font = `bold ${fontSize}px sans-serif`;
	} else {
		ctx.font = `normal ${fontSize}px sans-serif`;
	}
	ctx.setFillStyle(color)
	if (ctx.measureText(text).width > maxWidth) {
		var count = 1;
		while (ctx.measureText(text.slice(0, text.length - count)).width > 693) {
			count++
		}
		ctx.fillText(text.slice(0, text.length - (count + 1)) + "...", x, y)
	} else {
		ctx.fillText(text, x, y)
	}
},
//  * 绘制不会换行的文字
//* @param { Object } ctx - canvas组件的绘图上下文
//* @param { String } text - 需要被绘制的文字
//* @param { String } text- 需要被绘制的文字的大小
//* @param { String } color -文字的颜色
//* @param { Number } x - 文字的x坐标
//* @param { Number } y - 文字的y坐标
//* @param { Number } maxWidth - 文字最多可以多宽
//* @param { Number } maxHeight- 文本最多可以多高
//* /
drawTextMax(ctx, text, fontSize, color, x, y, maxWidth, maxHeight) {
	ctx.font = `normal ${fontSize}px sans-serif`;
	ctx.setFillStyle(color)
	if (ctx.measureText(text).width > maxWidth) {
		console.log(text)
		let textList = [];
		var count = 1;
		var colNum = 0;
		var rowTextNum = 0;
		let lineHeight = 1.6
		while (ctx.measureText(text.slice(0, text.length - count)).width > maxWidth) {
			count++
		}
		rowTextNum = Math.floor(text.length - count)
		colNum = Math.ceil(text.length / rowTextNum)
		for (var i = 0; i < colNum; i++) {
			textList.push(text.substr(rowTextNum * i, rowTextNum))
		}
		if (textList.length * fontSize * lineHeight > maxHeight) {
			let heng = Math.floor(textList.length - ((textList.length * fontSize * lineHeight -
				maxHeight) / (fontSize * lineHeight)));
			textList[heng] = textList[heng].substr(0, textList[heng].length - 1) + "..."
			textList.slice(0, heng + 1).map((ele, index) => {
				ctx.fillText(ele, x, y + index * fontSize * lineHeight)
			})
		} else {
			textList.forEach((ele, index) => {
				ctx.fillText(ele, x, y + index * fontSize * lineHeight)
			})
		}
	} else {
		ctx.fillText(text, x, y)
	}
},
//  * 绘制圆角矩形
//* @param { Object } ctx - canvas组件的绘图上下文
//* @param { String } imageUrl -  图片的路径 本地路径或者网络都可以
//* @param { Number } x - 图片的x坐标
//* @param { Number } y - 图片的y坐标
//* @param { Number } w - 图片的宽度
//* @param { Number } h - 图片的高度
//* /
drawImage(ctx, imageUrl, x, y, w, h) {
	return new Promise((r) => {
		var res = this.getImageInfo(imageUrl).then((res) => {
			ctx.drawImage(res.path, x, y, w, h)
			setTimeout(() => {
				r()
			}, 200)
		})
	})
},
//  * 绘制圆角矩形
//* @param { Object } ctx - canvas组件的绘图上下文
//* @param { Number } x - 矩形的x坐标
//* @param { Number } y - 矩形的y坐标
//* @param { Number } w - 矩形的宽度
//* @param { Number } h - 矩形的高度
//* @param { Number } r - 矩形的圆角半径
//* @param { String } [c = 'transparent'] - 矩形的填充色
//* /
roundRect(ctx, x, y, w, h, r, c = '#fff') {
	if (w < 2 * r) {
		r = w / 2;
	}
	if (h < 2 * r) {
		r = h / 2;
	}

	ctx.beginPath();
	ctx.fillStyle = c;
	// ctx.setFillStyle(c)
	ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
	ctx.moveTo(x + r, y);
	ctx.lineTo(x + w - r, y);
	ctx.lineTo(x + w, y + r);

	ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
	ctx.lineTo(x + w, y + h - r);
	ctx.lineTo(x + w - r, y + h);

	ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
	ctx.lineTo(x + r, y + h);
	ctx.lineTo(x, y + h - r);

	ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
	ctx.lineTo(x, y + r);
	ctx.lineTo(x + r, y);
	ctx.fill();
	ctx.closePath();

},

绘制过程

			this.canvasWidth = 750
			this.canvasHeight = 1375
			setTimeout(async () => {
				this.roundRect(this.ctx, 0, 0, this.canvasWidth, this
					.canvasHeight, 12,
					"#ffffff")
				// ctx, text, fontSize, color, x, y, bold
				this.drawText(this.ctx, this.item.enterpriseName, 36,
					"#222222", 28, 193, 693, true)
				this.ctx.restore()
				this.drawText(this.ctx,
					`${this.item.enterpriseNatureName} | ${this.item.enterpriseScaleName} | ${this.item.enterpriseIndustryName}`,
					28,
					"#666666", 28, 248, 693)
				// ctx, text, fontSize, color, x, y, maxHeight, maxWidt


				// this.ctx.setFontSize()
				await this.drawImage(this.ctx, this.item.enterpriseLogo,
					28, 46, 96, 96)
				await this.drawImage(this.ctx,
					this.item.pictures[0].pictureUrl, 28, 298, 694, 320
				)
				this.drawTextMax(this.ctx,
					this.item.enterpriseBriefIntroduction,
					28,
					"#666666", 28, 693, 693, 430)
				await this.drawImage(this.ctx, this.item.enterpriseLogo,
					28, 1159, 168, 168)
				this.drawText(this.ctx, '该公司还有很多精彩内容', 32,
					"#222222", 219, 1227, 693 - 209, true)
				this.drawText(this.ctx, '快来由信APP了解更多吧~', 26,
					"#666666", 219, 1287, 693 - 209, false)
				this.ctx.draw()
				setTimeout(() => {
					uni.canvasToTempFilePath({
						x: 0,
						y: 0,
						width: this.canvasWidth,
						height: this.canvasHeight,
						destWidth: this.canvasWidth,
						destHeight: this.canvasHeight,
						// quality: 0.5,
						canvasId: 'myCanvas',
						success: (res) => {
							this.imageSrc = res
								.tempFilePath
						}
					})
				}, 300)
			}, 200)

绘制结果

在这里插入图片描述
上面绘制多行文字的修改版

drawTextMax(ctx, text, fontSize, color, x, y, maxWidth, maxHeight) {
				ctx.font = `normal ${fontSize}px sans-serif`;
				ctx.setFillStyle(color)
				if (ctx.measureText(text).width > maxWidth) {
					let textList = [];
					var count = 1;
					var colNum = 0;
					var rowTextNum = 0;
					let lineHeight = 1.6;
					var endIndex = 0;
					var startIndex = 0;
					while (endIndex < text.length) {
						if (ctx.measureText(text.slice(startIndex, endIndex)).width > maxWidth - fontSize ) {
							textList.push(text.substring(startIndex, endIndex))
							startIndex = endIndex
						} else {
							endIndex++
						}
					}
					textList.push(text.substring(startIndex, endIndex))
					if (textList.length * fontSize * lineHeight > maxHeight) {
						let heng = Math.floor(textList.length - ((textList.length * fontSize * lineHeight -
							maxHeight) / (fontSize * lineHeight)));
						textList[heng] = textList[heng].substr(0, textList[heng].length - 1) + "..."
						textList.slice(0, heng + 1).map((ele, index) => {
							ctx.fillText(ele, x, y + index * fontSize * lineHeight)
						})
					} else {
						textList.forEach((ele, index) => {
							ctx.fillText(ele, x, y + index * fontSize * lineHeight)
						})
					}
				} else {
					ctx.fillText(text, x, y)
				}
			},

新加方法

防止图片变形,并且居中显示图片内容

// 调用方法
await this.drawImageWidthFix(this.ctx, this.item.enterpriseLogo,
					28, 1159, 168, 168)
					//  方法封装
drawImageWidthFix(ctx, imageUrl, x, y, w, h){
				return new Promise((r) => {
					var res = this.getImageInfo(imageUrl).then((res) => {
						// ctx.drawImage(res.path, x, y, w, h)
						// drawImage(dx, dy)
						// drawImage(dx, dy, dWidth, dHeight)
						// res.width 
						// res.height
						// 200 200
						// 694 320 694
						// w, h
						var proix = h / w
						let scaleNum = w / res.width;
						let shouldHeight = res.height * scaleNum
						var sHeight = res.width * proix 
						var sy = (res.height - sHeight) / 2;
						console.log(shouldHeight, sHeight,sy)
						ctx.drawImage(res.path,0, sy, res.width, sHeight, x, y, w, h)
						setTimeout(() => {
							r()
						}, 200)
						
					})
				})
			},

防止图片变形,并且居中显示图片内容2

// 调用方法
	drawImageWidthFix1(ctx, imageUrl, x, y, w, h) {
				return new Promise((r) => {
					var res = this.getImageInfo(imageUrl).then((res) => {
					var proix = h / w
						var sx = 0;
						var sy = 0;
						var sWidth = res.width;
						var sHeight = res.height;
						let scaleNum = 0;
						if (res.width > res.height) {
							sWidth = res.height * proix
							sx = (res.width - sWidth) / 2
						} else {
							sHeight = res.width * proix
							sy = (res.height - sHeight) / 2;
						}
				ctx.drawImage(res.path, sx, sy, sWidth, sHeight, x, y, w, h)
						setTimeout(() => {
							r()
						}, 200)

					})
				})
			},
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值