UNPKG

3.08 kBJavaScriptView Raw
1import { __read, __spreadArray } from "tslib";
2import { isString, memoize, values, toString } from '@antv/util';
3import { getCanvasContext } from './context';
4/**
5 * 计算文本在画布中的宽度
6 */
7export var measureTextWidth = memoize(function (text, font) {
8 if (font === void 0) { font = {}; }
9 var fontSize = font.fontSize, fontFamily = font.fontFamily, fontWeight = font.fontWeight, fontStyle = font.fontStyle, fontVariant = font.fontVariant;
10 var ctx = getCanvasContext();
11 ctx.font = [fontStyle, fontVariant, fontWeight, "".concat(fontSize, "px"), fontFamily].join(' ');
12 return ctx.measureText(isString(text) ? text : '').width;
13}, function (text, font) {
14 if (font === void 0) { font = {}; }
15 return __spreadArray([text], __read(values(font)), false).join('');
16});
17/**
18 * 获取文本的 ... 文本。
19 * 算法(减少每次 measureText 的长度,measureText 的性能跟字符串时间相关):
20 * 1. 先通过 STEP 逐步计算,找到最后一个小于 maxWidth 的字符串
21 * 2. 然后对最后这个字符串二分计算
22 * @param text 需要计算的文本, 由于历史原因 除了支持string,还支持空值,number和数组等
23 * @param maxWidth
24 * @param font
25 */
26export var getEllipsisText = function (text, maxWidth, font) {
27 var STEP = 16; // 每次 16,调参工程师
28 var DOT_WIDTH = measureTextWidth('...', font);
29 var leftText;
30 if (!isString(text)) {
31 leftText = toString(text);
32 }
33 else {
34 leftText = text;
35 }
36 var leftWidth = maxWidth;
37 var r = []; // 最终的分段字符串
38 var currentText;
39 var currentWidth;
40 if (measureTextWidth(text, font) <= maxWidth) {
41 return text;
42 }
43 // 首先通过 step 计算,找出最大的未超出长度的
44 while (true) {
45 // 更新字符串
46 currentText = leftText.substr(0, STEP);
47 // 计算宽度
48 currentWidth = measureTextWidth(currentText, font);
49 // 超出剩余宽度,则停止
50 if (currentWidth + DOT_WIDTH > leftWidth) {
51 if (currentWidth > leftWidth) {
52 break;
53 }
54 }
55 r.push(currentText);
56 // 没有超出,则计算剩余宽度
57 leftWidth -= currentWidth;
58 leftText = leftText.substr(STEP);
59 // 字符串整体没有超出
60 if (!leftText) {
61 return r.join('');
62 }
63 }
64 // 最下的最后一个 STEP,使用 1 递增(用二分效果更高)
65 while (true) {
66 // 更新字符串
67 currentText = leftText.substr(0, 1);
68 // 计算宽度
69 currentWidth = measureTextWidth(currentText, font);
70 // 超出剩余宽度,则停止
71 if (currentWidth + DOT_WIDTH > leftWidth) {
72 break;
73 }
74 r.push(currentText);
75 // 没有超出,则计算剩余宽度
76 leftWidth -= currentWidth;
77 leftText = leftText.substr(1);
78 if (!leftText) {
79 return r.join('');
80 }
81 }
82 return "".concat(r.join(''), "...");
83};
84//# sourceMappingURL=text.js.map
\No newline at end of file