| import { TextStyle, Dimension } from './types'; |
| import updateTextNode from './svg/updateTextNode'; |
| import getBBoxCeil from './svg/getBBoxCeil'; |
| import { hiddenSvgFactory, textFactory } from './svg/factories'; |
| |
| export interface GetTextDimensionInput { |
| className?: string; |
| container?: HTMLElement; |
| style?: TextStyle; |
| text: string; |
| } |
| |
| export default function getTextDimension( |
| input: GetTextDimensionInput, |
| defaultDimension?: Dimension, |
| ): Dimension { |
| const { text, className, style, container } = input; |
| |
| // Empty string |
| if (text.length === 0) { |
| return { height: 0, width: 0 }; |
| } |
| |
| const svgNode = hiddenSvgFactory.createInContainer(container); |
| const textNode = textFactory.createInContainer(svgNode); |
| updateTextNode(textNode, { className, style, text }); |
| const dimension = getBBoxCeil(textNode, defaultDimension); |
| |
| // The nodes are added to the DOM briefly only to make getBBox works. |
| // (If not added to DOM getBBox will always return 0x0.) |
| // After that the svg nodes are not needed. |
| // We delay its removal in case there are subsequent calls to this function |
| // that can reuse the svg nodes. |
| // Experiments have shown that reusing existing nodes |
| // instead of deleting and adding new ones can save lot of time. |
| setTimeout(() => { |
| textFactory.removeFromContainer(svgNode); |
| hiddenSvgFactory.removeFromContainer(container); |
| }, 500); |
| |
| return dimension; |
| } |