UNPKG

@visactor/vrender-core

Version:
332 lines (318 loc) 18.5 kB
"use strict"; var __importDefault = this && this.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { default: mod }; }; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.createRichText = exports.RichText = void 0; const vutils_1 = require("@visactor/vutils"), graphic_1 = require("./graphic"), config_1 = require("./config"), frame_1 = __importDefault(require("./richtext/frame")), paragraph_1 = __importDefault(require("./richtext/paragraph")), wrapper_1 = __importDefault(require("./richtext/wrapper")), theme_1 = require("./theme"), icon_1 = require("./richtext/icon"), application_1 = require("../application"), constants_1 = require("./constants"); let supportIntl = !1; try { supportIntl = Intl && "function" == typeof Intl.Segmenter; } catch (e) { supportIntl = !1; } const RICHTEXT_UPDATE_TAG_KEY = [ "width", "height", "ellipsis", "wordBreak", "verticalDirection", "maxHeight", "maxWidth", "textAlign", "textBaseline", "textConfig", "layoutDirection", "fill", "stroke", "fontSize", "fontFamily", "fontStyle", "fontWeight", "lineWidth", "opacity", "fillOpacity", "strokeOpacity", ...graphic_1.GRAPHIC_UPDATE_TAG_KEY ]; class RichText extends graphic_1.Graphic { constructor(params) { super(params), this.type = "richtext", this._currentHoverIcon = null, this.numberType = constants_1.RICHTEXT_NUMBER_TYPE, this.onBeforeAttributeUpdate = (val, attributes, key) => { for (const key in val) if ("hoverIconId" === key) { if (val[key] === attributes[key]) continue; const icon = this._frameCache.icons.get(val[key]); this.updateHoverIconState(icon); } }; } get width() { var _a; return null !== (_a = this.attribute.width) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.width; } set width(w) { this.attribute.width !== w && (this.attribute.width = w, this.addUpdateShapeAndBoundsTag()); } get height() { var _a; return null !== (_a = this.attribute.height) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.height; } set height(h) { this.attribute.height !== h && (this.attribute.height = h, this.addUpdateShapeAndBoundsTag()); } get maxWidth() { return this.attribute.maxWidth; } set maxWidth(mw) { this.attribute.maxWidth !== mw && (this.attribute.maxWidth = mw, this.addUpdateShapeAndBoundsTag()); } get maxHeight() { return this.attribute.maxHeight; } set maxHeight(mh) { this.attribute.maxHeight !== mh && (this.attribute.maxHeight = mh, this.addUpdateShapeAndBoundsTag()); } get ellipsis() { var _a; return null !== (_a = this.attribute.ellipsis) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.ellipsis; } set ellipsis(e) { this.attribute.ellipsis !== e && (this.attribute.ellipsis = e, this.addUpdateShapeAndBoundsTag()); } get wordBreak() { var _a; return null !== (_a = this.attribute.wordBreak) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.wordBreak; } set wordBreak(wb) { this.attribute.wordBreak !== wb && (this.attribute.wordBreak = wb, this.addUpdateShapeAndBoundsTag()); } get verticalDirection() { var _a; return null !== (_a = this.attribute.verticalDirection) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.verticalDirection; } set verticalDirection(vd) { this.attribute.verticalDirection !== vd && (this.attribute.verticalDirection = vd, this.addUpdateShapeAndBoundsTag()); } get textAlign() { var _a; return null !== (_a = this.attribute.textAlign) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.textAlign; } set textAlign(align) { this.attribute.textAlign !== align && (this.attribute.textAlign = align, this.addUpdateShapeAndBoundsTag()); } get textBaseline() { var _a; return null !== (_a = this.attribute.textBaseline) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.textBaseline; } set textBaseline(baseline) { this.attribute.textBaseline !== baseline && (this.attribute.textBaseline = baseline, this.addUpdateShapeAndBoundsTag()); } get textConfig() { var _a; return null !== (_a = this.attribute.textConfig) && void 0 !== _a ? _a : config_1.DefaultRichTextAttribute.textConfig; } set textConfig(config) { this.attribute.textConfig = config, this.addUpdateShapeAndBoundsTag(); } getGraphicTheme() { return (0, theme_1.getTheme)(this).richtext; } static AllSingleCharacter(cache) { if (cache.lines) { return cache.lines.every((line => line.paragraphs.every((item => !(item.text && (0, vutils_1.isString)(item.text) && RichText.splitText(item.text).length > 1))))); } return cache.every((item => item.isComposing || !(item.text && (0, vutils_1.isString)(item.text) && RichText.splitText(item.text).length > 1))); } static splitText(text) { if (supportIntl) { const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" }), segments = []; for (const {segment: segment} of segmenter.segment(text)) segments.push(segment); return segments; } return Array.from(text); } static TransformTextConfig2SingleCharacter(textConfig) { const tc = []; return textConfig.forEach((item => { const textList = RichText.splitText(item.text.toString()); if ((0, vutils_1.isString)(item.text) && textList.length > 1) for (let i = 0; i < textList.length; i++) { const t = textList[i]; tc.push(Object.assign(Object.assign({}, item), { text: t })); } else tc.push(item); })), tc; } updateAABBBounds(attribute, richtextTheme, aabbBounds) { var _a, _b, _c, _d; const {width: width = richtextTheme.width, height: height = richtextTheme.height, maxWidth: maxWidth = richtextTheme.maxWidth, maxHeight: maxHeight = richtextTheme.maxHeight, textAlign: textAlign = richtextTheme.textAlign, verticalDirection: verticalDirection = (null !== (_b = null !== (_a = attribute.textBaseline) && void 0 !== _a ? _a : richtextTheme.textBaseline) && void 0 !== _b ? _b : richtextTheme.verticalDirection), editOptions: editOptions} = attribute; if (width > 0 && height > 0) aabbBounds.set(0, 0, width, height); else { const frameCache = this.getFrameCache(), {width: actualWidth, height: actualHeight} = frameCache.getActualSize(); let contentWidth = width || actualWidth || 0, contentHeight = height || actualHeight || 0; contentHeight = "number" == typeof maxHeight && contentHeight > maxHeight ? maxHeight : contentHeight || 0, contentWidth = "number" == typeof maxWidth && contentWidth > maxWidth ? maxWidth : contentWidth || 0, aabbBounds.set(0, 0, contentWidth, contentHeight); } editOptions && editOptions.keepHeightWhileEmpty && !aabbBounds.height() && !(null === (_c = attribute.textConfig) || void 0 === _c ? void 0 : _c.length) && (aabbBounds.y2 = aabbBounds.y1 + (null !== (_d = attribute.fontSize) && void 0 !== _d ? _d : 12), aabbBounds.x2 = aabbBounds.x1 + 2); let deltaY = 0; switch (verticalDirection) { case "top": deltaY = 0; break; case "middle": deltaY = -aabbBounds.height() / 2; break; case "bottom": deltaY = -aabbBounds.height(); } let deltaX = 0; switch (textAlign) { case "left": deltaX = 0; break; case "center": deltaX = -aabbBounds.width() / 2; break; case "right": deltaX = -aabbBounds.width(); } return aabbBounds.translate(deltaX, deltaY), application_1.application.graphicService.updateTempAABBBounds(aabbBounds), null == attribute.forceBoundsHeight && null == attribute.forceBoundsWidth || application_1.application.graphicService.updateHTMLTextAABBBounds(attribute, richtextTheme, aabbBounds), application_1.application.graphicService.transformAABBBounds(attribute, aabbBounds, richtextTheme, !1, this), 0 === aabbBounds.width() && 0 === aabbBounds.height() && aabbBounds.clear(), aabbBounds; } needUpdateTags(keys) { return super.needUpdateTags(keys, RICHTEXT_UPDATE_TAG_KEY); } needUpdateTag(key) { return super.needUpdateTag(key, RICHTEXT_UPDATE_TAG_KEY); } getFrameCache() { return this.shouldUpdateShape() && (this.doUpdateFrameCache(), this.clearUpdateShapeTag()), this._frameCache; } get cliped() { const frameCache = this.getFrameCache(); if (frameCache.actualHeight > frameCache.height) return !0; const {disableAutoWrapLine: disableAutoWrapLine} = this.attribute; if (disableAutoWrapLine) for (let i = 0; i < frameCache.lines.length; i++) { const l = frameCache.lines[i]; for (let j = 0; j < l.paragraphs.length; j++) { const p = l.paragraphs[j]; if (p.overflow && "" !== p.text) return !0; } } return !1; } combinedStyleToCharacter(config) { const {fill: fill, stroke: stroke, fontSize: fontSize, fontFamily: fontFamily, fontStyle: fontStyle, fontWeight: fontWeight, lineWidth: lineWidth, opacity: opacity, fillOpacity: fillOpacity, lineHeight: lineHeight, strokeOpacity: strokeOpacity, upgradeAttrs: upgradeAttrs} = this.attribute, out = Object.assign({ fill: fill, stroke: stroke, fontSize: fontSize, fontFamily: fontFamily, fontStyle: fontStyle, fontWeight: fontWeight, lineWidth: lineWidth, opacity: opacity, fillOpacity: fillOpacity, strokeOpacity: strokeOpacity }, config); return (null == upgradeAttrs ? void 0 : upgradeAttrs.lineHeight) && (out.lineHeight = lineHeight), out; } doUpdateFrameCache(tc) { var _a; const {maxWidth: maxWidth, maxHeight: maxHeight, width: width, height: height, ellipsis: ellipsis, wordBreak: wordBreak, verticalDirection: verticalDirection, textAlign: textAlign, textBaseline: textBaseline, layoutDirection: layoutDirection, singleLine: singleLine, disableAutoWrapLine: disableAutoWrapLine, editable: editable, ascentDescentMode: ascentDescentMode, upgradeAttrs: upgradeAttrs} = this.attribute, enableMultiBreakLine = upgradeAttrs && upgradeAttrs.multiBreakLine; let {textConfig: _tc = []} = this.attribute; editable && _tc.length > 0 && !RichText.AllSingleCharacter(_tc) && (_tc = RichText.TransformTextConfig2SingleCharacter(_tc), this.attribute.textConfig = _tc); const paragraphs = [], textConfig = null != tc ? tc : _tc; for (let i = 0; i < textConfig.length; i++) if ("image" in textConfig[i]) { const config = this.combinedStyleToCharacter(textConfig[i]); config.lineWidth = void 0; const iconCache = config.id && this._frameCache && this._frameCache.icons && this._frameCache.icons.get(config.id); if (iconCache) paragraphs.push(iconCache); else { const icon = new icon_1.RichTextIcon(config); icon.successCallback = () => { var _a; this.addUpdateBoundTag(), null === (_a = this.stage) || void 0 === _a || _a.renderNextFrame(); }, icon.richtextId = config.id, paragraphs.push(icon); } } else { const richTextConfig = this.combinedStyleToCharacter(textConfig[i]); if ((0, vutils_1.isNumber)(richTextConfig.text) && (richTextConfig.text = `${richTextConfig.text}`), richTextConfig.text && richTextConfig.text.includes("\n")) { const textParts = richTextConfig.text.split("\n"); for (let j = 0; j < textParts.length; j++) if (0 === j) paragraphs.push(new paragraph_1.default(textParts[j], !1, richTextConfig, ascentDescentMode)); else if (textParts[j] || i === textConfig.length - 1) paragraphs.push(new paragraph_1.default(textParts[j], !0, richTextConfig, ascentDescentMode)); else { const nextRichTextConfig = this.combinedStyleToCharacter(textConfig[i + 1]); paragraphs.push(new paragraph_1.default(textParts[j], !0, nextRichTextConfig, ascentDescentMode)); } } else richTextConfig.text && paragraphs.push(new paragraph_1.default(richTextConfig.text, !1, richTextConfig, ascentDescentMode)); } const maxWidthFinite = "number" == typeof maxWidth && Number.isFinite(maxWidth) && maxWidth > 0, maxHeightFinite = "number" == typeof maxHeight && Number.isFinite(maxHeight) && maxHeight > 0, richTextWidthEnable = "number" == typeof width && Number.isFinite(width) && width > 0 && (!maxWidthFinite || width <= maxWidth), richTextHeightEnable = "number" == typeof height && Number.isFinite(height) && height > 0 && (!maxHeightFinite || height <= maxHeight), frameWidth = richTextWidthEnable ? width : maxWidthFinite ? maxWidth : 0, frameHeight = richTextHeightEnable ? height : maxHeightFinite ? maxHeight : 0, frame = new frame_1.default(0, 0, frameWidth || 0, frameHeight || 0, ellipsis, wordBreak, verticalDirection, textAlign, textBaseline, layoutDirection || "horizontal", !richTextWidthEnable && maxWidthFinite, !richTextHeightEnable && maxHeightFinite, singleLine || !1, null === (_a = this._frameCache) || void 0 === _a ? void 0 : _a.icons), wrapper = new wrapper_1.default(frame); if (wrapper.newLine = enableMultiBreakLine, disableAutoWrapLine) { let lineCount = 0, skip = !1; for (let i = 0; i < paragraphs.length; i++) { const p = paragraphs[i]; skip ? (p.overflow = !0, p.left = 1 / 0, p.top = 1 / 0, !p.newLine && frame.lines[frame.lines.length - 1].paragraphs.push(p)) : wrapper.deal(p, !0), frame.lines.length !== lineCount && (lineCount = frame.lines.length, wrapper.lineBuffer.length = 0, p.overflow = !0, p.left = 1e3, p.top = 1e3, frame.lines[frame.lines.length - 1].paragraphs.push(p), skip = !0), p.newLine && (skip = !1, wrapper.lineWidth = 0), wrapper.send(); } } else for (let i = 0; i < paragraphs.length; i++) wrapper.deal(paragraphs[i]); wrapper.send(); if (!("horizontal" === frame.layoutDirection ? richTextWidthEnable : richTextHeightEnable)) { const frameSize = frame.getActualSizeWidthEllipsis(); let offsetSize = "horizontal" === frame.layoutDirection ? frameSize.width : frameSize.height; ("horizontal" === frame.layoutDirection ? maxWidthFinite : maxHeightFinite) && (offsetSize = Math.min(offsetSize, "horizontal" === frame.layoutDirection ? maxWidth : maxHeight)), frame.lines.forEach((function(l) { l.calcOffset(offsetSize, !1); })); } enableMultiBreakLine && frame.lines.forEach((item => { const lastParagraphs = item.paragraphs; item.paragraphs = item.paragraphs.filter((p => "" !== p.text)), 0 === item.paragraphs.length && lastParagraphs.length && (lastParagraphs[0].text = "\n", item.paragraphs.push(lastParagraphs[0])); })), this._frameCache = frame; } clone() { return new RichText(Object.assign({}, this.attribute)); } setStage(stage, layer) { super.setStage(stage, layer); this.getFrameCache().icons.forEach((icon => { icon.setStage(stage, layer); })); } bindIconEvent() { this.addEventListener("pointermove", (e => { const pickedIcon = this.pickIcon(e.global); pickedIcon && pickedIcon === this._currentHoverIcon || (pickedIcon ? this.setAttribute("hoverIconId", pickedIcon.richtextId) : !pickedIcon && this._currentHoverIcon && this.setAttribute("hoverIconId", void 0)); })), this.addEventListener("pointerleave", (e => { this._currentHoverIcon && this.setAttribute("hoverIconId", void 0); })); } updateHoverIconState(pickedIcon) { var _a, _b, _c, _d, _e; pickedIcon ? (null === (_a = this._currentHoverIcon) || void 0 === _a || _a.setHoverState(!1), this._currentHoverIcon = pickedIcon, this._currentHoverIcon.setHoverState(!0), null === (_b = this.stage) || void 0 === _b || _b.setCursor(pickedIcon.attribute.cursor), null === (_c = this.stage) || void 0 === _c || _c.renderNextFrame()) : (this._currentHoverIcon.setHoverState(!1), this._currentHoverIcon = null, null === (_d = this.stage) || void 0 === _d || _d.setCursor(), null === (_e = this.stage) || void 0 === _e || _e.renderNextFrame()); } pickIcon(point) { const frameCache = this.getFrameCache(), {e: x, f: y} = this.globalTransMatrix; let pickIcon; return frameCache.icons.forEach(((icon, key) => { var _a, _b; const bounds = icon.AABBBounds.clone(); bounds.translate(icon._marginArray[3], icon._marginArray[0]), bounds.containsPoint({ x: point.x - x, y: point.y - y }) && (pickIcon = icon, pickIcon.globalX = (null !== (_a = pickIcon.attribute.x) && void 0 !== _a ? _a : 0) + x + icon._marginArray[3], pickIcon.globalY = (null !== (_b = pickIcon.attribute.y) && void 0 !== _b ? _b : 0) + y + icon._marginArray[0]); })), pickIcon; } getNoWorkAnimateAttr() { return RichText.NOWORK_ANIMATE_ATTR; } } function createRichText(attributes) { return new RichText(attributes); } exports.RichText = RichText, RichText.NOWORK_ANIMATE_ATTR = Object.assign({ ellipsis: 1, wordBreak: 1, verticalDirection: 1, textAlign: 1, textBaseline: 1, textConfig: 1, layoutDirection: 1 }, graphic_1.NOWORK_ANIMATE_ATTR), exports.createRichText = createRichText; //# sourceMappingURL=richtext.js.map