封装的方法
// * 获取图片信息用来绘制
//* @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)
})
})
},