804 lines
25 KiB
JavaScript
804 lines
25 KiB
JavaScript
import { useEffect, useRef, useState } from 'react'
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
|
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState, pitchTextSelector } from '@/store/canvasAtom'
|
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
import { usePolygon } from '@/hooks/usePolygon'
|
|
import { useMode } from '@/hooks/useMode'
|
|
import { useLine } from '@/hooks/useLine'
|
|
import { outerLineFixState } from '@/store/outerLineAtom'
|
|
import { useSwal } from '@/hooks/useSwal'
|
|
import { usePopup } from '@/hooks/usePopup'
|
|
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
|
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
|
|
import {
|
|
addedRoofsState,
|
|
basicSettingState,
|
|
correntObjectNoState,
|
|
selectedRoofMaterialSelector,
|
|
settingModalFirstOptionsState,
|
|
} from '@/store/settingAtom'
|
|
import { useAxios } from '@/hooks/useAxios'
|
|
import { globalLocaleStore } from '@/store/localeAtom'
|
|
|
|
// 지붕형상 설정
|
|
export function useRoofShapeSetting(id) {
|
|
const [shapeNum, setShapeNum] = useState(1)
|
|
const [buttonAct, setButtonAct] = useState(1)
|
|
const { swalFire } = useSwal()
|
|
const { getMessage } = useMessage()
|
|
const canvas = useRecoilValue(canvasState)
|
|
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
|
|
const pitchText = useRecoilValue(pitchTextSelector)
|
|
const { addPolygonByLines } = usePolygon()
|
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
|
|
|
const [pitch, setPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle) // 경사
|
|
const [eavesOffset, setEavesOffset] = useState(500) // 처마출폭
|
|
const [gableOffset, setGableOffset] = useState(300) // 케라바출폭
|
|
const [sleeveOffset, setSleeveOffset] = useState(300) // 소매출폭
|
|
const [jerkinHeadWidth, setJerkinHeadWidth] = useState(800) // 반절처 폭
|
|
const [jerkinHeadPitch, setJerkinHeadPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20) // 반절처 경사
|
|
const [hipAndGableWidth, setHipAndGableWidth] = useState(800) // 팔작지붕 폭
|
|
const [shedPitch, setShedPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle) // 팔작지붕 폭
|
|
const [shedWidth, setShedWidth] = useState(300) // 한쪽흐름 폭
|
|
const [hasSleeve, setHasSleeve] = useState('0')
|
|
const currentObject = useRecoilValue(currentObjectState)
|
|
const { drawRoofPolygon } = useMode()
|
|
const { hideLine, showLine, removePitchText, addPitchText, addPitchTextsByOuterLines } = useLine()
|
|
|
|
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
|
const outerLineFix = useRecoilValue(outerLineFixState)
|
|
|
|
const isFixRef = useRef(false)
|
|
|
|
const pitchRef = useRef(null)
|
|
const shedPitchRef = useRef(null)
|
|
const jerkinHeadPitchRef = useRef(null)
|
|
|
|
const history = useRef([])
|
|
const { closePopup, addPopup } = usePopup()
|
|
|
|
const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
|
|
|
|
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
|
|
|
|
const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState)
|
|
const correntObjectNo = useRecoilValue(correntObjectNoState)
|
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
|
const { post } = useAxios(globalLocaleState)
|
|
|
|
useEffect(() => {
|
|
pitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch)
|
|
}, [pitch])
|
|
useEffect(() => {
|
|
shedPitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? shedPitch : getChonByDegree(shedPitch)
|
|
}, [shedPitch])
|
|
useEffect(() => {
|
|
jerkinHeadPitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? jerkinHeadPitch : getChonByDegree(jerkinHeadPitch)
|
|
}, [jerkinHeadPitch])
|
|
|
|
useEffect(() => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
// if (!outerLineFix || outerLines.length === 0) {
|
|
// swalFire({ text: '외벽선이 없습니다.' })
|
|
// // setShowRoofShapeSettingModal(false)
|
|
// closePopup(id)
|
|
// }
|
|
|
|
return () => {
|
|
if (!isFixRef.current) {
|
|
return
|
|
}
|
|
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
const pitchTexts = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
|
|
canvas.remove(...pitchTexts)
|
|
outerLines.forEach((line) => {
|
|
let stroke, strokeWidth
|
|
if (line.attributes) {
|
|
if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES || line.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
|
stroke = '#45CD7D'
|
|
strokeWidth = 4
|
|
} else if (line.attributes.type === LINE_TYPE.WALLLINE.GABLE || line.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
|
stroke = '#3FBAE6'
|
|
strokeWidth = 4
|
|
} else {
|
|
stroke = '#000000'
|
|
strokeWidth = 4
|
|
}
|
|
|
|
line.set({
|
|
stroke,
|
|
strokeWidth,
|
|
})
|
|
|
|
addPitchText(line)
|
|
}
|
|
})
|
|
canvas.renderAll()
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (shapeNum !== 4) {
|
|
return
|
|
}
|
|
if (!currentObject) {
|
|
return
|
|
}
|
|
if (currentObject.name !== 'outerLine') {
|
|
return
|
|
}
|
|
|
|
/*const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
outerLines.forEach((line) => {
|
|
line.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
})
|
|
})*/
|
|
|
|
currentObject.set({
|
|
stroke: '#EA10AC',
|
|
strokeWidth: 4,
|
|
})
|
|
|
|
canvas.renderAll()
|
|
}, [currentObject])
|
|
|
|
useEffect(() => {
|
|
if (shapeNum === 4) {
|
|
canvas?.remove(canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL))
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
outerLines.forEach((line) => {
|
|
showLine(line)
|
|
line.bringToFront()
|
|
})
|
|
|
|
canvas?.renderAll()
|
|
}
|
|
setEavesOffset(500)
|
|
setGableOffset(300)
|
|
setSleeveOffset(300)
|
|
setJerkinHeadWidth(800)
|
|
setHipAndGableWidth(800)
|
|
setShedWidth(300)
|
|
}, [shapeNum])
|
|
|
|
const shapeMenu = [
|
|
{ id: 1, name: getMessage('modal.roof.shape.setting.ridge') }, // 용마루
|
|
{ id: 2, name: getMessage('modal.roof.shape.setting.patten.a') }, // 패턴A
|
|
{ id: 3, name: getMessage('modal.roof.shape.setting.patten.b') }, // 패턴B
|
|
{ id: 4, name: getMessage('modal.roof.shape.setting.side') }, // 변별로 설정
|
|
{ id: 5, name: getMessage('commons.west') }, // 서
|
|
{ id: 6, name: getMessage('commons.east') }, // 동
|
|
{ id: 7, name: getMessage('commons.south') }, // 남
|
|
{ id: 8, name: getMessage('commons.north') }, // 북
|
|
]
|
|
|
|
const buttonMenu = [
|
|
{ id: 1, name: getMessage('eaves') },
|
|
{ id: 2, name: getMessage('gable') },
|
|
{ id: 3, name: getMessage('wall') },
|
|
{ id: 4, name: getMessage('hipandgable') },
|
|
{ id: 5, name: getMessage('jerkinhead') },
|
|
{ id: 6, name: getMessage('shed') },
|
|
]
|
|
|
|
const handleSave = () => {
|
|
let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.visible)
|
|
let direction
|
|
|
|
if (outerLines.length < 2) {
|
|
swalFire({ text: getMessage('wall.line.not.found') })
|
|
return
|
|
}
|
|
|
|
if ([1, 2, 3, 5, 6, 7, 8].includes(shapeNum)) {
|
|
// 변별로 설정이 아닌 경우 경사를 지붕재에 적용해주어야함
|
|
setRoofPitch()
|
|
}
|
|
|
|
switch (shapeNum) {
|
|
case 1: {
|
|
outerLines = saveRidge()
|
|
break
|
|
}
|
|
case 2: {
|
|
outerLines = saveAPattern()
|
|
break
|
|
}
|
|
case 3: {
|
|
outerLines = saveBPattern()
|
|
break
|
|
}
|
|
case 4: {
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
let isValid = outerLines.every((line) => line.attributes?.isFixed)
|
|
if (!isValid) {
|
|
swalFire({ text: getMessage('modal.canvas.setting.roofline.properties.setting.not.setting'), type: 'alert', icon: 'warning' })
|
|
return
|
|
}
|
|
const pitch = outerLines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.SHED)?.attributes.pitch
|
|
|
|
// 변별로 설정중 한쪽흐름일 경우 한쪽흐름의 pitch로 설정
|
|
if (pitch) {
|
|
outerLines.forEach((line) => {
|
|
if (line.attributes.type === LINE_TYPE.WALLLINE.SHED) {
|
|
line.attributes = {
|
|
...line.attributes,
|
|
pitch: pitchRef.current,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
break
|
|
}
|
|
|
|
case 5: {
|
|
// 서쪽
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'west'
|
|
|
|
outerLines.forEach((line) => {
|
|
setWestAndEastRoof(line)
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
case 6: {
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'east'
|
|
|
|
outerLines.forEach((line) => {
|
|
setWestAndEastRoof(line)
|
|
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
case 7: {
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'south'
|
|
|
|
outerLines.forEach((line) => {
|
|
setSouthAndNorthRoof(line)
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
case 8: {
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'north'
|
|
|
|
outerLines.forEach((line) => {
|
|
setSouthAndNorthRoof(line)
|
|
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
onlyOffset: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
}
|
|
|
|
// 기존 wallLine, roofBase 제거
|
|
canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
|
.forEach((line) => {
|
|
canvas.remove(line)
|
|
})
|
|
|
|
canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.isFixed)
|
|
.forEach((obj) => {
|
|
canvas.remove(...obj.innerLines)
|
|
canvas.remove(obj)
|
|
})
|
|
|
|
const removeTargets = canvas
|
|
.getObjects()
|
|
.filter(
|
|
(obj) =>
|
|
(obj.name === 'pitchText' || obj.name === 'lengthText') &&
|
|
canvas.getObjects().find((parent) => parent.id === obj.parentId)?.name !== POLYGON_TYPE.ROOF,
|
|
)
|
|
removeTargets.forEach((obj) => {
|
|
canvas.remove(obj)
|
|
})
|
|
|
|
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL, direction, originX: 'center', originY: 'center' })
|
|
polygon.lines = [...outerLines]
|
|
|
|
addPitchTextsByOuterLines()
|
|
const roof = drawRoofPolygon(polygon)
|
|
|
|
canvas?.renderAll()
|
|
roof.drawHelpLine(settingModalFirstOptions)
|
|
isFixRef.current = true
|
|
addPopup(id, 1, <RoofAllocationSetting id={id} pos={{ x: 50, y: 230 }} />)
|
|
}
|
|
|
|
const initLineSetting = () => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
const tempPolygon = addPolygonByLines(outerLines)
|
|
tempPolygon.lines.forEach((line) => {
|
|
outerLines.forEach((outerLine) => {
|
|
if (
|
|
(line.startPoint === outerLine.startPoint && line.endPoint === outerLine.endPoint) ||
|
|
(line.startPoint === outerLine.endPoint && line.endPoint === outerLine.startPoint)
|
|
) {
|
|
outerLine.direction = line.direction
|
|
outerLine.idx = line.idx
|
|
}
|
|
})
|
|
})
|
|
|
|
// 첫번째 line의 방향이 right일 경우
|
|
if (outerLines[0].direction === 'right') {
|
|
// top과 bottom의 방향을 바꾼다.
|
|
outerLines.forEach((line) => {
|
|
if (line.direction === 'top') {
|
|
line.direction = 'bottom'
|
|
} else if (line.direction === 'bottom') {
|
|
line.direction = 'top'
|
|
}
|
|
})
|
|
}
|
|
canvas.remove(tempPolygon)
|
|
}
|
|
|
|
// 저장된 경사를 addedRoof 첫번째요소, basicSettings의 selectedRoofMaterial에 적용
|
|
const setRoofPitch = () => {
|
|
const newAddedRoofs = addedRoofs.map((roof, index) => {
|
|
if (index === 0) {
|
|
return { ...roof, pitch: Number(pitchRef.current), angle: getDegreeByChon(pitchRef.current) }
|
|
} else {
|
|
return { ...roof }
|
|
}
|
|
})
|
|
|
|
const newBasicSetting = { ...basicSetting, selectedRoofMaterial: { ...newAddedRoofs[0] } }
|
|
|
|
try {
|
|
basicSettingSave(newAddedRoofs)
|
|
|
|
setBasicSetting(newBasicSetting)
|
|
setAddedRoofs(newAddedRoofs)
|
|
} catch (error) {
|
|
swalFire({ text: error.message, icon: 'error' })
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 지붕면 할당 저장
|
|
*/
|
|
const basicSettingSave = async (newAddedRoofs) => {
|
|
try {
|
|
const patternData = {
|
|
objectNo: correntObjectNo,
|
|
planNo: Number(basicSetting.planNo),
|
|
roofSizeSet: Number(basicSetting.roofSizeSet),
|
|
roofAngleSet: basicSetting.roofAngleSet,
|
|
roofAllocationList: newAddedRoofs.map((item, index) => ({
|
|
planNo: Number(basicSetting.planNo),
|
|
roofApply: item.selected,
|
|
roofSeq: index,
|
|
roofMatlCd: item.roofMatlCd === null || item.roofMatlCd === undefined ? 'ROOF_ID_WA_53A' : item.roofMatlCd,
|
|
roofWidth: item.width === null || item.width === undefined ? 0 : Number(item.width),
|
|
roofHeight: item.length === null || item.length === undefined ? 0 : Number(item.length),
|
|
roofHajebichi: item.hajebichi === null || item.hajebichi === undefined ? 0 : Number(item.hajebichi),
|
|
roofGap: !item.raft ? item.raftBaseCd : item.raft,
|
|
roofLayout: item.layout === null || item.layout === undefined ? 'P' : item.layout,
|
|
roofPitch: item.pitch === null || item.pitch === undefined ? 4 : Number(item.pitch),
|
|
roofAngle: item.angle === null || item.angle === undefined ? 21.8 : Number(item.angle),
|
|
})),
|
|
}
|
|
|
|
await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData })
|
|
|
|
//Recoil 설정
|
|
//setCanvasSetting({ ...basicSetting })
|
|
} catch (error) {
|
|
swalFire({ text: error.message, icon: 'error' })
|
|
}
|
|
}
|
|
|
|
// 동, 서 선택 시 가로라인을 케라바로 설정
|
|
const setWestAndEastRoof = (line) => {
|
|
if (line.direction === 'left' || line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
}
|
|
}
|
|
|
|
// 남, 북 선택 시 세로라인을 케라바로 설정
|
|
const setSouthAndNorthRoof = (line) => {
|
|
if (line.direction === 'top' || line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
}
|
|
}
|
|
|
|
const saveRidge = () => {
|
|
// 용마루 저장
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
outerLines.forEach((line) => {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch),
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
onlyOffset: false,
|
|
}
|
|
// hideLine(line)
|
|
})
|
|
|
|
return outerLines
|
|
}
|
|
|
|
// 패턴 A : 가로선이 모두 케라바
|
|
const saveAPattern = () => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
outerLines.forEach((line) => {
|
|
if (line.direction === 'left' || line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
} else if (line.direction === 'top' || line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch),
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
// hideLine(line)
|
|
})
|
|
|
|
return outerLines
|
|
}
|
|
|
|
// 패턴 B : 세로선이 모두 케라바
|
|
const saveBPattern = () => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
outerLines.forEach((line) => {
|
|
if (line.direction === 'top' || line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
} else if (line.direction === 'left' || line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch),
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
// hideLine(line)
|
|
})
|
|
|
|
return outerLines
|
|
}
|
|
|
|
// 변별로 설정 팝업 내 적용
|
|
const handleConfirm = () => {
|
|
const selectedLine = canvas?.getActiveObject()
|
|
if (!selectedLine) {
|
|
return
|
|
}
|
|
|
|
let attributes
|
|
switch (buttonAct) {
|
|
case 1: {
|
|
// 처마
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
pitch: pitchRef.current,
|
|
offset: eavesOffset / 10,
|
|
}
|
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#45CD7D' })
|
|
break
|
|
}
|
|
case 2: {
|
|
// 케라바
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
offset: gableOffset / 10,
|
|
}
|
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#3FBAE6' })
|
|
break
|
|
}
|
|
case 3: {
|
|
// 벽
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.WALL,
|
|
width: hasSleeve === '0' ? 0 : sleeveOffset / 10,
|
|
sleeve: hasSleeve === '1',
|
|
}
|
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
|
break
|
|
}
|
|
case 4: {
|
|
// 팔작지붕
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.HIPANDGABLE,
|
|
pitch: pitchRef.current,
|
|
offset: eavesOffset / 10,
|
|
width: hipAndGableWidth / 10,
|
|
}
|
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#45CD7D' })
|
|
break
|
|
}
|
|
case 5: {
|
|
// 반절처
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.JERKINHEAD,
|
|
offset: gableOffset / 10,
|
|
width: jerkinHeadWidth / 10,
|
|
pitch: jerkinHeadPitchRef.current,
|
|
}
|
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#3FBAE6' })
|
|
break
|
|
}
|
|
case 6: {
|
|
// 한쪽흐름
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
pitch: shedPitchRef.current,
|
|
width: shedWidth / 10,
|
|
}
|
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#000000' })
|
|
break
|
|
}
|
|
}
|
|
|
|
canvas.renderAll()
|
|
nextLineFocus(selectedLine)
|
|
}
|
|
|
|
const nextLineFocus = (selectedLine) => {
|
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
const index = lines.findIndex((line) => line.idx === selectedLine.idx)
|
|
|
|
const nextLine = lines[index + 1] || lines[0]
|
|
history.current.push(selectedLine)
|
|
if (nextLine.attributes?.isFixed) {
|
|
canvas.discardActiveObject()
|
|
return
|
|
}
|
|
|
|
canvas.setActiveObject(nextLine)
|
|
}
|
|
|
|
// 변별로 설정 내 일변 전으로 돌아가기
|
|
const handleRollBack = () => {
|
|
if (history.current.length === 0) {
|
|
canvas.discardActiveObject()
|
|
return
|
|
}
|
|
const lastLine = history.current.pop()
|
|
canvas.setActiveObject(lastLine)
|
|
|
|
currentObject?.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
attributes: { isFixed: false },
|
|
})
|
|
|
|
lastLine.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
attributes: { isFixed: false },
|
|
})
|
|
|
|
canvas.renderAll()
|
|
}
|
|
|
|
return {
|
|
shapeNum,
|
|
setShapeNum,
|
|
shapeMenu,
|
|
handleSave,
|
|
buttonMenu,
|
|
pitch,
|
|
setPitch,
|
|
eavesOffset,
|
|
setEavesOffset,
|
|
gableOffset,
|
|
setGableOffset,
|
|
sleeveOffset,
|
|
setSleeveOffset,
|
|
jerkinHeadWidth,
|
|
setJerkinHeadWidth,
|
|
jerkinHeadPitch,
|
|
setJerkinHeadPitch,
|
|
hipAndGableWidth,
|
|
setHipAndGableWidth,
|
|
shedWidth,
|
|
setShedWidth,
|
|
hasSleeve,
|
|
setHasSleeve,
|
|
buttonAct,
|
|
setButtonAct,
|
|
handleConfirm,
|
|
handleRollBack,
|
|
pitchText,
|
|
shedPitch,
|
|
setShedPitch,
|
|
}
|
|
}
|