先看下效果图:
代码如下,后面解释(小程序为例)
content = "canvas的绘制文本自动换行 By Frank";
const ctx = wx.createCanvasContext('canvas');
ctx.setFillStyle('#666') // 文字颜色
ctx.setTextAlign('center') //水平对齐
ctx.setFontSize(18);//字体大小
let canvasWidth = 100; //画布宽度
let canvasHeight = 300; //画布宽度
let textareaWidth = Math.ceil(canvasWidth/18); //画布宽度除以字号
let text = [];//存放切割后的内容
while (content.length > 0) {
text.push(content.substr(0, textareaWidth ))
content = content.substr(textareaWidth, content.length)
}
//设置文本垂直居中
for (let i = 0; i < text.length; i++) {
let h = 0;
switch (text.length){
case 1:
h = (canvasWidth/ 100) * (i + 1 * 22) + (i * 20);
break;
case 2:
h = (canvasWidth/ 100) * (i + 1 * 20) + (i * 20);
break;
case 3:
h = (canvasWidth/ 100) * (i + 1 * 17) + (i * 20);
break;
}
ctx.fillText(text[i], canvasWidth/ 2, h)
}
解释:
1、设置字号、计算一行画布可绘制多少文字
ctx.setFontSize(18);//字体大小
let canvasWidth = 100; //画布宽度
let textareaWidth = Math.ceil(canvasWidth/18); //画布宽度除以字号
这句代码可以得到当前画布的宽度可以最多可以有几个字,当然,为了样式的美观,我们可以在canvasWidth减去内边距,例如:
ctx.setFontSize(18);//字体大小
let canvasWidth = 100;//画布宽度
let marginWidth = canvasWidth - 20 //画布宽度 - 20内边距 canvasWidth不要修改,水平时居中要用到
let textareaWidth = Math.ceil(marginWidth/18);
2、按画布的宽度切割文本
let text = [];//存放切割后的内容
while (content.length > 0) {
text.push(content.substr(0, textareaWidth ))
content = content.substr(textareaWidth, content.length)
}
这里将文字按照画布的宽度切割成一行存入数组中。或者你也可以不存储,在循环中也可以直接绘制到画布,但是多行文字不会垂直居中。(参照效果图中昵称下的介绍文本)代码如下:
for (let i = 0; i < content.length; i++) {
let text = content.substr(0, textareaWidth );
content = content.substr(textareaWidth, content.length)
ctx.fillText(text, canvasWidth/ 2, (canvasWidth/ 67)+ (15*i))
}
canvasWidth/ 2为设置水平居中, (canvasWidth/ 67)文字所在的高度 +(15*i)定义文本的行高
3、设置文本垂直居中
for (let i = 0; i < text.length; i++) {
let h = 0;
switch (text.length){
case 1:
h = (canvasHeight / 100) * (i + 1 * 22) + (i * 20);
break;
case 2:
h = (canvasHeight / 100) * (i + 1 * 20) + (i * 20);
break;
case 3:
h = (canvasHeight / 100) * (i + 1 * 17) + (i * 20);
break;
}
ctx.fillText(text[i], canvasWidth/ 2, h)
}
因为在博主的业务需求中最长的文本也不会超过3行,所以这里只需做个判断,来给第1行设置起始位置(y坐标)。
这里其实还是需要优化的,目前博主能力有限暂时这样写
h = (canvasHeight / 100) * (i + 1 * 17) + (i * 20);
(i + 1 * 17) 为当前行的起始位置(y坐标)
(i * 20) 为行距
若画布宽度使用百分比的话仅需修改canvasHeight 、canvasWidth 即可