선속성 작업중

This commit is contained in:
yjnoh 2024-11-11 10:19:40 +09:00
parent 21d758834d
commit 86d9e574bb
6 changed files with 210 additions and 29 deletions

View File

@ -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]

View File

@ -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) {
<div className="object-direction-wrap">
<div className="plane-direction">
<span className="top">{getMessage('commons.north')}</span>
<button className="plane-btn up"></button>
<button className={`plane-btn up ${flowDirection === 'north' ? 'act' : ''}`} onClick={() => setFlowDirection('north')}></button>
<span className="right">{getMessage('commons.east')}</span>
<button className="plane-btn right"></button>
<button className={`plane-btn right ${flowDirection === 'east' ? 'act' : ''}`} onClick={() => setFlowDirection('east')}></button>
<span className="bottom">{getMessage('commons.south')}</span>
<button className="plane-btn down act"></button>
<button className={`plane-btn down ${flowDirection === 'south' ? 'act' : ''}`} onClick={() => setFlowDirection('south')}></button>
<span className="left">{getMessage('commons.west')}</span>
<button className="plane-btn left"></button>
<button className={`plane-btn left ${flowDirection === 'west' ? 'act' : ''}`} onClick={() => setFlowDirection('west')}></button>
</div>
</div>
</div>
@ -111,18 +115,14 @@ export default function FlowDirectionSetting(props) {
key={index}
className={`circle ${compasDeg === 15 * (12 + index) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (12 + index))}
>
<i>{13 - index}</i>
</div>
></div>
))}
{Array.from({ length: 180 / 15 - 1 }).map((dot, index) => (
<div
key={index}
className={`circle ${compasDeg === 15 * (index + 1) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (index + 1))}
>
<i>{24 - index}</i>
</div>
></div>
))}
<div className="compas">
<div className="compas-arr" style={{ transform: `rotate(${compasDeg}deg)` }}></div>
@ -133,7 +133,9 @@ export default function FlowDirectionSetting(props) {
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
<button className="btn-frame modal act" onClick={() => changeSurfaceFlowDirection(target, flowDirection, selectedOrientation)}>
{getMessage('modal.common.save')}
</button>
</div>
</div>
</div>

View File

@ -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 (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r mount`}>
@ -66,7 +79,9 @@ export default function LinePropertySetting(props) {
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
<button className="btn-frame modal act" onClick={() => changeSurfaceLineProperty(selectedProperty)}>
{getMessage('modal.common.save')}
</button>
</div>
</div>
</div>

View File

@ -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,
}
}

View File

@ -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: <LinePropertySetting id={popupId} />,
component: <LinePropertySetting id={popupId} target={currentObject} />,
},
{
id: 'flowDirectionEdit',

View File

@ -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": "굵게",