Escribí una función simple para medir textos antes de decidir qué tamaño de fuente debo usar.
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); svg.appendChild(text); interface HeightAndWidth { width: number; height: number; } interface MeasureProps { label: string; fontFamily: string; size: number; fontWeight?: number; lineHeight?: number; letterSpacing?: string; } export const measureText = ({ label, fontFamily, size, fontWeight = 400, lineHeight = 1, letterSpacing = '0', }: MeasureProps): HeightAndWidth => { text.setAttribute('font-size', `${size}px`); text.setAttribute('line-height', `${lineHeight}px`); text.setAttribute('font-family', fontFamily); text.setAttribute('font-weight', `${fontWeight}`); text.setAttribute('letter-spacing', letterSpacing); text.textContent = label; document.body.appendChild(svg); const { width, height } = text.getBBox(); return { width, height, }; };Es bastante sencillo y funciona bien, pero tengo problemas para escribir pruebas unitarias para esto. El problema es que mientras trabaja en el navegador, no funciona durante las pruebas y arroja un error.
text.getBBox no es una función.
Intenté burlarme de window.SVGTextElement pero sigue arrojando un error de que a su prototipo le faltan 241 propiedades más. Incluso probé su tipo, pero el error permanece, y el error con la falta de repeticiones de getBBox .
¿Hay alguna manera de probar un código como este?
import { measureText } from '../measure'; interface MockSvgTextElement { prototype: { getBBox: () => { height: number; width: number }; }; } describe('animateNumber', () => { beforeEach(() => { window.SVGTextElement = { prototype: { getBBox: () => ({ height: 20, width: 100, }), }, } as MockSvgTextElement; const p = document.createElement('p'); document.body.appendChild(p); console.log('window.SVGTextElement', window.SVGTextElement); }); it('should measure text', () => { const textSize = measureText( { label: '12345', fontFamily: 'Roboto', size: 20, } ); expect(textSize).toEqual({}); }); });getBBox se puede usar para el tipo SVGGraphicsElement .
Cree un elemento <svg> debajo body y luego agregue un <text> debajo de svg .
Luego puede llamar a getBBox().width para el elemento de text