@visactor/vrender-core
Version:
## Description
135 lines (127 loc) • 6.95 kB
JavaScript
import { isArray } from "@visactor/vutils";
import { CanvasTextLayout } from "../core/contributions/textMeasure/layout";
import { application } from "../application";
import { Text } from "./text";
import { calculateLineHeight } from "../common/utils";
const WRAP_TEXT_UPDATE_TAG_KEY = [ "heightLimit", "lineClamp" ];
export class WrapText extends Text {
constructor(params) {
super(Object.assign(Object.assign({}, params), {
wrap: !0
}));
}
_isValid() {
const {text: text} = this.attribute;
return isArray(text) ? !text.every((t => null == t || "" === t)) : null != text && "" !== text;
}
updateMultilineAABBBounds(text) {
var _a, _b, _c, _d;
const textTheme = this.getGraphicTheme(), {fontFamily: fontFamily = textTheme.fontFamily, textAlign: textAlign = textTheme.textAlign, textBaseline: textBaseline = textTheme.textBaseline, fontSize: fontSize = textTheme.fontSize, ellipsis: ellipsis = textTheme.ellipsis, maxLineWidth: maxLineWidth, stroke: stroke = textTheme.stroke, lineWidth: lineWidth = textTheme.lineWidth, wordBreak: wordBreak = textTheme.wordBreak, fontWeight: fontWeight = textTheme.fontWeight, ignoreBuf: ignoreBuf = textTheme.ignoreBuf, heightLimit: heightLimit = 0, suffixPosition: suffixPosition = textTheme.suffixPosition, lineClamp: lineClamp} = this.attribute, lineHeight = null !== (_a = calculateLineHeight(this.attribute.lineHeight, this.attribute.fontSize || textTheme.fontSize)) && void 0 !== _a ? _a : this.attribute.fontSize || textTheme.fontSize, buf = ignoreBuf ? 0 : 2;
if (!this.shouldUpdateShape() && (null === (_b = this.cache) || void 0 === _b ? void 0 : _b.layoutData)) {
const bbox = this.cache.layoutData.bbox;
return this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height),
stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
}
const textMeasure = application.graphicUtil.textMeasure, layoutObj = new CanvasTextLayout(fontFamily, {
fontSize: fontSize,
fontWeight: fontWeight,
fontFamily: fontFamily
}, textMeasure), lines = text.map((l => l.toString())), linesLayout = [], bboxWH = [ 0, 0 ];
let lineCountLimit = 1 / 0;
if (heightLimit > 0 && (lineCountLimit = Math.max(Math.floor(heightLimit / lineHeight), 1)),
lineClamp && (lineCountLimit = Math.min(lineCountLimit, lineClamp)), "number" == typeof maxLineWidth && maxLineWidth !== 1 / 0) {
if (maxLineWidth > 0) for (let i = 0; i < lines.length; i++) {
const str = lines[i];
let needCut = !0;
if (i === lineCountLimit - 1) {
const clip = layoutObj.textMeasure.clipTextWithSuffix(str, layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
linesLayout.push({
str: clip.str,
width: clip.width,
ascent: 0,
descent: 0,
keepCenterInLine: !1
});
break;
}
const clip = layoutObj.textMeasure.clipText(str, layoutObj.textOptions, maxLineWidth, "break-word" === wordBreak);
if ("" !== str && "" === clip.str) {
if (ellipsis) {
const clipEllipsis = layoutObj.textMeasure.clipTextWithSuffix(str, layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
clip.str = null !== (_c = clipEllipsis.str) && void 0 !== _c ? _c : "", clip.width = null !== (_d = clipEllipsis.width) && void 0 !== _d ? _d : 0;
} else clip.str = "", clip.width = 0;
needCut = !1;
}
if (linesLayout.push({
str: clip.str,
width: clip.width,
ascent: 0,
descent: 0,
keepCenterInLine: !1
}), clip.str.length === str.length) ; else if (needCut) {
const newStr = str.substring(clip.str.length);
lines.splice(i + 1, 0, newStr);
}
}
let maxWidth = 0;
linesLayout.forEach((layout => {
maxWidth = Math.max(maxWidth, layout.width);
})), bboxWH[0] = maxWidth;
} else {
let width, text, lineWidth = 0;
for (let i = 0, len = lines.length; i < len; i++) {
if (i === lineCountLimit - 1) {
const clip = layoutObj.textMeasure.clipTextWithSuffix(lines[i], layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
linesLayout.push({
str: clip.str,
width: clip.width,
ascent: 0,
descent: 0,
keepCenterInLine: !1
}), lineWidth = Math.max(lineWidth, clip.width);
break;
}
text = lines[i], width = layoutObj.textMeasure.measureTextWidth(text, layoutObj.textOptions, "break-word" === wordBreak),
lineWidth = Math.max(lineWidth, width), linesLayout.push({
str: text,
width: width,
ascent: 0,
descent: 0,
keepCenterInLine: !1
});
}
bboxWH[0] = lineWidth;
}
bboxWH[1] = linesLayout.length * (lineHeight + buf);
const bbox = {
xOffset: 0,
yOffset: 0,
width: bboxWH[0],
height: bboxWH[1]
};
layoutObj.LayoutBBox(bbox, textAlign, textBaseline);
const layoutData = layoutObj.layoutWithBBox(bbox, linesLayout, textAlign, textBaseline, lineHeight);
return this.cache.layoutData = layoutData, this.clearUpdateShapeTag(), this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height),
stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
}
needUpdateTags(keys) {
for (let i = 0; i < WRAP_TEXT_UPDATE_TAG_KEY.length; i++) {
const attrKey = WRAP_TEXT_UPDATE_TAG_KEY[i];
if (-1 !== keys.indexOf(attrKey)) return !0;
}
return super.needUpdateTags(keys);
}
needUpdateTag(key) {
for (let i = 0; i < WRAP_TEXT_UPDATE_TAG_KEY.length; i++) {
if (key === WRAP_TEXT_UPDATE_TAG_KEY[i]) return !0;
}
return super.needUpdateTag(key);
}
getNoWorkAnimateAttr() {
return WrapText.NOWORK_ANIMATE_ATTR;
}
}
export function createWrapText(attributes) {
return new WrapText(attributes);
}
//# sourceMappingURL=wrap-text.js.map