diff --git a/src/common/components/mock-components/front-rich-components/tabsbar/business/tabsbar.business.ts b/src/common/components/mock-components/front-rich-components/tabsbar/business/tabsbar.business.ts index ce08f8bb..ed119ee4 100644 --- a/src/common/components/mock-components/front-rich-components/tabsbar/business/tabsbar.business.ts +++ b/src/common/components/mock-components/front-rich-components/tabsbar/business/tabsbar.business.ts @@ -1,6 +1,6 @@ import { Layer } from 'konva/lib/Layer'; import { balanceSpacePerItem } from './balance-space'; -import { calcTextWidth } from './calc-text-width'; +import { calcTextDimensions } from '@/common/utils/calc-text-dimensions'; export const adjustTabWidths = (args: { tabs: string[]; @@ -35,9 +35,14 @@ export const adjustTabWidths = (args: { } const arrangeTabsInfo = tabs.reduce( (acc: OriginalTabInfo[], tab, index): OriginalTabInfo[] => { - const tabFullTextWidth = - calcTextWidth(tab, font.fontSize, font.fontFamily, konvaLayer) + - totalInnerXPadding; + const { width: textWidth } = calcTextDimensions( + tab, + font.fontSize, + font.fontFamily, + konvaLayer + ); + + const tabFullTextWidth = textWidth + totalInnerXPadding; const desiredWidth = Math.max(totalMinTabSpace, tabFullTextWidth); return [ ...acc, diff --git a/src/common/components/mock-components/front-text-components/front-text-hooks/resize-fontsize-change.hook.ts b/src/common/components/mock-components/front-text-components/front-text-hooks/resize-fontsize-change.hook.ts new file mode 100644 index 00000000..a629b2f3 --- /dev/null +++ b/src/common/components/mock-components/front-text-components/front-text-hooks/resize-fontsize-change.hook.ts @@ -0,0 +1,63 @@ +import { calcTextDimensions } from '@/common/utils/calc-text-dimensions'; +import { useCanvasContext } from '@/core/providers'; +import { useEffect, useRef } from 'react'; + +export const useResizeOnFontSizeChange = ( + id: string, + coords: { x: number; y: number }, + text: string, + fontSize: number, + fontVariant: string, + multiline: boolean = false +) => { + const previousFontSize = useRef(fontSize); + const { updateShapeSizeAndPosition, stageRef } = useCanvasContext(); + const konvaLayer = stageRef.current?.getLayers()[0]; + + useEffect(() => { + if (previousFontSize.current !== fontSize) { + previousFontSize.current = fontSize; + + const paragraphLines = _extractParagraphLines(text); + const longestLine = _findLongestString(paragraphLines); + + const { width, height } = calcTextDimensions( + multiline ? longestLine : text, + fontSize, + fontVariant, + konvaLayer + ); + + updateShapeSizeAndPosition( + id, + coords, + { + width: width * 1.15, + height: multiline + ? _calcParagraphTotalHeight(height, 0.8, paragraphLines.length) + : height, + }, + true + ); + } + }, [fontSize]); +}; + +/* Hook Helper functions */ +function _extractParagraphLines(multilineText: string) { + return multilineText.split(/\r?\n/).filter(line => line.trim() !== ''); +} + +function _findLongestString(stringsArray: string[]): string { + return stringsArray.reduce((longest, current) => + current.length > longest.length ? current : longest + ); +} + +function _calcParagraphTotalHeight( + heightPerLine: number, + lineHeight: number = 1.3, + linesQty: number +) { + return heightPerLine * lineHeight * linesQty; +} diff --git a/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx b/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx index ed5ef8c5..1e76ba40 100644 --- a/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx +++ b/src/common/components/mock-components/front-text-components/heading1-text-shape.tsx @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest import { useShapeProps } from '../../shapes/use-shape-props.hook'; import { BASIC_SHAPE } from '../front-components/shape.const'; import { useGroupShapeProps } from '../mock-components.utils'; +import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook'; const heading1SizeRestrictions: ShapeSizeRestrictions = { minWidth: 40, @@ -56,6 +57,8 @@ export const Heading1Shape = forwardRef((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant); + return ( ((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant); + return ( ((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant); + return ( ((props, ref) => { const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, textDecoration, fontSize, textAlignment } = useShapeProps( - otherProps, - BASIC_SHAPE - ); + const { textColor, textDecoration, fontSize, textAlignment, fontVariant } = + useShapeProps(otherProps, BASIC_SHAPE); const commonGroupProps = useGroupShapeProps( props, @@ -53,6 +52,8 @@ export const LinkShape = forwardRef((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant); + return ( ((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant); + return ( ((props, ref) => { ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const { textColor, fontSize, textAlignment } = useShapeProps( + const { textColor, fontSize, textAlignment, fontVariant } = useShapeProps( otherProps, BASIC_SHAPE ); @@ -52,6 +53,8 @@ export const ParagraphShape = forwardRef((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant, true); + return ( ((props, ref) => { ref ); + useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant); + return ( { const context = konvaLayer.getContext(); context.font = `${fontSize}px ${fontfamily}`; - return context.measureText(text).width; + const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } = + context.measureText(text); + const totalHeight = fontBoundingBoxAscent + fontBoundingBoxDescent; + return { width, height: totalHeight }; }; const _getTextCreatingNewCanvas = ( @@ -43,8 +46,13 @@ const _getTextCreatingNewCanvas = ( const context = canvas.getContext('2d'); if (context) { context.font = `${fontSize}px ${fontfamily}`; - return context.measureText(text).width; + const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } = + context.measureText(text); + const height = fontBoundingBoxAscent + fontBoundingBoxDescent; + return { width, height }; } const charAverageWidth = fontSize * 0.7; - return text.length * charAverageWidth + charAverageWidth * 0.8; + const width = text.length * charAverageWidth + charAverageWidth * 0.8; + const height = fontSize * 1.5; + return { width, height }; };