From 6c15375a53f27bd22ad8f0a85370691c8f193c03 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 15 Oct 2024 15:35:00 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20->=20=EC=98=A4?= =?UTF-8?q?=EB=B8=8C=EC=A0=9D=ED=8A=B8=20=EB=B0=B0=EC=B9=98=20->=20?= =?UTF-8?q?=EA=B0=9C=EA=B5=AC,=EA=B7=B8=EB=A6=BC=EC=9E=90=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 4 + src/components/floor-plan/MenuDepth01.jsx | 10 +- .../floor-plan/modal/basic/BasicSetting.jsx | 2 +- .../floor-plan/modal/object/ObjectSetting.jsx | 128 +---------- .../modal/object/type/OpenSpace.jsx | 46 +++- .../floor-plan/modal/object/type/Shadow.jsx | 47 +++- src/hooks/object/useObjectBatch.js | 206 +++++++++++++++++- src/hooks/surface/useSurfaceShapeBatch.js | 34 ++- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 10 files changed, 333 insertions(+), 148 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index 9aa7f9f0..09f742f2 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -96,6 +96,10 @@ export const BATCH_TYPE = { OPENING_TEMP: 'openingTemp', SHADOW: 'shadow', SHADOW_TEMP: 'shadowTemp', + TRIANGLE_DORMER: 'triangleDormer', + TRIANGLE_DORMER_TEMP: 'triangleDormerTemp', + PENTAGON_DORMER: 'pentagonDormer', + PENTAGON_DORMER_TEMP: 'pentagonDormerTemp', } // 오브젝트 배치 > 프리입력, 치수입력 export const INPUT_TYPE = { diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index 21631434..8fcb9599 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -5,7 +5,7 @@ import { useEffect, useState } from 'react' import { MENU } from '@/common/common' import { currentMenuState } from '@/store/canvasAtom' import { useSetRecoilState } from 'recoil' - +import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' export default function MenuDepth01(props) { const { setShowOutlineModal, @@ -28,6 +28,9 @@ export default function MenuDepth01(props) { const { getMessage } = useMessage() const [activeMenu, setActiveMenu] = useState() const setCurrentMenu = useSetRecoilState(currentMenuState) + + const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch() + const onClickMenu = ({ id, menu, name }) => { setActiveMenu(menu) setShowOutlineModal(menu === MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) @@ -60,6 +63,11 @@ export default function MenuDepth01(props) { setShowPlaceShapeDrawingModal(id === 1) setShowPlacementSurfaceSettingModal(id === 2) setShowObjectSettingModal(id === 3) + + //배치면 전체 삭제 + if (id === 4) { + deleteAllSurfacesAndObjects() + } } if (type === 'module') { diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index c6663cba..de2c28eb 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -1,5 +1,5 @@ import { useMessage } from '@/hooks/useMessage' -import WithDraggable from '@/components/common/draggable/withDraggable' +import WithDraggable from '@/components/common/draggable/WithDraggable' import { useState } from 'react' import Orientation from '@/components/floor-plan/modal/basic/step/Orientation' import Module from '@/components/floor-plan/modal/basic/step/Module' diff --git a/src/components/floor-plan/modal/object/ObjectSetting.jsx b/src/components/floor-plan/modal/object/ObjectSetting.jsx index de7e36c3..07a21f0c 100644 --- a/src/components/floor-plan/modal/object/ObjectSetting.jsx +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -3,12 +3,10 @@ import { useState, useRef } from 'react' import { useRecoilValue } from 'recoil' import { useMessage } from '@/hooks/useMessage' -import { INPUT_TYPE, BATCH_TYPE } from '@/common/common' import { useEvent } from '@/hooks/useEvent' import { canvasState } from '@/store/canvasAtom' import { useSwal } from '@/hooks/useSwal' -import { polygonToTurfPolygon, rectToPolygon, pointsToTurfPolygon } from '@/util/canvas-util' -import * as turf from '@turf/turf' +import { useObjectBatch } from '@/hooks/object/useObjectBatch' import WithDraggable from '@/components/common/draggable/WithDraggable' import OpenSpace from '@/components/floor-plan/modal/object/type/OpenSpace' @@ -20,9 +18,8 @@ export default function ObjectSetting({ setShowObjectSettingModal }) { const { getMessage } = useMessage() const canvas = useRecoilValue(canvasState) const [buttonAct, setButtonAct] = useState(1) - const [preObjects, setPreObjects] = useState([]) - const { addCanvasMouseEventListener, initEvent } = useEvent() const { swalFire } = useSwal() + const { applyOpeningAndShadow } = useObjectBatch() /** * 개구배치, 그림자배치 @@ -35,13 +32,8 @@ export default function ObjectSetting({ setShowObjectSettingModal }) { } const applyObject = () => { - setShowObjectSettingModal(false) - - let preObjectsArray = preObjects const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === 'surfaceShapeBatch') - console.log(preObjectsArray) - if (surfaceShapePolygons.length === 0) { swalFire({ text: '지붕이 없어요 지붕부터 그리세요', icon: 'error' }) return @@ -49,121 +41,7 @@ export default function ObjectSetting({ setShowObjectSettingModal }) { //개구배치, 그림자배치 if (buttonAct === 1 || buttonAct === 2) { - const type = objectPlacement.typeRef.current.find((radio) => radio.checked).value - const isCrossChecked = objectPlacement.isCrossRef.current.checked - - let rect, isDown, origX, origY - let selectedSurface - - //프리입력 - if (type === INPUT_TYPE.FREE) { - addCanvasMouseEventListener('mouse:down', (e) => { - isDown = true - const pointer = canvas.getPointer(e.e) - - surfaceShapePolygons.forEach((surface) => { - if (surface.inPolygon({ x: pointer.x, y: pointer.y })) { - selectedSurface = surface - } - }) - - if (!selectedSurface) { - swalFire({ text: '지붕안에 그려야해요', icon: 'error' }) - setShowObjectSettingModal(true) //메뉴보이고 - initEvent() //이벤트 초기화 - return - } - - origX = pointer.x - origY = pointer.y - - rect = new fabric.Rect({ - left: origX, - top: origY, - originX: 'left', - originY: 'top', - width: 0, - height: 0, - angle: 0, - stroke: 'black', - }) - - //개구냐 그림자냐에 따라 변경 - rect.set({ - fill: buttonAct === 1 ? 'white' : 'rgba(0, 0, 0, 0.3)', - name: buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP, - }) - - canvas?.add(rect) - }) - - addCanvasMouseEventListener('mouse:move', (e) => { - if (!isDown) return - - if (selectedSurface) { - const pointer = canvas.getPointer(e.e) - const width = pointer.x - origX - const height = pointer.y - origY - - rect.set({ width: Math.abs(width), height: Math.abs(height) }) - - if (width < 0) { - rect.set({ left: Math.abs(pointer.x) }) - } - if (height < 0) { - rect.set({ top: Math.abs(pointer.y) }) - } - - canvas?.renderAll() - } - }) - - addCanvasMouseEventListener('mouse:up', (e) => { - if (rect) { - const rectPolygon = pointsToTurfPolygon(rectToPolygon(rect)) - const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) - - //지붕 밖으로 그렸을때 - if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) { - swalFire({ text: '지붕안에 그리라고요...', icon: 'error' }) - //일단 지워 - const deleteTarget = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING_TEMP || obj.name === BATCH_TYPE.SHADOW_TEMP) - canvas?.remove(...deleteTarget) - setShowObjectSettingModal(true) //메뉴보이고 - initEvent() //이벤트 초기화 - return - } - - // if (!isCrossChecked) { - // const isCross = preObjectsArray.some((object) => turf.booleanOverlap(pointsToTurfPolygon(rectToPolygon(object), rectPolygon))) - - // console.log(isCross) - - // if (isCross) { - // swalFire({ text: '겹치기 불가요...', icon: 'error' }) - // const deleteTarget = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING_TEMP || obj.name === BATCH_TYPE.SHADOW_TEMP) - // canvas?.remove(...deleteTarget) - // setShowObjectSettingModal(true) //메뉴보이고 - // initEvent() //이벤트 초기화 - // return - // } - // } - - isDown = false - const complateName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW - rect.set({ name: complateName }) - rect.setCoords() - - preObjectsArray.push(rect) - - console.log('preObjectsArray', preObjectsArray) - setPreObjects(preObjectsArray) - - setShowObjectSettingModal(true) //메뉴보이고 - initEvent() - } - }) - } + applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons, setShowObjectSettingModal) } } diff --git a/src/components/floor-plan/modal/object/type/OpenSpace.jsx b/src/components/floor-plan/modal/object/type/OpenSpace.jsx index 2ffe9b26..ab4d287d 100644 --- a/src/components/floor-plan/modal/object/type/OpenSpace.jsx +++ b/src/components/floor-plan/modal/object/type/OpenSpace.jsx @@ -1,23 +1,45 @@ -import { forwardRef } from 'react' +import { forwardRef, useState, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' import { INPUT_TYPE } from '@/common/common' const OpenSpace = forwardRef((props, refs) => { const { getMessage } = useMessage() + const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE) + + useEffect(() => { + if (selectedType === INPUT_TYPE.FREE) { + refs.widthRef.current.value = 0 + refs.heightRef.current.value = 0 + } + }, [selectedType]) //체크하면 값바꿈 - return (
- (refs.typeRef.current[0] = el)} /> + (refs.typeRef.current[0] = el)} + onClick={() => setSelectedType(INPUT_TYPE.FREE)} + />
- (refs.typeRef.current[1] = el)} /> + (refs.typeRef.current[1] = el)} + onClick={() => setSelectedType(INPUT_TYPE.DIMENSION)} + />
@@ -29,7 +51,13 @@ const OpenSpace = forwardRef((props, refs) => {
- +
mm
@@ -40,7 +68,13 @@ const OpenSpace = forwardRef((props, refs) => {
- +
mm
diff --git a/src/components/floor-plan/modal/object/type/Shadow.jsx b/src/components/floor-plan/modal/object/type/Shadow.jsx index 71bfb6ed..0945d78c 100644 --- a/src/components/floor-plan/modal/object/type/Shadow.jsx +++ b/src/components/floor-plan/modal/object/type/Shadow.jsx @@ -1,20 +1,45 @@ -import { forwardRef } from 'react' +import { forwardRef, useState, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' import { INPUT_TYPE } from '@/common/common' const Shadow = forwardRef((props, refs) => { const { getMessage } = useMessage() + + const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE) + + useEffect(() => { + if (selectedType === INPUT_TYPE.FREE) { + refs.widthRef.current.value = 0 + refs.heightRef.current.value = 0 + } + }, [selectedType]) + return (
- (refs.typeRef.current[0] = el)} /> + (refs.typeRef.current[0] = el)} + onClick={() => setSelectedType(INPUT_TYPE.FREE)} + />
- (refs.typeRef.current[1] = el)} /> + (refs.typeRef.current[1] = el)} + onClick={() => setSelectedType(INPUT_TYPE.DIMENSION)} + />
@@ -26,7 +51,13 @@ const Shadow = forwardRef((props, refs) => {
- +
mm
@@ -37,7 +68,13 @@ const Shadow = forwardRef((props, refs) => {
- +
mm
diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index 1d395d27..33b393b8 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -1,6 +1,210 @@ +'use client' +import { useMessage } from '@/hooks/useMessage' +import { useRecoilState, useRecoilValue } from 'recoil' +import { canvasState } from '@/store/canvasAtom' +import { INPUT_TYPE, BATCH_TYPE } from '@/common/common' +import { useEvent } from '@/hooks/useEvent' +import { polygonToTurfPolygon, rectToPolygon, pointsToTurfPolygon } from '@/util/canvas-util' +import { useSwal } from '@/hooks/useSwal' +import * as turf from '@turf/turf' + export function useObjectBatch() { const { getMessage } = useMessage() const canvas = useRecoilValue(canvasState) + const { addCanvasMouseEventListener, initEvent } = useEvent() + const { swalFire } = useSwal() - const openObjectBatch = () => {} + const applyOpeningAndShadow = (objectPlacement, buttonAct, surfaceShapePolygons, setShowObjectSettingModal) => { + const selectedType = objectPlacement.typeRef.current.find((radio) => radio.checked).value + const isCrossChecked = buttonAct === 1 ? objectPlacement.isCrossRef.current.checked : false + const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP + const objName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW + + let rect, isDown, origX, origY + let selectedSurface + + //프리입력 + if (selectedType === INPUT_TYPE.FREE) { + addCanvasMouseEventListener('mouse:down', (e) => { + isDown = true + const pointer = canvas.getPointer(e.e) + + surfaceShapePolygons.forEach((surface) => { + if (surface.inPolygon({ x: pointer.x, y: pointer.y })) { + selectedSurface = surface + } + }) + + if (!selectedSurface) { + swalFire({ text: '지붕안에 그려야해요', icon: 'error' }) + initEvent() //이벤트 초기화 + return + } + + origX = pointer.x + origY = pointer.y + + rect = new fabric.Rect({ + left: origX, + top: origY, + originX: 'left', + originY: 'top', + width: 0, + height: 0, + angle: 0, + stroke: 'black', + }) + + //개구냐 그림자냐에 따라 변경 + rect.set({ + fill: buttonAct === 1 ? 'white' : 'rgba(0, 0, 0, 0.4)', + name: objTempName, + }) + + canvas?.add(rect) + }) + + addCanvasMouseEventListener('mouse:move', (e) => { + if (!isDown) return + + if (selectedSurface) { + const pointer = canvas.getPointer(e.e) + const width = pointer.x - origX + const height = pointer.y - origY + + rect.set({ width: Math.abs(width), height: Math.abs(height) }) + + if (width < 0) { + rect.set({ left: Math.abs(pointer.x) }) + } + if (height < 0) { + rect.set({ top: Math.abs(pointer.y) }) + } + + canvas?.renderAll() + } + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + if (rect) { + const rectPolygon = pointsToTurfPolygon(rectToPolygon(rect)) + const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) + + //지붕 밖으로 그렸을때 + if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) { + swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' }) + //일단 지워 + deleteTempObjects(setShowObjectSettingModal) + return + } + + if (!isCrossChecked) { + const preObjects = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW) + const preObjectsArray = preObjects.map((obj) => rectToPolygon(obj)) + const isCross = preObjectsArray.some((object) => turf.booleanOverlap(pointsToTurfPolygon(object), rectPolygon)) + + if (isCross) { + swalFire({ text: '겹치기 불가요...', icon: 'error' }) + deleteTempObjects(setShowObjectSettingModal) + return + } + } + + isDown = false + rect.set({ name: objName }) + rect.setCoords() + initEvent() + } + }) + } else if (selectedType === INPUT_TYPE.DIMENSION) { + const width = objectPlacement.widthRef.current.value / 10 + const height = objectPlacement.heightRef.current.value / 10 + + if (width === '' || height === '' || width <= 0 || height <= 0) { + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) + return + } + + // setShowObjectSettingModal(false) //메뉴보이고 + addCanvasMouseEventListener('mouse:move', (e) => { + isDown = true + if (!isDown) return + + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === objTempName)) //움직일때 일단 지워가면서 움직임 + const pointer = canvas.getPointer(e.e) + + surfaceShapePolygons.forEach((surface) => { + if (surface.inPolygon({ x: pointer.x, y: pointer.y })) { + selectedSurface = surface + } + }) + + rect = new fabric.Rect({ + fill: 'white', + stroke: 'black', + strokeWidth: 1, + width: width, + height: height, + left: pointer.x - width / 2, + top: pointer.y - height / 2, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + }) + + //개구냐 그림자냐에 따라 변경 + rect.set({ + fill: buttonAct === 1 ? 'white' : 'rgba(0, 0, 0, 0.4)', + name: objTempName, + }) + + canvas?.add(rect) + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + if (rect) { + const rectPolygon = pointsToTurfPolygon(rectToPolygon(rect)) + const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) + + //지붕 밖으로 그렸을때 + if (!turf.booleanWithin(rectPolygon, selectedSurfacePolygon)) { + swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' }) + //일단 지워 + deleteTempObjects(setShowObjectSettingModal) + return + } + + if (!isCrossChecked) { + const preObjects = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW) + const preObjectsArray = preObjects.map((obj) => rectToPolygon(obj)) + const isCross = preObjectsArray.some((object) => turf.booleanOverlap(pointsToTurfPolygon(object), rectPolygon)) + + if (isCross) { + swalFire({ text: '겹치기 불가요...', icon: 'error' }) + deleteTempObjects(setShowObjectSettingModal) + return + } + } + + isDown = false + rect.set({ name: objName }) + rect.setCoords() + initEvent() + } + }) + } + } + + const deleteTempObjects = (setShowObjectSettingModal) => { + const deleteTarget = canvas?.getObjects().filter((obj) => obj.name === BATCH_TYPE.OPENING_TEMP || obj.name === BATCH_TYPE.SHADOW_TEMP) + canvas?.remove(...deleteTarget) + initEvent() //이벤트 초기화 + } + + return { + applyOpeningAndShadow, + } } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index c9e898e9..bcffeba4 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -2,7 +2,7 @@ import { useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' -import { MENU } from '@/common/common' +import { MENU, BATCH_TYPE } from '@/common/common' import { getIntersectionPoint, setSurfaceShapePattern } from '@/util/canvas-util' import { degreesToRadians } from '@turf/turf' import { QPolygon } from '@/components/fabric/QPolygon' @@ -131,23 +131,23 @@ export function useSurfaceShapeBatch() { if (surfaceId === 1) { if (length1 === 0) { - swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } if (length2 === 0) { if (length3 === 0) { - swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } } } else if ([2, 4].includes(surfaceId)) { if (length1 === 0 || length2 === 0) { - swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } } else if ([3, 5, 6, 15, 18].includes(surfaceId)) { if (length1 === 0 || length2 === 0 || length3 === 0) { - swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } if (surfaceId === 3 && length3 > length1) { @@ -173,7 +173,7 @@ export function useSurfaceShapeBatch() { } } else if ([8, 12, 13, 16, 17].includes(surfaceId)) { if (length1 === 0 || length2 === 0 || length3 === 0 || length4 === 0) { - swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } @@ -201,7 +201,7 @@ export function useSurfaceShapeBatch() { } } else if ([7, 9, 10, 11, 14].includes(surfaceId)) { if (length1 === 0 || length2 === 0 || length3 === 0 || length4 === 0 || length5 === 0) { - swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } if (surfaceId === 9 || surfaceId === 10 || surfaceId === 11) { @@ -564,7 +564,27 @@ export function useSurfaceShapeBatch() { return points } + + const deleteAllSurfacesAndObjects = () => { + swalFire({ + text: '삭제 ㄱㄱ?', + type: 'confirm', + confirmFn: () => { + canvas?.getObjects().forEach((obj) => { + if (obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH || obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.SHADOW) { + canvas?.remove(obj) + } + }) + swalFire({ text: '삭제 완료 되었습니다.' }) + }, + denyFn: () => { + swalFire({ text: '취소되었습니다.' }) + }, + }) + } + return { applySurfaceShape, + deleteAllSurfacesAndObjects, } } diff --git a/src/locales/ja.json b/src/locales/ja.json index c2ae55a0..abdfc11c 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -470,7 +470,7 @@ "main.popup.login.validate1": "入力したパスワードが異なります。", "main.popup.login.validate2": "半角10文字以内で入力してください。", "main.popup.login.success": "パスワードが変更されました。", - "surface.shape.validate.size": "寸法を入力してください.", + "common.canvas.validate.size": "寸法を入力してください.", "surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.", "surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.", "surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.", diff --git a/src/locales/ko.json b/src/locales/ko.json index 0bd7e448..3e37918b 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -474,7 +474,7 @@ "main.popup.login.validate1": "입력한 패스워드가 다릅니다.", "main.popup.login.validate2": "반각 10자 이내로 입력해주세요.", "main.popup.login.success": "비밀번호가 변경되었습니다.", - "surface.shape.validate.size": "사이즈를 입력해 주세요.", + "common.canvas.validate.size": "사이즈를 입력해 주세요.", "surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.", "surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.", "surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.",