get-ellipsis-text.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import isString from './is-string';
  2. import toString from './to-string';
  3. import { default as measureTextWidth } from './measure-text-width';
  4. /**
  5. * 获取文本的 ... 文本。
  6. * 算法(减少每次 measureText 的长度,measureText 的性能跟字符串时间相关):
  7. * 1. 先通过 STEP 逐步计算,找到最后一个小于 maxWidth 的字符串
  8. * 2. 然后对最后这个字符串二分计算
  9. * @param text 需要计算的文本, 由于历史原因 除了支持string,还支持空值,number和数组等
  10. * @param maxWidth 最大宽度
  11. * @param font 字体
  12. * @param str 要替换的文本
  13. */
  14. export default (function (text, maxWidth, font, str) {
  15. if (str === void 0) { str = '...'; }
  16. var STEP = 16; // 每次 16,调参工程师
  17. var PLACEHOLDER_WIDTH = measureTextWidth(str, font);
  18. var leftText = !isString(text) ? toString(text) : text;
  19. var leftWidth = maxWidth;
  20. var r = []; // 最终的分段字符串
  21. var currentText;
  22. var currentWidth;
  23. if (measureTextWidth(text, font) <= maxWidth) {
  24. return text;
  25. }
  26. // 首先通过 step 计算,找出最大的未超出长度的
  27. // eslint-disable-next-line no-constant-condition
  28. while (true) {
  29. // 更新字符串
  30. currentText = leftText.substr(0, STEP);
  31. // 计算宽度
  32. currentWidth = measureTextWidth(currentText, font);
  33. // 超出剩余宽度,则停止
  34. if (currentWidth + PLACEHOLDER_WIDTH > leftWidth) {
  35. if (currentWidth > leftWidth) {
  36. break;
  37. }
  38. }
  39. r.push(currentText);
  40. // 没有超出,则计算剩余宽度
  41. leftWidth -= currentWidth;
  42. leftText = leftText.substr(STEP);
  43. // 字符串整体没有超出
  44. if (!leftText) {
  45. return r.join('');
  46. }
  47. }
  48. // 最下的最后一个 STEP,使用 1 递增(用二分效果更高)
  49. // eslint-disable-next-line no-constant-condition
  50. while (true) {
  51. // 更新字符串
  52. currentText = leftText.substr(0, 1);
  53. // 计算宽度
  54. currentWidth = measureTextWidth(currentText, font);
  55. // 超出剩余宽度,则停止
  56. if (currentWidth + PLACEHOLDER_WIDTH > leftWidth) {
  57. break;
  58. }
  59. r.push(currentText);
  60. // 没有超出,则计算剩余宽度
  61. leftWidth -= currentWidth;
  62. leftText = leftText.substr(1);
  63. if (!leftText) {
  64. return r.join('');
  65. }
  66. }
  67. return "" + r.join('') + str;
  68. });
  69. //# sourceMappingURL=get-ellipsis-text.js.map