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 [type, setType] = useState(TYPES.EAVES)
|
||||||
const isFix = useRef(false)
|
const isFix = useRef(false)
|
||||||
const initLines = useRef([])
|
const initLines = useRef([])
|
||||||
|
const removedWalls = useRef([])
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
@ -60,6 +61,7 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
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)
|
canvas?.remove(...wallLines)
|
||||||
|
|
||||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
@ -198,10 +200,32 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleLineToPolygon = () => {
|
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')
|
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
|
let checkedAllSetting = true
|
||||||
|
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
@ -219,36 +243,27 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
canvas.remove(obj)
|
canvas.remove(obj)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 저장 시에는 자동 설정과 동일하게 외벽선을 타입별 색상으로 표시
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
hideLine(line)
|
let stroke
|
||||||
})
|
if (line.attributes?.type === LINE_TYPE.WALLLINE.EAVES || line.attributes?.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
||||||
|
stroke = '#45CD7D'
|
||||||
let wall
|
} else if (line.attributes?.type === LINE_TYPE.WALLLINE.GABLE || line.attributes?.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||||
|
stroke = '#3FBAE6'
|
||||||
if (isFix.current) {
|
|
||||||
wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
|
||||||
} else {
|
} else {
|
||||||
// 그냥 닫을 경우 처리
|
stroke = '#000000'
|
||||||
wall = addPolygonByLines([...initLines.current], {
|
|
||||||
name: POLYGON_TYPE.WALL,
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
})
|
|
||||||
lines.forEach((line, idx) => {
|
|
||||||
line.attributes = initLines.current[idx].attributes
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
line.set({ stroke, strokeWidth: 4, selectable: false, visible: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
const wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||||
wall.lines = [...lines]
|
wall.lines = [...lines]
|
||||||
|
|
||||||
// 기존 그려진 지붕이 없다면
|
|
||||||
|
|
||||||
if (isFix.current) {
|
|
||||||
// 완료 한 경우에는 지붕까지 그려줌
|
// 완료 한 경우에는 지붕까지 그려줌
|
||||||
addPitchTextsByOuterLines()
|
addPitchTextsByOuterLines()
|
||||||
const roof = drawRoofPolygon(wall)
|
const roof = drawRoofPolygon(wall)
|
||||||
addLengthText(roof)
|
addLengthText(roof)
|
||||||
}
|
lines.forEach((line) => line.bringToFront())
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,11 @@ export function useRoofShapeSetting(id) {
|
|||||||
|
|
||||||
const isFixRef = useRef(false)
|
const isFixRef = useRef(false)
|
||||||
|
|
||||||
|
// 저장 없이 닫을 때 롤백할 진입 시점 스냅샷
|
||||||
|
const initLinesRef = useRef([])
|
||||||
|
const removedWallsRef = useRef([])
|
||||||
|
const pitchTextLineIdsRef = useRef(new Set())
|
||||||
|
|
||||||
const pitchRef = useRef(null)
|
const pitchRef = useRef(null)
|
||||||
const shedPitchRef = useRef(null)
|
const shedPitchRef = useRef(null)
|
||||||
const jerkinHeadPitchRef = useRef(null)
|
const jerkinHeadPitchRef = useRef(null)
|
||||||
@ -87,14 +92,46 @@ export function useRoofShapeSetting(id) {
|
|||||||
closePopup(id)
|
closePopup(id)
|
||||||
return
|
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 outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
const pitchTexts = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
|
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)
|
canvas.remove(...pitchTexts)
|
||||||
outerLines.forEach((line) => {
|
outerLines.forEach((line) => {
|
||||||
let stroke, strokeWidth
|
let stroke, strokeWidth
|
||||||
@ -113,6 +150,8 @@ export function useRoofShapeSetting(id) {
|
|||||||
line.set({
|
line.set({
|
||||||
stroke,
|
stroke,
|
||||||
strokeWidth,
|
strokeWidth,
|
||||||
|
selectable: false,
|
||||||
|
visible: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
addPitchText(line)
|
addPitchText(line)
|
||||||
@ -144,10 +183,15 @@ export function useRoofShapeSetting(id) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shapeNum === 4) {
|
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')
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
outerLines.forEach((line) => {
|
outerLines.forEach((line) => {
|
||||||
showLine(line)
|
showLine(line)
|
||||||
|
line.set({ selectable: true })
|
||||||
line.bringToFront()
|
line.bringToFront()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user