@visactor/vrender-core
Version:
```typescript import { xxx } from '@visactor/vrender-core'; ```
334 lines (320 loc) • 18.7 kB
JavaScript
"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, textBaseline: textBaseline = (null !== (_b = null !== (_a = attribute.textBaseline) && void 0 !== _a ? _a : richtextTheme.textBaseline) && void 0 !== _b ? _b : "top"), 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 (textBaseline) {
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 height || ("middle" === this.verticalDirection ? deltaY -= aabbBounds.height() / 2 : "bottom" === this.verticalDirection && (deltaY -= aabbBounds.height())),
aabbBounds.translate(deltaX, deltaY), application_1.application.graphicService.updateTempAABBBounds(aabbBounds),
null == attribute.forceBoundsHeight && null == attribute.forceBoundsWidth || application_1.application.graphicService.updateHTMLTextAABBBounds(attribute, richtextTheme, aabbBounds),
this.widthWithoutTransform = aabbBounds.x2 - aabbBounds.x1, this.heightWithoutTransform = aabbBounds.y2 - aabbBounds.y1,
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