@rxflow/base
Version:
BaseFlow - 核心 Flow 组件库
76 lines (71 loc) • 2.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isTextOverflow = isTextOverflow;
exports.measureTextWidth = measureTextWidth;
exports.truncateTextWithEllipsis = truncateTextWithEllipsis;
/*
* @author: yanxianliang
* @date: 2025-05-16 23:49
* @desc: 检测文字宽度
*
* Copyright (c) 2025 by yanxianliang, All Rights Reserved.
*/
// 离线canvas,支持在worker 中使用
const canvas = new OffscreenCanvas(2000, 200);
const context = canvas.getContext('2d');
/**
* 计算文案宽度,根据内容自动计算节点宽度
* @param text
* @param fontStyle
*/
function measureTextWidth(text, fontStyle = '14px Arial, helvetica, sans-serif') {
context.font = fontStyle; // 设置字体样式
return context.measureText(text).width;
}
/**
* 文本宽度是否超出了允许的最大宽度
* @param text
* @param maxWidth
* @param fontStyle
*/
function isTextOverflow(text, maxWidth, fontStyle) {
const textWidth = measureTextWidth(text, fontStyle);
return textWidth > maxWidth;
}
const ellipsisCalcCache = new Map();
const ellipsis = '...';
function calcEllipsisWidth(fontStyle) {
if (ellipsisCalcCache.has(fontStyle)) {
return ellipsisCalcCache.get(fontStyle);
}
const width = measureTextWidth(ellipsis, fontStyle);
ellipsisCalcCache.set(fontStyle, width);
return width;
}
/**
* 文本根据宽度计算溢出显示结果
* @param text
* @param maxWidth
* @param fontStyle
*/
function truncateTextWithEllipsis(text, maxWidth, fontStyle) {
if (!isTextOverflow(text, maxWidth, fontStyle)) {
return text;
}
const ellipsisWidth = calcEllipsisWidth(fontStyle);
const contentMaxWidth = maxWidth - ellipsisWidth;
let low = 0,
high = text.length;
while (low <= high) {
const mid = Math.floor((low + high) / 2);
const currentText = text.substring(0, mid);
if (measureTextWidth(currentText) <= contentMaxWidth) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return text.substring(0, high) + ellipsis;
}