fix: 지붕형상 설정/수동설정 외벽선 표시·선택 상태 정리
[작업내용] : - 지붕형상 저장 후 색칠된 외벽선 선택·드래그 차단, 변별로 설정 재진입 시 선택 복원 - 수동설정 저장 시에도 자동설정과 동일하게 외벽선을 타입별 색상으로 표시 - 두 모달을 진입 시 스냅샷 → 저장 시 커밋 / 저장 없이 닫으면 롤백 구조로 변경 (팝업을 열었다 닫기만 해도 외벽선이 숨겨지고 지붕면이 삭제되던 문제 수정) - 롤백 시 WALL 폴리곤은 원본 객체를 원래 z-순서에 재삽입 (재생성 시 최상단에 올라가 보조선 클릭을 가로채던 문제 방지) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
54e6a31dcf
commit
e17af8f4b4
@ -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 wall
|
||||
|
||||
if (isFix.current) {
|
||||
wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||
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 {
|
||||
// 그냥 닫을 경우 처리
|
||||
wall = addPolygonByLines([...initLines.current], {
|
||||
name: POLYGON_TYPE.WALL,
|
||||
fill: 'transparent',
|
||||
stroke: 'black',
|
||||
})
|
||||
lines.forEach((line, idx) => {
|
||||
line.attributes = initLines.current[idx].attributes
|
||||
})
|
||||
stroke = '#000000'
|
||||
}
|
||||
line.set({ stroke, strokeWidth: 4, selectable: false, visible: true })
|
||||
})
|
||||
|
||||
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)
|
||||
}
|
||||
lines.forEach((line) => line.bringToFront())
|
||||
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
@ -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()
|
||||
})
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user