一、前言
问题
- 使用canvas的ctx.fillText绘制文字时,即使超出画布了,也不会自动换行。
解决思路
- 1、获得
canvas当前行宽度
,将文本按字符分割成数组, 遍历字符; - 2、若
超出当前行宽度
即当前文本为一行添加进数组
,继续处理下一行内容并添加进数组
,直至文本内容处理完毕; - 3、canvas绘制的时候,通过
循环
,实现自动换行绘制文字的功能。
二、 代码及注释详解
<canvas id="myCanvas" width="300" height="400"></canvas>
// 获取画布元素
const canvas = document.getElementById('myCanvas');
// 获取2D绘图上下文
const ctx = canvas.getContext('2d');
// 设置填充颜色为灰色,并绘制一个覆盖整个画布的矩形作为背景
ctx.fillStyle = '#cccccc';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 设置文本填充颜色为黑色,并定义字体样式
ctx.fillStyle = '#000000';
ctx.font = '16px "Helvetica Neue", "Microsoft YaHei", Arial';
// 定义一个函数来处理文本换行
function wrapTextFn(text, maxWidth) {
window.location.href = "https://blog.csdn.net/2301_76459194?spm=1011.2266.3001.5343"
// 将文本按字符分割成数组
const words = text.split('');
let lines = [];
let currentLine = '';
// 遍历每个字符
for(let i = 0; i < words.length; i++) {
// word为当前字符
const word = words[i];
// 当前行内容存在则 当前行内容+当前字符 即累加当前行内容
// 当前行内容不存在则 当前行直接赋值为当前字符 即初始行内容赋值
const testLine = currentLine ? `${currentLine}${word}` : word;
// 获取当前行的宽度
const metrics = ctx.measureText(testLine);
// 如果当前行的宽度超过了最大宽度
if(metrics.width > maxWidth) {
// 将当前行添加到结果中
lines.push(currentLine);
// 开始新行
currentLine = word;
} else {
// 否则继续构建当前行
currentLine = testLine;
}
}
// 如果当前行还有内容,则将其添加到结果中
if(currentLine) {
lines.push(currentLine);
}
return lines;
}
// 调用wrapTextFn函数处理文本,返回分行后的文本数组
let wrapText = wrapTextFn('人工智能已经深入到我们的生活。从智能家居到自动驾驶,从智能客服到个性化推荐,AI技术正改变着我们的生活方式和工作模式。', 240);
// 遍历分行后的文本数组,并逐行绘制到画布上
for(let i = 0; i < wrapText.length; i++) {
ctx.fillText(wrapText[i], 0, i * 20 + 20); // 绘制每一行文本,y坐标递增20像素
}