dev #930

Merged
ysCha merged 95 commits from dev into dev-deploy 2026-06-23 18:00:25 +09:00
2 changed files with 91 additions and 32 deletions
Showing only changes of commit e17af8f4b4 - Show all commits

View File

@ -36,6 +36,7 @@ export function useRoofShapePassivitySetting(id) {
const [type, setType] = useState(TYPES.EAVES)
const isFix = useRef(false)
const initLines = useRef([])
const removedWalls = useRef([])
const [isLoading, setIsLoading] = useState(false)
const { closePopup } = usePopup()
@ -60,6 +61,7 @@ export function useRoofShapePassivitySetting(id) {
addCanvasMouseEventListener('mouse:down', mouseDown)
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
removedWalls.current = wallLines.map((wall) => ({ wall, index: canvas.getObjects().indexOf(wall) }))
canvas?.remove(...wallLines)
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
@ -198,10 +200,32 @@ export function useRoofShapePassivitySetting(id) {
}
const handleLineToPolygon = () => {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
if (!isFix.current) {
// 저장 없이 닫을 경우 진입 시점 스냅샷으로 롤백 — 캔버스를 진입 전 상태 그대로 되돌린다
lines.forEach((line, idx) => {
const init = initLines.current[idx]
if (!init) {
return
}
init.visible ? showLine(line) : hideLine(line)
line.set({ stroke: init.stroke, strokeWidth: init.strokeWidth, selectable: init.selectable })
line.attributes = init.attributes
})
// 진입 시 삭제했던 WALL 폴리곤 원본을 원래 z-순서 그대로 재삽입
removedWalls.current.forEach(({ wall, index }) => {
canvas.insertAt(wall, index)
})
removedWalls.current = []
canvas.renderAll()
return
}
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
let checkedAllSetting = true
lines.forEach((line) => {
@ -219,36 +243,27 @@ export function useRoofShapePassivitySetting(id) {
canvas.remove(obj)
})
// 저장 시에는 자동 설정과 동일하게 외벽선을 타입별 색상으로 표시
lines.forEach((line) => {
hideLine(line)
let stroke
if (line.attributes?.type === LINE_TYPE.WALLLINE.EAVES || line.attributes?.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
stroke = '#45CD7D'
} else if (line.attributes?.type === LINE_TYPE.WALLLINE.GABLE || line.attributes?.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
stroke = '#3FBAE6'
} else {
stroke = '#000000'
}
line.set({ stroke, strokeWidth: 4, selectable: false, visible: true })
})
let wall
if (isFix.current) {
wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
} else {
// 그냥 닫을 경우 처리
wall = addPolygonByLines([...initLines.current], {
name: POLYGON_TYPE.WALL,
fill: 'transparent',
stroke: 'black',
})
lines.forEach((line, idx) => {
line.attributes = initLines.current[idx].attributes
})
}
const wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
wall.lines = [...lines]
// 기존 그려진 지붕이 없다면
if (isFix.current) {
// 완료 한 경우에는 지붕까지 그려줌
addPitchTextsByOuterLines()
const roof = drawRoofPolygon(wall)
addLengthText(roof)
}
// 완료 한 경우에는 지붕까지 그려줌
addPitchTextsByOuterLines()
const roof = drawRoofPolygon(wall)
addLengthText(roof)
lines.forEach((line) => line.bringToFront())
canvas.renderAll()
}

View File

@ -52,6 +52,11 @@ export function useRoofShapeSetting(id) {
const isFixRef = useRef(false)
// 저장 없이 닫을 때 롤백할 진입 시점 스냅샷
const initLinesRef = useRef([])
const removedWallsRef = useRef([])
const pitchTextLineIdsRef = useRef(new Set())
const pitchRef = useRef(null)
const shedPitchRef = useRef(null)
const jerkinHeadPitchRef = useRef(null)
@ -87,14 +92,46 @@ export function useRoofShapeSetting(id) {
closePopup(id)
return
}
return () => {
if (!isFixRef.current) {
return
}
initLinesRef.current = outerLines.map((line) => ({ ...line }))
pitchTextLineIdsRef.current = new Set(
canvas
.getObjects()
.filter((obj) => obj.name === 'pitchText')
.map((obj) => obj.parentId),
)
return () => {
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
const pitchTexts = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
if (!isFixRef.current) {
// 저장 없이 닫을 경우 진입 시점 스냅샷으로 롤백 — 캔버스를 진입 전 상태 그대로 되돌린다
canvas.remove(...pitchTexts)
outerLines.forEach((line, idx) => {
const init = initLinesRef.current[idx]
if (!init) {
return
}
init.visible ? showLine(line) : hideLine(line)
line.set({ stroke: init.stroke, strokeWidth: init.strokeWidth, selectable: init.selectable })
line.attributes = init.attributes
if (pitchTextLineIdsRef.current.has(line.id)) {
addPitchText(line)
}
})
// 변별로 설정 진입 시 삭제했던 WALL 폴리곤 원본을 원래 z-순서 그대로 재삽입
removedWallsRef.current.forEach(({ wall, index }) => {
canvas.insertAt(wall, index)
})
removedWallsRef.current = []
canvas.discardActiveObject()
canvas.renderAll()
return
}
canvas.remove(...pitchTexts)
outerLines.forEach((line) => {
let stroke, strokeWidth
@ -113,6 +150,8 @@ export function useRoofShapeSetting(id) {
line.set({
stroke,
strokeWidth,
selectable: false,
visible: true,
})
addPitchText(line)
@ -144,10 +183,15 @@ export function useRoofShapeSetting(id) {
useEffect(() => {
if (shapeNum === 4) {
canvas?.remove(canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL))
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL)
if (wall && removedWallsRef.current.length === 0) {
removedWallsRef.current = [{ wall, index: canvas.getObjects().indexOf(wall) }]
}
canvas?.remove(wall)
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
outerLines.forEach((line) => {
showLine(line)
line.set({ selectable: true })
line.bringToFront()
})