diff --git a/src/common/common.js b/src/common/common.js
index d0016af1..eb86bb89 100644
--- a/src/common/common.js
+++ b/src/common/common.js
@@ -161,6 +161,7 @@ export const SAVE_KEY = [
'groupId',
'planeSize',
'actualSize',
+ 'surfaceId',
]
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype]
diff --git a/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx b/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx
index 8e54c646..effb4717 100644
--- a/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx
+++ b/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx
@@ -5,14 +5,18 @@ import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
-
+import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
export default function FlowDirectionSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition, target } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [compasDeg, setCompasDeg] = useState(360)
+ const [flowDirection, setFlowDirection] = useState(target.direction)
+ const { changeSurfaceFlowDirection } = useSurfaceShapeBatch()
+
const orientations = [
+ // { name: `${getMessage('commons.none')}`, value: 0 },
{ name: `${getMessage('commons.south')}`, value: 360 },
{ name: `${getMessage('commons.south')}${getMessage('commons.east')}`, value: 315 },
{ name: `${getMessage('commons.south')}${getMessage('commons.west')}`, value: 45 },
@@ -75,13 +79,13 @@ export default function FlowDirectionSetting(props) {
{getMessage('commons.north')}
-
+
{getMessage('commons.east')}
-
+
{getMessage('commons.south')}
-
+
{getMessage('commons.west')}
-
+
@@ -111,18 +115,14 @@ export default function FlowDirectionSetting(props) {
key={index}
className={`circle ${compasDeg === 15 * (12 + index) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (12 + index))}
- >
- {13 - index}
-
+ >
))}
{Array.from({ length: 180 / 15 - 1 }).map((dot, index) => (
setCompasDeg(15 * (index + 1))}
- >
- {24 - index}
-
+ >
))}
@@ -133,7 +133,9 @@ export default function FlowDirectionSetting(props) {
-
+
diff --git a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx
index f5425e67..5b4075f0 100644
--- a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx
+++ b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx
@@ -3,13 +3,18 @@ import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
-import { useState } from 'react'
+import { useState, useEffect } from 'react'
+import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
+import { useEvent } from '@/hooks/useEvent'
export default function LinePropertySetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
- const { id, pos = contextPopupPosition } = props
+ const { id, pos = contextPopupPosition, target } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
+ const { changeSurfaceLinePropertyEvent, changeSurfaceLineProperty } = useSurfaceShapeBatch()
+ const { initEvent } = useEvent()
+
const properties = [
{ name: getMessage('eaves.line'), value: 'eaves' },
{ name: getMessage('ridge'), value: 'ridge' },
@@ -29,6 +34,14 @@ export default function LinePropertySetting(props) {
{ name: getMessage('no.setting'), value: 'noSetting' },
]
const [selectedProperty, setSelectedProperty] = useState(null)
+
+ useEffect(() => {
+ changeSurfaceLinePropertyEvent(target)
+ return () => {
+ initEvent()
+ }
+ }, [])
+
return (
@@ -66,7 +79,9 @@ export default function LinePropertySetting(props) {
-
+
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js
index d2c6aee7..67ee1874 100644
--- a/src/hooks/surface/useSurfaceShapeBatch.js
+++ b/src/hooks/surface/useSurfaceShapeBatch.js
@@ -13,6 +13,8 @@ import { usePopup } from '@/hooks/usePopup'
import { roofDisplaySelector } from '@/store/settingAtom'
import { usePolygon } from '@/hooks/usePolygon'
import { fontSelector } from '@/store/fontAtom'
+import { slopeSelector } from '@/store/commonAtom'
+import { QLine } from '@/components/fabric/QLine'
export function useSurfaceShapeBatch() {
const { getMessage } = useMessage()
@@ -22,6 +24,7 @@ export function useSurfaceShapeBatch() {
const canvas = useRecoilValue(canvasState)
const globalPitch = useRecoilValue(globalPitchState)
const roofDisplay = useRecoilValue(roofDisplaySelector)
+ const slope = useRecoilValue(slopeSelector(globalPitch))
const { swalFire } = useSwal()
const { addCanvasMouseEventListener, initEvent } = useEvent()
const { closePopup } = usePopup()
@@ -126,6 +129,7 @@ export function useSurfaceShapeBatch() {
addCanvasMouseEventListener('mouse:down', (e) => {
isDrawing = false
obj.set('name', POLYGON_TYPE.ROOF)
+ obj.set('surfaceId', surfaceId)
initEvent()
setSurfaceShapePattern(obj, roofDisplay.column)
closePopup(id)
@@ -580,18 +584,19 @@ export function useSurfaceShapeBatch() {
text: '배치면 내용을 전부 삭제하시겠습니까?',
type: 'confirm',
confirmFn: () => {
- canvas?.getObjects().forEach((obj) => {
- if (
- obj.name === POLYGON_TYPE.ROOF ||
- obj.name === BATCH_TYPE.OPENING ||
- obj.name === BATCH_TYPE.SHADOW ||
- obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
- obj.name === BATCH_TYPE.PENTAGON_DORMER ||
- obj.name === 'lengthText'
- ) {
- canvas?.remove(obj)
- }
- })
+ // canvas?.getObjects().forEach((obj) => {
+ // if (
+ // obj.name === POLYGON_TYPE.ROOF ||
+ // obj.name === BATCH_TYPE.OPENING ||
+ // obj.name === BATCH_TYPE.SHADOW ||
+ // obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
+ // obj.name === BATCH_TYPE.PENTAGON_DORMER ||
+ // obj.name === 'lengthText'
+ // ) {
+ // canvas?.remove(obj)
+ // }
+ // })
+ canvas.clear()
swalFire({ text: '삭제 완료 되었습니다.' })
},
// denyFn: () => {
@@ -823,10 +828,159 @@ export function useSurfaceShapeBatch() {
canvas.renderAll()
}
+ const surfaceShapeActualSize = () => {
+ const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
+ let notParallelLines = []
+
+ const roofArray = []
+
+ roofs.forEach((obj) => {
+ const roof = {
+ id: obj.id,
+ surfaceId: obj.surfaceId,
+ targetLines: [],
+ baseLines: [],
+ direction: obj.direction,
+ }
+ obj.lines.forEach((line) => {
+ if (obj.direction === 'north' || obj.direction === 'south') {
+ if (line.y1 !== line.y2) {
+ roof.targetLines.push(line)
+ } else {
+ roof.baseLines.push(line)
+ }
+ } else {
+ if (line.x1 !== line.x2) {
+ roof.targetLines.push(line)
+ } else {
+ roof.baseLines.push(line)
+ }
+ }
+ })
+ roofArray.push(roof)
+ })
+
+ const slopeRadians = slope.angleValue * (Math.PI / 180)
+ const tanSlope = Math.tan(slopeRadians)
+
+ roofArray.forEach((roof) => {
+ roof.targetLines.forEach((line) => {
+ let calcLength = line.length
+
+ if (roof.surfaceId === 1) {
+ calcLength = roof.direction === 'north' || roof.direction === 'south' ? Math.abs(line.y1 - line.y2) : Math.abs(line.x1 - line.x2)
+ }
+
+ const h = calcLength * tanSlope
+ const resultLength = Math.sqrt(Math.pow(calcLength, 2) + Math.pow(h, 2))
+
+ line.set({
+ attributes: {
+ ...line.attributes,
+ actualSize: parseInt((Math.floor(resultLength) * 10).toFixed(0)),
+ planeSize: parseInt(line.length * 10),
+ },
+ })
+ })
+ roof.baseLines.forEach((line) => {
+ line.set({
+ attributes: {
+ ...line.attributes,
+ actualSize: parseInt((Math.floor(line.length) * 10).toFixed(0)),
+ planeSize: parseInt(line.length * 10),
+ },
+ })
+ })
+ })
+ }
+
+ const changeSurfaceLinePropertyEvent = (roof) => {
+ let tmpLines = []
+ roof.set({
+ selectable: false,
+ })
+ canvas.discardActiveObject()
+ roof.lines.forEach((obj, index) => {
+ const tmpLine = new QLine([obj.x1, obj.y1, obj.x2, obj.y2], {
+ ...obj,
+ stroke: 'rgb(3, 255, 0)',
+ strokeWidth: 8,
+ selectable: true,
+ name: 'lineProperty',
+ index: index,
+ })
+
+ tmpLines.push(tmpLine)
+ canvas.add(tmpLine)
+ })
+
+ addCanvasMouseEventListener('mouse:down', (e) => {
+ const selectedLine = e.target
+ if (selectedLine) {
+ selectedLine.set({
+ stroke: 'red',
+ name: 'selectedLineProperty',
+ })
+ tmpLines.forEach((line) => {
+ if (line.index !== selectedLine.index) {
+ line.set({
+ stroke: 'rgb(3, 255, 0)',
+ name: 'lineProperty',
+ })
+ }
+ })
+ } else {
+ tmpLines.forEach((line) => {
+ line.set({
+ stroke: 'rgb(3, 255, 0)',
+ name: 'lineProperty',
+ })
+ })
+ }
+ })
+
+ canvas.renderAll()
+ }
+
+ const changeSurfaceLineProperty = (property) => {
+ console.log(property)
+ if (!property) {
+ swalFire({ text: getMessage('modal.line.property.change'), icon: 'error' })
+ return
+ }
+
+ const selectedLine = canvas.getActiveObjects()
+ if (selectedLine && selectedLine[0].name === 'selectedLineProperty') {
+ swalFire({
+ text: getMessage('modal.line.property.change.confirm'),
+ type: 'confirm',
+ confirmFn: () => {
+ selectedLine.set({
+ type: property.value,
+ })
+ },
+ })
+ } else {
+ swalFire({ text: getMessage('modal.line.property.change.unselect'), icon: 'error' })
+ }
+ }
+
+ const changeSurfaceFlowDirection = (roof, direction, orientation) => {
+ roof.set({
+ direction: direction,
+ })
+ drawDirectionArrow(roof)
+ canvas?.renderAll()
+ }
+
return {
applySurfaceShape,
deleteAllSurfacesAndObjects,
moveSurfaceShapeBatch,
resizeSurfaceShapeBatch,
+ surfaceShapeActualSize,
+ changeSurfaceFlowDirection,
+ changeSurfaceLinePropertyEvent,
+ changeSurfaceLineProperty,
}
}
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index 64892dce..cc8cce69 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -51,7 +51,7 @@ export function useContextMenu() {
const [column, setColumn] = useState(null)
const { handleZoomClear } = useCanvasEvent()
const { moveObjectBatch } = useObjectBatch({})
- const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
+ const { moveSurfaceShapeBatch, surfaceShapeActualSize } = useSurfaceShapeBatch()
const currentMenuSetting = () => {
switch (currentMenu) {
case MENU.PLAN_DRAWING:
@@ -303,6 +303,11 @@ export function useContextMenu() {
case 'roof':
setContextMenu([
[
+ {
+ id: 'surfaceShapeActualSize',
+ name: '면형상 실측',
+ fn: () => surfaceShapeActualSize(),
+ },
{
id: 'sizeEdit',
name: '사이즈 변경',
@@ -336,7 +341,7 @@ export function useContextMenu() {
{
id: 'linePropertyEdit',
name: getMessage('contextmenu.line.property.edit'),
- component: ,
+ component: ,
},
{
id: 'flowDirectionEdit',
diff --git a/src/locales/ko.json b/src/locales/ko.json
index a2ef69b3..bfa3cdc5 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -400,6 +400,9 @@
"modal.module.circuit.number.edit": "모듈 일괄 회로 번호 변경",
"modal.module.circuit.number.edit.info": "회로 번호를 입력해주세요.",
"modal.module.circuit.number": "회로 번호",
+ "modal.line.property.change": "변경할 속성을 선택해 주세요.",
+ "modal.line.property.change.unselect": "변경할 라인을 선택해 주세요.",
+ "modal.line.property.change.confirm": "속성을 변경하시겠습니까?",
"common.message.no.data": "No data",
"common.message.no.dataDown": "No data to download",
"common.message.noData": "No data to display",
@@ -495,6 +498,7 @@
"commons.east": "동",
"commons.south": "남",
"commons.north": "북",
+ "commons.none": "선택안함",
"font.style.normal": "보통",
"font.style.italic": "기울임꼴",
"font.style.bold": "굵게",