UNPKG

@visactor/vrender-core

Version:
135 lines (127 loc) 6.95 kB
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