import React, { useRef, useEffect, useState } from "react"; import { Rect, Text, Group } from "react-konva"; import useSetting from "../../hooks/useSetting"; const maxTokenSize = 3; const defaultFontSize = 16; function TokenLabel({ tokenState, width, height }) { const [labelSize] = useSetting("map.labelSize"); const paddingY = (height / 12 / tokenState.size) * Math.min(tokenState.size, maxTokenSize); const paddingX = (height / 8 / tokenState.size) * Math.min(tokenState.size, maxTokenSize); const [fontScale, setFontScale] = useState(0); useEffect(() => { const text = textSizerRef.current; if (!text) { return; } let fontSizes = []; for (let size = 20 * labelSize; size >= 6; size--) { const verticalSize = height / size / tokenState.size; const tokenSize = Math.min(tokenState.size, maxTokenSize); const fontSize = verticalSize * tokenSize * labelSize; fontSizes.push(fontSize); } function findFontScale() { const size = fontSizes.reduce((prev, curr) => { text.fontSize(curr); const textWidth = text.getTextWidth() + paddingX * 2; if (textWidth < width) { return curr; } else { return prev; } }, 1); setFontScale(size / defaultFontSize); } findFontScale(); }, [ tokenState.label, tokenState.visible, width, height, tokenState, labelSize, paddingX, ]); const [rectWidth, setRectWidth] = useState(0); const [textWidth, setTextWidth] = useState(0); useEffect(() => { const text = textRef.current; if (text && tokenState.label) { setRectWidth(text.getTextWidth() * fontScale + paddingX * 2); setTextWidth(text.getTextWidth() * fontScale); } else { setRectWidth(0); setTextWidth(0); } }, [tokenState.label, paddingX, width, fontScale]); const textRef = useRef(); const textSizerRef = useRef(); return ( {}} /> {/* Use an invisible text block to work out text sizing */} ); } export default TokenLabel;