文中所有参数为canvas的定义
const query = wx.createSelectorQuery()
query.select('#poster').fields({ node: true, size: true }).exec(async (res) => {
const canvas = res[0].node
//此处的canvas即下列封装方法参数cavans
})
1:矩形
// 绘制矩形
export const drawRect = (ctx: CanvasRenderingContext2D, width: number, height: number, backgroundColor = '#fff', x = 0, y = 0): Promise<boolean> => {
return new Promise(resolve => {
ctx.save()
ctx.rect(x, y, width, height)
ctx.fillStyle = backgroundColor
ctx.fill()
ctx.restore()
resolve(true)
})
}
2:绘制文字
export const drawText = (ctx: CanvasRenderingContext2D, content: string, color = '#fff', size = 14, fontWeight = 400, fontFamily = 'Alibaba-PuHuiTi-R, Alibaba-PuHuiTi', x = 0, y = 0): Promise<boolean> => {
return new Promise(resolve => {
ctx.save()
ctx.textBaseline = 'top'
ctx.textAlign = 'left'
ctx.font = `normal ${fontWeight} ${size}px ${fontFamily}`
ctx.fillStyle = color
ctx.fillText(content, x, y)
ctx.restore()
resolve(true)
})
}
3:绘制多行文本
// width指文本宽度多少时换行
export const drawMultiLineText = (ctx: CanvasRenderingContext2D, width: number, lineHeight: number, content: string, x = 0, y = 0, color = '#fff', size = 14, fontWeight = 400, fontFamily = 'Alibaba-PuHuiTi-R, Alibaba-PuHuiTi',): Promise<boolean> => {
return new Promise(resolve => {
ctx.save();
let arrText = content.split("");
let line = "";
ctx.font = `normal ${fontWeight} ${size}px ${fontFamily}`
ctx.fillStyle = color
ctx.textBaseline = "top";
ctx.textAlign = 'left'
for (let n = 0; n < arrText.length; n++) {
let testLine = line + arrText[n];
let metrics = ctx.measureText(testLine);
let testWidth = metrics.width;
if (testWidth > width && n > 0) {
ctx.fillText(line, x, y);
line = arrText[n];
y += lineHeight;
} else {
line = testLine;
}
}
ctx.fillText(line, x, y);
ctx.restore();
resolve(true);
});
}
4:绘制图片
//此处canvas参数请查看文章开头注释
export const drawImage = (canvas: any, ctx: CanvasRenderingContext2D, src: string, width: number, height: number, x = 0, y = 0): Promise<boolean> => {
return new Promise(resolve => {
const nowTime = new Date().getTime()
ctx.save()
let pic = canvas.createImage();
pic.src = `${src}?${nowTime}`//nowTime防止图片缓存
pic.onload = () => {
ctx.drawImage(pic, x, y, width, height);
ctx.restore()
resolve(true)
}
})
}
5:绘制圆形图片
//此处canvas参数请查看文章开头注释
//此处的x与y记住需要加上原型图片的半径;原理自己思考;
export const drawCircleImage = (canvas: any, ctx: CanvasRenderingContext2D, src: string, r: number, x = 0, y = 0,): Promise<boolean> => {
return new Promise(async resolve => {
ctx.save()
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2, false);
ctx.clip();
//此处的drawImage即 4:绘制图片方法
await drawImage(canvas, ctx, src, r * 2, r * 2, x - r, y - r)
ctx.restore()
resolve(true)
})
}
6:绘制圆形图片&&带边框
//此处canvas参数请查看文章开头注释
//此处的x与y记住需要加上原型图片的半径以及border宽度;原理自己思考;
export const drawCircleImageWithBorder = (canvas: any, ctx: CanvasRenderingContext2D, src: string, x = 0, y = 0, r = 0, borderWidth = 1, backgroundColor = "#fff", borderColor = '#fff'): Promise<boolean> => {
return new Promise(resolve => {
ctx.save()
ctx.beginPath()
ctx.arc(x, y, r + borderWidth, 0, Math.PI * 2, false)
ctx.fillStyle = borderColor
ctx.fill()
ctx.save()
ctx.beginPath()
ctx.arc(x, y, r + borderWidth, 0, Math.PI * 2, false)
ctx.fillStyle = backgroundColor
ctx.fill()
ctx.clip()
wx.downloadFile({
url: src,
success: async (res) => {
if (res.statusCode === 200) {
//此处的drawImage即 4:绘制图片方法
await drawImage(canvas, ctx, res.tempFilePath, r * 2, r * 2, x - r, y - r,)
ctx.restore()
resolve(true)
}
}
})
})
}
7:测量文本宽度
export const measureTextWidth = (ctx: CanvasRenderingContext2D, content: string, fontWeight = 400, size = 14, fontFamily = 'Alibaba-PuHuiTi-R, Alibaba-PuHuiTi'): number => {
ctx.font = `normal ${fontWeight} ${size}px ${fontFamily}`
const width = ctx.measureText(content).width
return width
}
8:cavans导出图片
// 画布导出=>图片
//此处canvas参数请查看文章开头注释
export const canvasToImage = (canvas: any, width: number, height: number, x = 0, y = 0): Promise<boolean> => {
return new Promise(resolve => {
wx.canvasToTempFilePath({
canvas,
x,
y,
width, //自己定义canvas的宽度
height, //自己定义canvas的高度
success: function (res) {
let tempFilePath = res.tempFilePath
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: function () {
resolve(true)
},
fail: (err) => {
wx.hideLoading()
if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
wx.showModal({
title: '提示',
content: '请授权保存到相册',
showCancel: false,
success() {
wx.openSetting({
success(openres) {
if (openres.authSetting['scope.writePhotosAlbum']) {
console.log('获取权限成功')
} else {
console.log('获取权限失败')
}
},
fail(failerr) {
console.log("failerr", failerr)
}
})
}
})
}
}
})
},
fail: function (res) {
console.log(res)
wx.hideLoading()
}
})
})
}