import { useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { fontSelector } from '@/store/fontAtom' import { useCallback, useEffect } from 'react' /** 폰트 타입별 캔버스 오브젝트 이름 매핑 */ const FONT_TYPE_TO_OBJ_NAME = { commonText: 'commonText', dimensionLineText: 'dimensionLineText', flowText: 'flowText', lengthText: 'lengthText', circuitNumberText: 'circuitNumber', } /** 캔버스 오브젝트 이름 → 폰트 타입 역매핑 */ const OBJ_NAME_TO_FONT_TYPE = Object.fromEntries(Object.entries(FONT_TYPE_TO_OBJ_NAME).map(([k, v]) => [v, k])) export function useFont() { const canvas = useRecoilValue(canvasState) const commonText = useRecoilValue(fontSelector('commonText')) const dimensionLineText = useRecoilValue(fontSelector('dimensionLineText')) const flowText = useRecoilValue(fontSelector('flowText')) const lengthText = useRecoilValue(fontSelector('lengthText')) const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText')) /** 폰트 타입별 설정 매핑 */ const fontSettings = { commonText, dimensionLineText, flowText, lengthText, circuitNumberText, } /** * 타입별 폰트 설정을 캔버스 오브젝트에 적용하는 공통 함수 * @param {string} type - 폰트 타입 (commonText, dimensionLineText, flowText, lengthText, circuitNumberText) * @param {number} delay - 적용 지연 시간 (ms), 기본값 200 */ const changeFontByType = useCallback( (type, delay = 200) => { const fontSetting = fontSettings[type] const objName = FONT_TYPE_TO_OBJ_NAME[type] if (!fontSetting || !objName) { console.warn(`Invalid font type: ${type}`) return } setTimeout(() => { if (canvas && fontSetting.fontWeight?.value) { const textObjs = canvas.getObjects().filter((obj) => obj.name === objName) textObjs.forEach((obj) => { obj.set({ fontFamily: fontSetting.fontFamily.value, fontWeight: fontSetting.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', fontStyle: fontSetting.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontSize: fontSetting.fontSize.value, fill: fontSetting.fontColor.value, }) }) canvas.renderAll() } }, delay) }, [canvas, fontSettings], ) const changeAllFonts = () => { changeFontByType('commonText') changeFontByType('dimensionLineText') changeFontByType('flowText') changeFontByType('lengthText') changeFontByType('circuitNumberText') } /** 각 폰트 타입별 useEffect */ useEffect(() => { changeFontByType('commonText') }, [commonText]) useEffect(() => { changeFontByType('dimensionLineText') }, [dimensionLineText]) useEffect(() => { changeFontByType('flowText') }, [flowText]) useEffect(() => { changeFontByType('lengthText') }, [lengthText]) useEffect(() => { changeFontByType('circuitNumberText') }, [circuitNumberText]) /** 캔버스에 텍스트 오브젝트 추가 시 자동으로 폰트 적용 */ useEffect(() => { if (!canvas) return const handleObjectAdded = (e) => { const obj = e.target if (!obj?.name) return const fontType = OBJ_NAME_TO_FONT_TYPE[obj.name] if (fontType) { changeFontByType(fontType, 0) } } canvas.on('object:added', handleObjectAdded) return () => { canvas.off('object:added', handleObjectAdded) } }, [canvas, changeFontByType]) return { changeFontByType, changeAllFonts } }