通过文本中的换行符进行主动换行

This commit is contained in:
feipeng 2019-07-15 17:17:21 +08:00
parent ef9e437398
commit 3d14c9c446

View File

@ -143,25 +143,41 @@ export default class Painter {
} }
_preProcess(view, notClip) { _preProcess(view, notClip) {
let width; let width=0;
let height; let height;
let extra; let extra;
switch (view.type) { switch (view.type) {
case 'text': { case 'text': {
const textArray = view.text.split('\n');
//处理多个连续的'\n'
for(let i = 0; i < textArray.length ; ++i){
if(textArray[i]===''){
textArray[i]=' ';
}
}
const fontWeight = view.css.fontWeight === 'bold' ? 'bold' : 'normal'; const fontWeight = view.css.fontWeight === 'bold' ? 'bold' : 'normal';
view.css.fontSize = view.css.fontSize ? view.css.fontSize : '20rpx'; view.css.fontSize = view.css.fontSize ? view.css.fontSize : '20rpx';
this.ctx.font = `normal ${fontWeight} ${view.css.fontSize.toPx()}px ${view.css.fontFamily ? view.css.fontFamily : 'sans-serif'}`; this.ctx.font = `normal ${fontWeight} ${view.css.fontSize.toPx()}px ${view.css.fontFamily ? view.css.fontFamily : 'sans-serif'}`;
// this.ctx.setFontSize(view.css.fontSize.toPx()); // this.ctx.setFontSize(view.css.fontSize.toPx());
const textLength = this.ctx.measureText(view.text).width;
width = view.css.width ? view.css.width.toPx() : textLength;
// 计算行数 // 计算行数
const calLines = Math.ceil(textLength / width); let lines=0;
const lines = view.css.maxLines < calLines ? view.css.maxLines : calLines; let linesArray=[];
for(let i=0; i<textArray.length; ++i){
const textLength = this.ctx.measureText(textArray[i]).width;
const partWidth = view.css.width ? view.css.width.toPx() : textLength;
const calLines = Math.ceil(textLength / partWidth);
width = partWidth > width ? partWidth : width;
lines += calLines;
linesArray[i] = calLines;
}
lines = view.css.maxLines < lines ? view.css.maxLines : lines;
const lineHeight = view.css.lineHeight ? view.css.lineHeight.toPx() : view.css.fontSize.toPx(); const lineHeight = view.css.lineHeight ? view.css.lineHeight.toPx() : view.css.fontSize.toPx();
height = lineHeight * lines; height = lineHeight * lines;
extra = { extra = {
lines: lines, lines: lines,
lineHeight: lineHeight, lineHeight: lineHeight,
textArray: textArray,
linesArray: linesArray,
}; };
break; break;
} }
@ -346,36 +362,47 @@ export default class Painter {
const { const {
lines, lines,
lineHeight, lineHeight,
textArray,
linesArray
} = extra; } = extra;
const preLineLength = Math.round(view.text.length / lines);
let start = 0;
let alreadyCount = 0;
// 如果设置了id则保留 text 的长度 // 如果设置了id则保留 text 的长度
if (view.id) { if (view.id) {
const textWidth = this.ctx.measureText(view.text).width; let textWidth = 0;
for(let i = 0; i < textArray.length; ++i){
textWidth = this.ctx.measureText(textArray[i]).width > textWidth ? this.ctx.measureText(textArray[i]).width : textWidth;
}
this.globalTextWidth[view.id] = width ? (textWidth < width ? textWidth : width) : textWidth; this.globalTextWidth[view.id] = width ? (textWidth < width ? textWidth : width) : textWidth;
} }
for (let i = 0; i < lines; ++i) { let lineIndex=0;
for(let j = 0; j < textArray.length; ++j){
const preLineLength = Math.round(textArray[j].length / linesArray[j]);
let start = 0;
let alreadyCount = 0;
for (let i = 0; i < linesArray[j]; ++i) {
//绘制行数大于最大行数,则直接跳出循环
if(lineIndex >= lines){
break;
}
alreadyCount = preLineLength; alreadyCount = preLineLength;
let text = view.text.substr(start, alreadyCount); let text = textArray[j].substr(start, alreadyCount);
let measuredWith = this.ctx.measureText(text).width; let measuredWith = this.ctx.measureText(text).width;
// 如果测量大小小于width一个字符的大小则进行补齐如果测量大小超出 width则进行减除 // 如果测量大小小于width一个字符的大小则进行补齐如果测量大小超出 width则进行减除
// 如果已经到文本末尾,也不要进行该循环 // 如果已经到文本末尾,也不要进行该循环
while ((start + alreadyCount <= view.text.length) && (width - measuredWith > view.css.fontSize.toPx() || measuredWith > width)) { while ((start + alreadyCount <= textArray[j].length) && (width - measuredWith > view.css.fontSize.toPx() || measuredWith > width)) {
if (measuredWith < width) { if (measuredWith < width) {
text = view.text.substr(start, ++alreadyCount); text = textArray[j].substr(start, ++alreadyCount);
} else { } else {
if (text.length <= 1) { if (text.length <= 1) {
// 如果只有一个字符时,直接跳出循环 // 如果只有一个字符时,直接跳出循环
break; break;
} }
text = view.text.substr(start, --alreadyCount); text = textArray[j].substr(start, --alreadyCount);
} }
measuredWith = this.ctx.measureText(text).width; measuredWith = this.ctx.measureText(text).width;
} }
start += text.length; start += text.length;
// 如果是最后一行了,发现还有未绘制完的内容,则加... // 如果是最后一行了,发现还有未绘制完的内容,则加...
if (i === lines - 1 && start < view.text.length) { if (lineIndex === lines - 1 && (j < textArray.length -1 || start < textArray[j].length)) {
while (this.ctx.measureText(`${text}...`).width > width) { while (this.ctx.measureText(`${text}...`).width > width) {
if (text.length <= 1) { if (text.length <= 1) {
// 如果只有一个字符时,直接跳出循环 // 如果只有一个字符时,直接跳出循环
@ -399,7 +426,8 @@ export default class Painter {
x = -(width / 2); x = -(width / 2);
break; break;
} }
const y = -(height / 2) + (i === 0 ? view.css.fontSize.toPx() : (view.css.fontSize.toPx() + i * lineHeight)); const y = -(height / 2) + (lineIndex === 0 ? view.css.fontSize.toPx() : (view.css.fontSize.toPx() + lineIndex * lineHeight));
lineIndex++;
if (view.css.textStyle === 'stroke') { if (view.css.textStyle === 'stroke') {
this.ctx.strokeText(text, x, y, measuredWith); this.ctx.strokeText(text, x, y, measuredWith);
} else { } else {
@ -425,7 +453,7 @@ export default class Painter {
this.ctx.stroke(); this.ctx.stroke();
} }
} }
}
this.ctx.restore(); this.ctx.restore();
this._doBorder(view, width, height); this._doBorder(view, width, height);
} }