canvas公用函数封装
前言
在传播和分享中很多时候会用到canvas生成图片进行分享的操作,场景不一需求也不一致,但是有些方法是比较公用,适当的做一些抽离,下边就是我列的几个比较常用的方法。
把长段文字进行多行拆分
// 把需要绘制的文字根据参数改成多行,然后逐行绘制
export const getCanvasMultiLineText = (
ctx: WechatMiniprogram.CanvasContext,
options: {
text: string,
width: number,
fontSize: number
}
) => {
const {
text,
width,
fontSize
} = options;
// 这要单独提一下如果不设置 font-family的话,在小程序端会有展示异常问题
ctx.font = `${fontSize}px sans-serif`
ctx.setFontSize(fontSize);
let textArr: any = text.split(''),
lineArr: string[] = [],
line = '';
textArr.forEach((word: string, index: number) => {
if (index > 0 && ctx.measureText(`${line}${word}`).width > width) {
lineArr.push(line);
line = word;
} else {
line = `${line}${word}`;
if (index === textArr.length - 1) {
lineArr.push(line)
}
}
});
return lineArr
}
逐行绘制文本
// 逐行绘制文本
export const drawMultiLineTextOnCanvas = (
ctx: WechatMiniprogram.CanvasContext,
options: {
text: string,
width: number,
fontSize: number,
line?: number,
color: string,
align?: "left" | "center" | "right",
baseline?: "top" | "bottom" | "middle" | "normal",
x: number,
y: number,
lineHeight?: number
}
) => {
const {
text,
width,
fontSize,
line = 1,
color,
align = 'left',
baseline = 'top',
x,
y,
lineHeight = fontSize * 1.5
} = options;
let textLineArr: any = getCanvasMultiLineText(ctx, { text, width, fontSize })
textLineArr.slice(0, line).forEach((str: string, index: number) => {
let textTemp = textLineArr.length > line && index === line - 1
? `${str.substring(0, str.length - 2)}...`
: str;
ctx.save();
ctx.setFillStyle(color);
ctx.setFontSize(fontSize);
ctx.setTextAlign(align);
ctx.setTextBaseline(baseline);
ctx.fillText(textTemp, x, y + index * lineHeight);
ctx.restore();
});
}
小程序网络图片转本地图片
// 小程序网络图片转本地图片
export const getLocalePathFromNetImgUrl = (images: string[]) => {
const promises: any = [];
images.forEach((image: any, index: number) => {
const promise = new Promise((resolve, reject) => {
wx.getImageInfo({
src: image,
success: res => {
resolve(extend(true, {
index
}, res))
},
fail: reject
})
})
promises.push(promise);
})
return Promise.all(promises)
}
canvas圆角方法
roundRect(ctx: any, x: number, y: number, w: number, h: number, r: number, c: string) {
if (w < 2 * r) {
let r = w / 2;
}
if (h < 2 * r) {
let r = h / 2;
}
ctx.beginPath();
ctx.fillStyle = 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();
},
canvas 圆形方法
// canvas 圆形方法
getCirclePic(ctx: any, x: number, y: number, r: number, pic: string, dx: number, dy: number, dWidth: number, dHeight: number) {
// x:圆心x轴位置
// y:圆心y轴位置
// r:圆半径
// pic:图片
// dx:图片左上角x轴位置
// dy:图片左上角y轴位置
// dWidth:图片的宽
// dHeight:图片的高
ctx.save();
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI, false);
ctx.fill();
ctx.clip();
ctx.drawImage(pic, dx, dy, dWidth, dHeight);
ctx.restore();
},
总结
公用的方法目前封装了这几个,如果以后还有其他的需求,在进行填充,生命不息,代码重构不止~
如果小伙伴们觉得有用的话欢迎点赞分享~
如果有其他好的方法也可以评论区留言,大家一同进步~