本来用富文本编辑器写了一次 不知道为什么代码没有换行;第一次记录所以有重新用编辑器写了一次
最近电商开发使用canvas生成海报比较多;在此做一个简单的绘画文字需要换行的问题
实现思路
循环文字长度累计计算文字长度;通过传入最大长度width判断当前位置长度是否超过最大长度;
通过charCodeAt判断Unicode 区分汉字和特殊字符计算不同宽度汉字采用字体大小宽度,特殊字符采用 canvas.measureText获取字体宽度;
数据格式
{
type: "text", //数据类型
x: 10, //横轴
y: 360, //纵坐标
width: 340, //文字显示最大长度
fontSize: "14px", //字体大小
fontColor: "#000000", //字体颜色
text: "a我们输入过多的文字来测试看看它会不会换行试看看它会不会换行" //文本内容
}
具体代码参考:
/**
* @description: 画文字
* @param {*} ctx 画布上下文
* @param {*} rect 参数对象
* { //基本格式
* fontSize 字体大小
* fontColor 字体颜色
* text 文本
* x,t,width, height//基本属性
* }
* @return {*}
*/
export function fontRext(ctx, rect) {
ctx.save();
ctx.font = `${rect.fontSize || "14px"} Microsoft YaHei`;
ctx.fillStyle = rect.fontColor || "#000000";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText(rect.text, rect.x, rect.y);
ctx.restore();
}
//绘画文本
function drawText(rect) {
const newRect = JSON.parse(JSON.stringify(rect));
let textWidth = 0; //累计宽度
let substringIndex = 0; //截取位置
for (let index = 0; index < rect.text.length; index++) {
const element = rect.text[index];
// 获取字体实际高度
textWidth += element.charCodeAt(0) > 255 ? parseInt(rect.fontSize) : Math.ceil(ctx.measureText(element).width);
//ctx.measureText(element).width
// textWidth += 14;
// 字体累计宽度大于文字宽度
if (textWidth > (rect.width || option.width)) {
//画截取字段
newRect.text = rect.text.substring(substringIndex, index);
fontRext(ctx, newRect);
//设置开始下标 和 枢轴 y
substringIndex = index;
textWidth = 0;
newRect.y = newRect.y + parseInt(newRect.fontSize);
}
if (index === rect.text.length - 1) {
newRect.text = rect.text.substring(substringIndex, index + 1);
fontRext(ctx, newRect);
}
}
}
最后
由于项目使用的海报不是很复杂;所以比较简陋;还有很多可以完善例如;字体高度间距 行高
后面我还会吧画圆角矩形、圆角图片、圆角边框矩形的分享出来;