diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx index 9ac285c0..d6d08675 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx @@ -1,9 +1,14 @@ import Image from 'next/image' import { useMessage } from '@/hooks/useMessage' +import { forwardRef, useState } from 'react' -export default function PlacementSurface(props) { +const PlacementSurface = forwardRef((props, refs) => { const { getMessage } = useMessage() const { id, lines, info, rotate, xInversion, yInversion } = props + let { length1, length2, length3, length4, length5, lengthetc, azimuth } = refs + + const [azimuthDirection, setAzimuthDirection] = useState(azimuth.current) + const num = ['①', '②', '③', '④', '⑤'] const getImageUrl = () => { if (xInversion && !yInversion) { @@ -24,6 +29,12 @@ export default function PlacementSurface(props) { return `/static/images/canvas/shape/${rotate !== 0 ? Math.abs(rotate * 90) + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` } + + const azimuthButton = (direction, e) => { + setAzimuthDirection(direction) + azimuth.current = direction + } + return ( <>
@@ -36,14 +47,31 @@ export default function PlacementSurface(props) {
{lines?.map((line, index) => ( -
+
{line.isDiagonal ? getMessage('modal.placement.surface.setting.diagonal.length') : num[index]}
- +
mm
@@ -62,10 +90,10 @@ export default function PlacementSurface(props) { {getMessage('commons.east')} {getMessage('commons.south')} {getMessage('commons.west')} - - - - + + + +
@@ -73,4 +101,6 @@ export default function PlacementSurface(props) { {info &&
{info}
} ) -} +}) + +export default PlacementSurface diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx index 06af2237..d2c3022a 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -1,15 +1,30 @@ import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' -import { useEffect, useState } from 'react' +import { useEffect, useState, useRef } from 'react' import Image from 'next/image' import PlacementSurface from '@/components/floor-plan/modal/placementSurface/PlacementSurface' +import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSettingModal }) { const { getMessage } = useMessage() + const [selectedType, setSelectedType] = useState() const [rotate, setRotate] = useState(0) const [xInversion, setXInversion] = useState(false) const [yInversion, setYInversion] = useState(false) + + const { applySurfaceShape } = useSurfaceShapeBatch() + + const surfaceRefs = { + length1: useRef(null), + length2: useRef(null), + length3: useRef(null), + length4: useRef(null), + length5: useRef(null), + lengthetc: useRef(null), + azimuth: useRef('down'), + } + /* type * a: line 2 * b: line 2 + diagonal 1 @@ -21,11 +36,11 @@ export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSetting { id: 1, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, { isDiagonal: true, - value: 3500, + value: 0, }, ], info: getMessage('modal.placement.surface.setting.info'), @@ -33,151 +48,151 @@ export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSetting { id: 2, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 3, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 4, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 5, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 6, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], lineAmount: 3, }, { id: 7, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 8, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 9, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 10, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 11, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 12, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 13, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 14, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 15, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 16, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 17, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, { id: 18, lines: [ - { isDiagonal: false, value: 4500 }, - { isDiagonal: false, value: 2600 }, - { isDiagonal: false, value: 2600 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, + { isDiagonal: false, value: 0 }, ], }, ] @@ -200,11 +215,11 @@ export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSetting return `rotate(${90 * rotate}deg)` } - const onClick = () => { - if (xInversion !== yInversion) { - } else { - setRotate((rotate + 1) % 4) - } + const applySurfaces = () => { + surfaceRefs.xInversion = xInversion //좌우반전 + surfaceRefs.yInversion = yInversion //상하반전 + surfaceRefs.rotate = rotate * 90 //앵글 + applySurfaceShape(surfaceRefs, selectedType, setShowPlacementSurfaceSettingModal) } useEffect(() => { @@ -245,9 +260,11 @@ export default function PlacementSurfaceSetting({ setShowPlacementSurfaceSetting
- +
- +
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js new file mode 100644 index 00000000..e612a463 --- /dev/null +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -0,0 +1,633 @@ +'use client' + +import { useEffect, useRef, useState } from 'react' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { canvasState } from '@/store/canvasAtom' +import { MENU } from '@/common/common' +import { getIntersectionPoint } from '@/util/canvas-util' +import { degreesToRadians } from '@turf/turf' +import { QPolygon } from '@/components/fabric/QPolygon' +import { fabric } from 'fabric' +import { useSwal } from '@/hooks/useSwal' +import { useMessage } from '@/hooks/useMessage' + +export function useSurfaceShapeBatch() { + const { getMessage } = useMessage() + + const canvas = useRecoilValue(canvasState) + const { swalFire } = useSwal() + + const applySurfaceShape = (surfaceRefs, selectedType, setShowPlacementSurfaceSettingModal) => { + let length1, length2, length3, length4, length5 + const surfaceId = selectedType?.id + const azimuth = surfaceRefs.azimuth.current + + if (surfaceId === 1) { + length1 = surfaceRefs.length1.current.value + length2 = surfaceRefs.length2.current.value + length3 = surfaceRefs.lengthetc.current.value //대각선 + } else if ([2, 4].includes(surfaceId)) { + length1 = surfaceRefs.length1.current.value + length2 = surfaceRefs.length2.current.value + } else if ([3, 5, 6, 15, 18].includes(surfaceId)) { + length1 = surfaceRefs.length1.current.value + length2 = surfaceRefs.length2.current.value + length3 = surfaceRefs.length3.current.value + } else if ([8, 12, 13, 16, 17].includes(surfaceId)) { + length1 = surfaceRefs.length1.current.value + length2 = surfaceRefs.length2.current.value + length3 = surfaceRefs.length3.current.value + length4 = surfaceRefs.length4.current.value + } else if ([7, 9, 10, 11, 14].includes(surfaceId)) { + length1 = surfaceRefs.length1.current.value + length2 = surfaceRefs.length2.current.value + length3 = surfaceRefs.length3.current.value + length4 = surfaceRefs.length4.current.value + length5 = surfaceRefs.length5.current.value + } + + length1 = parseInt(length1 === undefined ? 0 : length1 / 10) + length2 = parseInt(length2 === undefined ? 0 : length2 / 10) + length3 = parseInt(length3 === undefined ? 0 : length3 / 10) + length4 = parseInt(length4 === undefined ? 0 : length4 / 10) + length5 = parseInt(length5 === undefined ? 0 : length5 / 10) + + let isDrawing = true + let obj = null + let points = [] + if (checkSurfaceShape(surfaceId, { length1, length2, length3, length4, length5 })) { + setShowPlacementSurfaceSettingModal(false) + canvas?.on('mouse:move', (e) => { + console.log('asdfasdfasdfasdfasdfsdfasdfsdf') + + if (!isDrawing) { + return + } + const pointer = canvas?.getPointer(e.e) + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP)) + points = getSurfaceShape(surfaceId, pointer, { length1, length2, length3, length4, length5 }) + + const options = { + fill: 'transparent', + stroke: 'black', + strokeWidth: 1, + strokeDasharray: [10, 4], + fontSize: 12, + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + lockScalingX: true, // X 축 크기 조정 잠금 + lockScalingY: true, // Y 축 크기 조정 잠금 + name: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP, + flipX: surfaceRefs.yInversion, + flipY: surfaceRefs.xInversion, + angle: surfaceRefs.rotate, + originX: 'center', + originY: 'center', + } + + obj = new QPolygon(points, options) + obj.setCoords() //좌표 변경 적용 + + canvas?.add(obj) + + //각도 추가 + let originAngle = 0 //기본 남쪽 + let direction = 'south' + if (azimuth === 'left') { + //서 + originAngle = 90 + direction = 'west' + } else if (azimuth === 'right') { + //동 + originAngle = 270 + direction = 'east' + } else if (azimuth === 'up') { + //북 + originAngle = 180 + direction = 'north' + } + + obj.set({ direction: direction }) + obj.set({ originAngle: originAngle }) + + // setCurrentPattern(obj) + canvas?.renderAll() + }) + + canvas?.on('mouse:down', (e) => { + isDrawing = false + obj.set('name', MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH) + canvas?.off('mouse:down') + canvas.off('mouse:move') + setSurfaceShapePattern(obj) + setShowPlacementSurfaceSettingModal(true) + }) + } + } + + //면형상 입력 validate + const checkSurfaceShape = (surfaceId, lengths) => { + const { length1, length2, length3, length4, length5 } = lengths + let check = true + + if (surfaceId === 1) { + if (length1 === 0) { + swalFire({ text: getMessage('surface.shape.validate.size'), icon: 'error' }) + check = false + } + if (length2 === 0) { + if (length3 === 0) { + swalFire({ text: getMessage('surface.shape.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' }) + 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' }) + check = false + } + if (surfaceId === 3 && length3 > length1) { + swalFire({ text: getMessage('surface.shape.validate.size.1to3'), icon: 'error' }) + check = false + } + + if (surfaceId === 5 || surfaceId === 15) { + if (length3 >= length2) { + swalFire({ text: getMessage('surface.shape.validate.size.2to3'), icon: 'error' }) + check = false + } + } + if (surfaceId === 18) { + if (length1 >= length2) { + swalFire({ text: getMessage('surface.shape.validate.size.1to2'), icon: 'error' }) + check = false + } + if (length4 >= length3) { + swalFire({ text: getMessage('surface.shape.validate.size.3to4'), icon: 'error' }) + check = false + } + } + } 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' }) + check = false + } + + if (surfaceId === 8) { + if (length2 >= length1) { + swalFire({ text: getMessage('surface.shape.validate.size.1to2'), icon: 'error' }) + check = false + } + if (length4 >= length3) { + swalFire({ text: getMessage('surface.shape.validate.size.3to4'), icon: 'error' }) + check = false + } + } + + if (surfaceId === 12 || surfaceId === 13 || surfaceId === 16 || surfaceId === 17) { + if (length2 >= length1) { + swalFire({ text: getMessage('surface.shape.validate.size.1to2'), icon: 'error' }) + check = false + } + + if (length4 >= length3) { + swalFire({ text: getMessage('surface.shape.validate.size.1to2'), icon: 'error' }) + check = false + } + } + } 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' }) + check = false + } + if (surfaceId === 9 || surfaceId === 10 || surfaceId === 11) { + if (length2 + length3 >= length1) { + swalFire({ text: getMessage('surface.shape.validate.size.1to23'), icon: 'error' }) + check = false + } + if (length5 >= length4) { + swalFire({ text: getMessage('surface.shape.validate.size.4to5'), icon: 'error' }) + check = false + } + } + + if (surfaceId === 14) { + if (length2 + length3 >= length1) { + swalFire({ text: getMessage('surface.shape.validate.size.1to23'), icon: 'error' }) + check = false + } + if (length5 >= length4) { + swalFire({ text: getMessage('surface.shape.validate.size.4to5'), icon: 'error' }) + check = false + } + } + } + return check + } + + //면형상 가져오기 + const getSurfaceShape = (surfaceId, pointer, lengths) => { + let points = [] + const { length1, length2, length3, length4, length5 } = lengths + + switch (surfaceId) { + case 1: { + let newLength2 = length2 + + if (length3 !== 0) { + newLength2 = Math.sqrt(length3 ** 2 - (length1 / 2) ** 2) + } + + points = [ + { x: pointer.x, y: pointer.y - parseInt(newLength2) / 2 }, + { x: pointer.x - parseInt(length1) / 2, y: pointer.y + parseInt(newLength2) / 2 }, + { x: pointer.x + parseInt(length1) / 2, y: pointer.y + parseInt(newLength2) / 2 }, + ] + + break + } + case 2: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y - length2 / 2 }, + { x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 }, + ] + + break + } + case 3: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length3 / 2, y: pointer.y - length2 / 2 }, + { x: pointer.x - length3 / 2, y: pointer.y - length2 / 2 }, + ] + + break + } + case 4: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y - length2 / 2 }, + ] + + break + } + case 5: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y - length3 / 2 }, + { x: pointer.x - length1 / 2, y: pointer.y + length3 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 - length2 }, + ] + + break + } + case 6: { + const angleInRadians = Math.asin(length2 / length3) + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x - length1 / 2 + length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) }, + { x: pointer.x + length1 / 2 + length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, + ] + + break + } + case 7: { + points = [ + { x: pointer.x - (length1 + length2 + length3) / 2, y: pointer.y - (length4 + length5) / 2 }, + { x: pointer.x - (length1 + length2 + length3) / 2, y: pointer.y + (length4 + length5) / 2 }, + { x: pointer.x - (length1 + length2 + length3) / 2 + length1, y: pointer.y + (length4 + length5) / 2 }, + { x: pointer.x - (length1 + length2 + length3) / 2 + length1, y: pointer.y + (length4 + length5) / 2 - length5 }, + { x: pointer.x - (length1 + length2 + length3) / 2 + length1 + length2, y: pointer.y + (length4 + length5) / 2 - length5 }, + { x: pointer.x - (length1 + length2 + length3) / 2 + length1 + length2, y: pointer.y + (length4 + length5) / 2 - length5 + length5 }, + { + x: pointer.x - (length1 + length2 + length3) / 2 + length1 + length2 + length3, + y: pointer.y + (length4 + length5) / 2 - length5 + length5, + }, + { + x: pointer.x - (length1 + length2 + length3) / 2 + length1 + length2 + length3, + y: pointer.y + (length4 + length5) / 2 - length5 + length5 - (length4 + length5), + }, + ] + + break + } + case 8: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length3 }, + { x: pointer.x - length1 / 2 + length1 - (length1 - length2), y: pointer.y + length4 / 2 - length3 }, + { x: pointer.x - length1 / 2 + length1 - (length1 - length2), y: pointer.y + length4 / 2 - length3 + (length3 - length4) }, + { x: pointer.x - length1 / 2 + length1 - (length1 - length2) - length2, y: pointer.y + length4 / 2 - length3 + (length3 - length4) }, + ] + + break + } + case 9: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 }, + { x: pointer.x - length1 / 2 + length1 - length3, y: pointer.y + length4 / 2 - length4 }, + { x: pointer.x - length1 / 2 + length1 - length3, y: pointer.y + length4 / 2 - length4 + (length4 - length5) }, + { x: pointer.x - length1 / 2 + length1 - length3 - length2, y: pointer.y + length4 / 2 - length4 + (length4 - length5) }, + ] + break + } + case 10: { + points = [ + { x: pointer.x + length1 / 2, y: pointer.y + length4 / 2 }, + { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 }, + { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 - length5 }, + { x: pointer.x + length1 / 2 - length1 + length2, y: pointer.y + length4 / 2 - length5 }, + { x: pointer.x + length1 / 2 - length1 + length2, y: pointer.y + length4 / 2 - length5 - (length4 - length5) }, + { x: pointer.x + length1 / 2 - length1 + length2 + length3, y: pointer.y + length4 / 2 - length5 - (length4 - length5) }, + ] + break + } + case 11: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length5 }, + { x: pointer.x - length1 / 2 + length1 - length2, y: pointer.y + length4 / 2 - length5 }, + { x: pointer.x - length1 / 2 + length1 - length2, y: pointer.y + length4 / 2 - length5 - (length4 - length5) }, + { x: pointer.x - length1 / 2 + length1 - length2 - length3, y: pointer.y + length4 / 2 - length5 - (length4 - length5) }, + ] + break + } + case 12: { + const leftHypotenuse = Math.sqrt(((length1 - length2) / 2) ** 2 + length3 ** 2) + const rightHypotenuse = (length4 / length3) * leftHypotenuse + + const leftAngle = Math.acos((length1 - length2) / 2 / leftHypotenuse) + + points = [ + { x: pointer.x - length1 / 2 + leftHypotenuse * Math.cos(leftAngle), y: pointer.y + length3 / 2 - leftHypotenuse * Math.sin(leftAngle) }, + { x: pointer.x - length1 / 2, y: pointer.y + length3 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 }, + { + x: pointer.x + length1 / 2 - rightHypotenuse * Math.cos(leftAngle), + y: pointer.y + length3 / 2 - rightHypotenuse * Math.sin(leftAngle), + }, + { + x: pointer.x + length1 / 2 - rightHypotenuse * Math.cos(leftAngle) - length2, + y: pointer.y + length3 / 2 - rightHypotenuse * Math.sin(leftAngle), + }, + ] + + break + } + case 13: { + const pointsArray = [ + { x: 0, y: 0 }, + { x: 0, y: 0 }, + { x: 0, y: 0 }, + { x: 0, y: 0 }, + { x: 0, y: 0 }, + ] + + const tmpPolygon = new QPolygon( + [ + { x: 0, y: length3 }, + { x: length1 - length2, y: length3 }, + { x: (length1 - length2) / 2, y: length3 - length3 }, + ], + { + fill: 'transparent', + stroke: 'black', //black + strokeWidth: 2, + selectable: true, + fontSize: 0, + }, + ) + + const coord = getIntersectionPoint(tmpPolygon.lines[1].startPoint, tmpPolygon.lines[2].startPoint, length3 - length4) + const scale = (length1 - length2) / coord.x + + tmpPolygon.set({ scaleX: scale }) + + pointsArray[0].x = 0 + pointsArray[0].y = length3 //바닥면부터 시작하게 + pointsArray[1].x = pointsArray[0].x + length1 + pointsArray[1].y = pointsArray[0].y + pointsArray[2].x = pointsArray[1].x + pointsArray[2].y = pointsArray[1].y - length4 + pointsArray[3].x = pointsArray[2].x - length2 + pointsArray[3].y = pointsArray[2].y + pointsArray[4].x = tmpPolygon.getCurrentPoints()[2].x + pointsArray[4].y = tmpPolygon.getCurrentPoints()[2].y + + points = [ + { + x: pointer.x - length1 / 2, + y: pointer.y + length4 / 2, + }, + { + x: pointer.x + length1 / 2, + y: pointer.y + length4 / 2, + }, + { + x: pointer.x + length1 / 2, + y: pointer.y - length4 / 2, + }, + { + x: pointer.x - (length2 - length1 / 2), + y: pointer.y - length4 / 2, + }, + { + x: pointer.x - length1 / 2 + pointsArray[4].x, + y: pointer.y - length3 + length4 / 2, + }, + ] + + break + } + case 14: { + points = [ + { x: pointer.x - length1 / 2 + length2, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 - length4 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 + length4 }, + { x: pointer.x - length1 / 2 + length1 - length3, y: pointer.y + length4 / 2 - length4 + length4 }, + { x: pointer.x - length1 / 2 + length2 + (length1 - length2 - length3) / 2, y: pointer.y + length4 / 2 - length4 + length5 }, + ] + break + } + + case 15: { + points = [ + { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 }, + { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 }, + { x: pointer.x, y: pointer.y + length2 - length2 / 2 - length3 - (length2 - length3) }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 + length3 }, + ] + break + } + + case 16: { + points = [ + { + x: pointer.x - length1 / 2, + y: pointer.y + length3 / 2, + }, + { + x: pointer.x - length1 / 2 + (length1 - length2) / 2, + y: pointer.y + length3 / 2 - (length3 - length4), + }, + { + x: pointer.x - length1 / 2 + (length1 - length2) / 2, + y: pointer.y + length3 / 2 - (length3 - length4) - length4, + }, + { + x: pointer.x - length1 / 2 + (length1 - length2) / 2 + length2, + y: pointer.y + length3 / 2 - (length3 - length4) - length4, + }, + { + x: pointer.x - length1 / 2 + (length1 - length2) / 2 + length2, + y: pointer.y + length3 / 2 - (length3 - length4) - length4 + length4, + }, + { + x: pointer.x - length1 / 2 + length1, + y: pointer.y + length3 / 2, + }, + ] + break + } + case 17: { + const angle = (Math.asin(length3 / length4) * 180) / Math.PI // 높이와 빗변으로 먼저 각도구하기 + + const topL = (length1 - length2) / 2 / Math.cos((angle * Math.PI) / 180) // 꺽이는부분 윗쪽 길이 + + points = [ + { + x: pointer.x - length1 / 2 + length1, + y: pointer.y + length3 / 2, + }, + { + x: pointer.x - length1 / 2, + y: pointer.y + length3 / 2, + }, + { + x: pointer.x - length1 / 2 + length4 * Math.cos(angle), + y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), + }, + { + x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2, + y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), + }, + { + x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2 + topL * Math.cos(degreesToRadians(angle)), + y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)) + topL * Math.sin(degreesToRadians(angle)), + }, + ] + break + } + + case 18: { + const a = Math.sqrt(length3 * length3 - length2 * length2) // 입력된 밑변과 높이 + + const sinA = a / length3 + const angleInRadians = Math.asin(sinA) + const angleInDegrees = angleInRadians * (180 / Math.PI) + const b = a - length1 / 2 + + const c = b / Math.tan(angleInRadians) + const d = Math.sqrt(b * b + c * c) + const newAngleInRadians = (90 - angleInDegrees) * (Math.PI / 180) + points = [ + { x: pointer.x - (length1 + b) / 2, y: pointer.y + length2 / 2 }, + { x: pointer.x + length1 / 2 - b / 2, y: pointer.y + length2 / 2 }, + { + x: pointer.x + length1 / 2 - b / 2 + d * Math.cos(newAngleInRadians), + y: pointer.y + length2 / 2 - d * Math.sin(newAngleInRadians), + }, + { + x: pointer.x - (length1 + b) / 2 + length3 * Math.cos(newAngleInRadians), + y: pointer.y + length2 / 2 - length3 * Math.sin(newAngleInRadians), + }, + ] + break + } + } + + return points + } + + //면형상 선택 클릭시 지붕 패턴 입히기 + const setSurfaceShapePattern = (polygon) => { + const ratio = window.devicePixelRatio || 1 + + let width = 265 / 10 + let height = 150 / 10 + let roofStyle = 2 + const inputPatternSize = { width: width, height: height } //임시 사이즈 + const patternSize = { ...inputPatternSize } // 입력된 값을 뒤집기 위해 + + if (polygon.direction === 'east' || polygon.direction === 'west') { + //세로형이면 width height를 바꿈 + ;[patternSize.width, patternSize.height] = [inputPatternSize.height, patternSize.width] + } + + // 패턴 소스를 위한 임시 캔버스 생성 + const patternSourceCanvas = document.createElement('canvas') + patternSourceCanvas.width = polygon.width * ratio + patternSourceCanvas.height = polygon.height * ratio + const ctx = patternSourceCanvas.getContext('2d') + const offset = roofStyle === 1 ? 0 : patternSize.width / 2 + + const rows = Math.floor(patternSourceCanvas.height / patternSize.height) + const cols = Math.floor(patternSourceCanvas.width / patternSize.width) + + ctx.strokeStyle = 'green' + ctx.lineWidth = 0.4 + + for (let row = 0; row <= rows; row++) { + const y = row * patternSize.height + + ctx.beginPath() + ctx.moveTo(0, y) // 선 시작점 + ctx.lineTo(patternSourceCanvas.width, y) // 선 끝점 + ctx.stroke() + + for (let col = 0; col <= cols; col++) { + const x = col * patternSize.width + (row % 2 === 0 ? 0 : offset) + const yStart = row * patternSize.height + const yEnd = yStart + patternSize.height + + ctx.beginPath() + ctx.moveTo(x, yStart) // 선 시작점 + ctx.lineTo(x, yEnd) // 선 끝점 + ctx.stroke() + } + } + + // 패턴 생성 + const pattern = new fabric.Pattern({ + source: patternSourceCanvas, + repeat: 'repeat', + }) + + polygon.set('fill', null) + polygon.set('fill', pattern) + canvas?.renderAll() + } + + return { + applySurfaceShape, + } +} diff --git a/src/locales/ja.json b/src/locales/ja.json index cbda8988..faddd395 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -361,5 +361,12 @@ "main.content.objectList": "最近の更新物件一覧", "main.content.notice": "お知らせ", "main.content.download1": "操作マニュアル", - "main.content.download2": "屋根の説明書" + "main.content.download2": "屋根の説明書", + "surface.shape.validate.size": "寸法を入力してください.", + "surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.2to3": "②길이는 ③보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.3to4": "③길이는 ④보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.4to5": "④길이는 ⑤보다 큰 값을 넣어주세요." } diff --git a/src/locales/ko.json b/src/locales/ko.json index 6f3d3aca..3f5dd119 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -367,5 +367,12 @@ "main.content.objectList": "최근 갱신 물건목록", "main.content.notice": "공지사항", "main.content.download1": "조작메뉴얼", - "main.content.download2": "지붕설명서" + "main.content.download2": "지붕설명서", + "surface.shape.validate.size": "사이즈를 입력해 주세요.", + "surface.shape.validate.size.1to2": "①길이는 ②보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.1to3": "①길이는 ③보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.1to23": "①길이는 ②+③보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.2to3": "②길이는 ③보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.3to4": "③길이는 ④보다 큰 값을 넣어주세요.", + "surface.shape.validate.size.4to5": "④길이는 ⑤보다 큰 값을 넣어주세요." }