지붕형상 설정 추가
This commit is contained in:
parent
3b5201a0ce
commit
325e5632c5
@ -169,8 +169,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
attributes: {
|
attributes: {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
},
|
},
|
||||||
|
parent: this,
|
||||||
direction: getDirectionByPoint(point, nextPoint),
|
direction: getDirectionByPoint(point, nextPoint),
|
||||||
idx: i,
|
idx: i + 1,
|
||||||
})
|
})
|
||||||
line.startPoint = point
|
line.startPoint = point
|
||||||
line.endPoint = nextPoint
|
line.endPoint = nextPoint
|
||||||
|
|||||||
@ -1,25 +1,73 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import Ridge from '@/components/floor-plan/modal/roofShape/type/Ridge'
|
import Ridge from '@/components/floor-plan/modal/roofShape/type/Ridge'
|
||||||
import Pattern from '@/components/floor-plan/modal/roofShape/type/Pattern'
|
import Pattern from '@/components/floor-plan/modal/roofShape/type/Pattern'
|
||||||
import Side from '@/components/floor-plan/modal/roofShape/type/Side'
|
import Side from '@/components/floor-plan/modal/roofShape/type/Side'
|
||||||
import { useState } from 'react'
|
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import Direction from '@/components/floor-plan/modal/roofShape/type/Direction'
|
import Direction from '@/components/floor-plan/modal/roofShape/type/Direction'
|
||||||
|
import { useRoofShapeSetting } from '@/hooks/roofcover/useRoofShapeSetting'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
|
||||||
export default function RoofShapeSetting({ setShowRoofShapeSettingModal }) {
|
export default function RoofShapeSetting({ setShowRoofShapeSettingModal }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const [shapeNum, setShapeNum] = useState(1)
|
const {
|
||||||
const shapeMenu = [
|
shapeNum,
|
||||||
{ id: 1, name: getMessage('modal.roof.shape.setting.ridge') }, // 용마루
|
setShapeNum,
|
||||||
{ id: 2, name: getMessage('modal.roof.shape.setting.patten.a') }, // 패턴A
|
shapeMenu,
|
||||||
{ id: 3, name: getMessage('modal.roof.shape.setting.patten.b') }, // 패턴B
|
handleSave,
|
||||||
{ id: 4, name: getMessage('modal.roof.shape.setting.side') }, // 변별로 설정
|
pitch,
|
||||||
{ id: 5, name: getMessage('commons.west') }, // 서
|
setPitch,
|
||||||
{ id: 6, name: getMessage('commons.east') }, // 서
|
eavesOffset,
|
||||||
{ id: 7, name: getMessage('commons.south') }, // 서
|
setEavesOffset,
|
||||||
{ id: 8, name: getMessage('commons.north') }, // 북
|
gableOffset,
|
||||||
]
|
setGableOffset,
|
||||||
|
sleeveOffset,
|
||||||
|
setSleeveOffset,
|
||||||
|
jerkinHeadWidth,
|
||||||
|
setJerkinHeadWidth,
|
||||||
|
jerkinHeadPitch,
|
||||||
|
setJerkinHeadPitch,
|
||||||
|
hipAndGableWidth,
|
||||||
|
setHipAndGableWidth,
|
||||||
|
shedWidth,
|
||||||
|
setShedWidth,
|
||||||
|
hasSleeve,
|
||||||
|
setHasSleeve,
|
||||||
|
buttonAct,
|
||||||
|
setButtonAct,
|
||||||
|
buttonMenu,
|
||||||
|
handleConfirm,
|
||||||
|
handleRollBack,
|
||||||
|
} = useRoofShapeSetting()
|
||||||
|
|
||||||
|
const ridgeProps = { pitch, setPitch, eavesOffset, setEavesOffset }
|
||||||
|
const patternProps = { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset }
|
||||||
|
const sideProps = {
|
||||||
|
pitch,
|
||||||
|
setPitch,
|
||||||
|
eavesOffset,
|
||||||
|
setEavesOffset,
|
||||||
|
gableOffset,
|
||||||
|
setGableOffset,
|
||||||
|
sleeveOffset,
|
||||||
|
setSleeveOffset,
|
||||||
|
jerkinHeadWidth,
|
||||||
|
setJerkinHeadWidth,
|
||||||
|
jerkinHeadPitch,
|
||||||
|
setJerkinHeadPitch,
|
||||||
|
hipAndGableWidth,
|
||||||
|
setHipAndGableWidth,
|
||||||
|
shedWidth,
|
||||||
|
setShedWidth,
|
||||||
|
hasSleeve,
|
||||||
|
setHasSleeve,
|
||||||
|
buttonAct,
|
||||||
|
setButtonAct,
|
||||||
|
buttonMenu,
|
||||||
|
handleConfirm,
|
||||||
|
handleRollBack,
|
||||||
|
}
|
||||||
|
|
||||||
|
const directionProps = { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}>
|
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}>
|
||||||
@ -43,13 +91,15 @@ export default function RoofShapeSetting({ setShowRoofShapeSettingModal }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="properties-setting-wrap">
|
<div className="properties-setting-wrap">
|
||||||
<div className="setting-tit">{getMessage('setting')}</div>
|
<div className="setting-tit">{getMessage('setting')}</div>
|
||||||
{shapeNum === 1 && <Ridge />}
|
{shapeNum === 1 && <Ridge {...ridgeProps} />}
|
||||||
{(shapeNum === 2 || shapeNum === 3) && <Pattern />}
|
{(shapeNum === 2 || shapeNum === 3) && <Pattern {...patternProps} />}
|
||||||
{shapeNum === 4 && <Side />}
|
{shapeNum === 4 && <Side {...sideProps} />}
|
||||||
{(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && <Direction />}
|
{(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && <Direction {...directionProps} />}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame modal act">{getMessage('common.setting.finish')}</button>
|
<button className="btn-frame modal act" onClick={() => handleSave(setShowRoofShapeSettingModal)}>
|
||||||
|
{getMessage('common.setting.finish')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Direction() {
|
export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
return (
|
return (
|
||||||
<div className="setting-box">
|
<div className="setting-box">
|
||||||
@ -9,7 +10,7 @@ export default function Direction() {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={4} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{getMessage('size')}</span>
|
<span className="thin">{getMessage('size')}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -18,7 +19,7 @@ export default function Direction() {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={500} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +28,7 @@ export default function Direction() {
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={300} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -36,7 +37,7 @@ export default function Direction() {
|
|||||||
{getMessage('windage.width')}
|
{getMessage('windage.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={300} />
|
<input type="text" className="input-origin block" value={shedWidth} onChange={(e) => onlyNumberInputChange(e, setShedWidth)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Pattern() {
|
export default function Pattern(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset } = props
|
||||||
return (
|
return (
|
||||||
<div className="setting-box">
|
<div className="setting-box">
|
||||||
<div className="outline-form mb10">
|
<div className="outline-form mb10">
|
||||||
@ -9,7 +11,7 @@ export default function Pattern() {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={4} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin"> {getMessage('size')}</span>
|
<span className="thin"> {getMessage('size')}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -18,7 +20,7 @@ export default function Pattern() {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={500} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +29,7 @@ export default function Pattern() {
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={300} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={setGableOffset} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,11 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Ridge() {
|
export default function Ridge(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { pitch, setPitch, eavesOffset, setEavesOffset } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="setting-box">
|
<div className="setting-box">
|
||||||
<div className="outline-form mb10">
|
<div className="outline-form mb10">
|
||||||
@ -9,7 +13,7 @@ export default function Ridge() {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={100} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{getMessage('size')}</span>
|
<span className="thin">{getMessage('size')}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -18,7 +22,7 @@ export default function Ridge() {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={100} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -7,39 +7,68 @@ import Wall from '@/components/floor-plan/modal/roofShape/type/option/Wall'
|
|||||||
import Jerkinhead from '@/components/floor-plan/modal/roofShape/type/option/Jerkinhead'
|
import Jerkinhead from '@/components/floor-plan/modal/roofShape/type/option/Jerkinhead'
|
||||||
import Shed from '@/components/floor-plan/modal/roofShape/type/option/Shed'
|
import Shed from '@/components/floor-plan/modal/roofShape/type/option/Shed'
|
||||||
|
|
||||||
export default function Side() {
|
export default function Side(props) {
|
||||||
const [buttonAct, setButtonAct] = useState(1)
|
const {
|
||||||
|
pitch,
|
||||||
|
setPitch,
|
||||||
|
eavesOffset,
|
||||||
|
setEavesOffset,
|
||||||
|
gableOffset,
|
||||||
|
setGableOffset,
|
||||||
|
sleeveOffset,
|
||||||
|
setSleeveOffset,
|
||||||
|
jerkinHeadWidth,
|
||||||
|
setJerkinHeadWidth,
|
||||||
|
jerkinHeadPitch,
|
||||||
|
setJerkinHeadPitch,
|
||||||
|
hipAndGableWidth,
|
||||||
|
setHipAndGableWidth,
|
||||||
|
shedWidth,
|
||||||
|
setShedWidth,
|
||||||
|
hasSleeve,
|
||||||
|
setHasSleeve,
|
||||||
|
buttonAct,
|
||||||
|
setButtonAct,
|
||||||
|
buttonMenu,
|
||||||
|
handleConfirm,
|
||||||
|
handleRollBack,
|
||||||
|
} = props
|
||||||
|
|
||||||
|
const eavesProps = { pitch, setPitch, eavesOffset, setEavesOffset }
|
||||||
|
const gableProps = { gableOffset, setGableOffset }
|
||||||
|
const wallProps = { sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }
|
||||||
|
const hipAndGableProps = { pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth }
|
||||||
|
const jerkinheadProps = { gableOffset, setGableOffset, jerkinHeadWidth, setJerkinHeadWidth, jerkinHeadPitch, setJerkinHeadPitch }
|
||||||
|
const shedProps = { shedWidth, setShedWidth }
|
||||||
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
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') },
|
|
||||||
]
|
|
||||||
return (
|
return (
|
||||||
<div className="setting-box">
|
<div className="setting-box">
|
||||||
<div className="discrimination-tab">
|
<div className="discrimination-tab">
|
||||||
<div className="modal-btn-wrap sub">
|
<div className="modal-btn-wrap sub">
|
||||||
{buttonMenu.map((item) => (
|
{buttonMenu.map((item, idx) => (
|
||||||
<button className={`btn-frame sub-tab ${buttonAct === item.id ? 'act' : ''}`} onClick={() => setButtonAct(item.id)}>
|
<button key={idx} className={`btn-frame sub-tab ${buttonAct === item.id ? 'act' : ''}`} onClick={() => setButtonAct(item.id)}>
|
||||||
{item.name}
|
{item.name}
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="discrimination-box">
|
<div className="discrimination-box">
|
||||||
{buttonAct === 1 && <Eaves />}
|
{buttonAct === 1 && <Eaves {...eavesProps} />}
|
||||||
{buttonAct === 2 && <Gable />}
|
{buttonAct === 2 && <Gable {...gableProps} />}
|
||||||
{buttonAct === 3 && <Wall />}
|
{buttonAct === 3 && <Wall {...wallProps} />}
|
||||||
{buttonAct === 4 && <HipAndGable />}
|
{buttonAct === 4 && <HipAndGable {...hipAndGableProps} />}
|
||||||
{buttonAct === 5 && <Jerkinhead />}
|
{buttonAct === 5 && <Jerkinhead {...jerkinheadProps} />}
|
||||||
{buttonAct === 6 && <Shed />}
|
{buttonAct === 6 && <Shed {...shedProps} />}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame sub-tab mr5">{getMessage('common.setting.rollback')}</button>
|
<button className="btn-frame sub-tab mr5" onClick={handleRollBack}>
|
||||||
<button className="btn-frame sub-tab act">{getMessage('apply')}</button>
|
{getMessage('common.setting.rollback')}
|
||||||
|
</button>
|
||||||
|
<button className="btn-frame sub-tab act" onClick={handleConfirm}>
|
||||||
|
{getMessage('apply')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Eaves() {
|
export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -9,7 +10,7 @@ export default function Eaves() {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={4} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{getMessage('size')}</span>
|
<span className="thin">{getMessage('size')}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -18,7 +19,7 @@ export default function Eaves() {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={500} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Gable() {
|
export default function Gable({ gableOffset, setGableOffset }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('gable.offset')}</span>
|
<span className="mr10">{getMessage('gable.offset')}</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={4} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function HipAndGable() {
|
export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -9,7 +10,7 @@ export default function HipAndGable() {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={4} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{getMessage('size')}</span>
|
<span className="thin">{getMessage('size')}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -18,16 +19,21 @@ export default function HipAndGable() {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={500} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10" style={{ width: '60px' }}>
|
<span className="mr10" style={{ width: '60px' }}>
|
||||||
{getMessage('gable.offset')}
|
{getMessage('hipandgable.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={300} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={hipAndGableWidth}
|
||||||
|
onChange={(e) => onlyNumberInputChange(e, setHipAndGableWidth)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Jerkinhead() {
|
export default function Jerkinhead({ gableOffset, setGableOffset, jerkinHeadWidth, setJerkinHeadWidth, jerkinHeadPitch, setJerkinHeadPitch }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -9,7 +10,7 @@ export default function Jerkinhead() {
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={300} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -18,7 +19,7 @@ export default function Jerkinhead() {
|
|||||||
{getMessage('jerkinhead.width')}
|
{getMessage('jerkinhead.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={800} />
|
<input type="text" className="input-origin block" value={jerkinHeadWidth} onChange={(e) => onlyNumberInputChange(e, setJerkinHeadWidth)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +28,12 @@ export default function Jerkinhead() {
|
|||||||
{getMessage('jerkinhead.slope')}
|
{getMessage('jerkinhead.slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={4.5} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={jerkinHeadPitch}
|
||||||
|
onChange={(e) => onlyNumberWithDotInputChange(e, setJerkinHeadPitch)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{getMessage('size')}</span>
|
<span className="thin">{getMessage('size')}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Shed() {
|
export default function Shed({ shedWidth, setShedWidth }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('shed.width')}</span>
|
<span className="mr10">{getMessage('shed.width')}</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={600} />
|
<input type="text" className="input-origin block" value={shedWidth} onChange={(e) => onlyNumberInputChange(e, setShedWidth)} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Wall() {
|
export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) {
|
||||||
const [hasSleeve, setHasSleeve] = useState('0')
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -26,7 +26,13 @@ export default function Wall() {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={300} readOnly={hasSleeve === '0'} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={sleeveOffset}
|
||||||
|
onChange={(e) => onlyNumberInputChange(e, setSleeveOffset)}
|
||||||
|
readOnly={hasSleeve === '0'}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
adsorptionPointModeState,
|
adsorptionPointModeState,
|
||||||
adsorptionRangeState,
|
adsorptionRangeState,
|
||||||
canvasState,
|
canvasState,
|
||||||
|
currentCanvasPlanState,
|
||||||
dotLineIntervalSelector,
|
dotLineIntervalSelector,
|
||||||
verticalHorizontalModeState,
|
verticalHorizontalModeState,
|
||||||
} from '@/store/canvasAtom'
|
} from '@/store/canvasAtom'
|
||||||
@ -43,7 +44,7 @@ export function useOuterLineWall() {
|
|||||||
const adsorptionPointMode = useRecoilValue(adsorptionPointModeState)
|
const adsorptionPointMode = useRecoilValue(adsorptionPointModeState)
|
||||||
const adsorptionRange = useRecoilValue(adsorptionRangeState)
|
const adsorptionRange = useRecoilValue(adsorptionRangeState)
|
||||||
const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격
|
const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격
|
||||||
|
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
|
||||||
const length1Ref = useRef(null)
|
const length1Ref = useRef(null)
|
||||||
const length2Ref = useRef(null)
|
const length2Ref = useRef(null)
|
||||||
const angle1Ref = useRef(null)
|
const angle1Ref = useRef(null)
|
||||||
@ -73,14 +74,6 @@ export function useOuterLineWall() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (points.length === 0) {
|
|
||||||
// 만약 포인트가 없다면 모든 라인과 텍스트를 삭제 후 outerLines에서 point를 뽑아 points에 넣어준다.
|
|
||||||
const lengthTxts = canvas?.getObjects().filter((obj) => obj.name === 'lengthTxt')
|
|
||||||
lengthTxts.forEach((txt) => {
|
|
||||||
canvas?.remove(txt)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||||
clear()
|
clear()
|
||||||
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
|
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
|
||||||
@ -98,6 +91,18 @@ export function useOuterLineWall() {
|
|||||||
addDocumentEventListener('keydown', document, keydown[type])
|
addDocumentEventListener('keydown', document, keydown[type])
|
||||||
}, [type])
|
}, [type])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const outerLinePoints = canvas?.getObjects().filter((obj) => obj.name === 'outerLinePoint')
|
||||||
|
const newPoints = []
|
||||||
|
if (points.length === 0 && outerLinePoints.length > 0) {
|
||||||
|
outerLinePoints.forEach((point) => {
|
||||||
|
newPoints.push({ x: point.left, y: point.top })
|
||||||
|
})
|
||||||
|
|
||||||
|
setPoints(newPoints)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const clear = () => {
|
const clear = () => {
|
||||||
setLength1(0)
|
setLength1(0)
|
||||||
setLength2(0)
|
setLength2(0)
|
||||||
@ -186,6 +191,21 @@ export function useOuterLineWall() {
|
|||||||
canvas?.add(point)
|
canvas?.add(point)
|
||||||
} else {
|
} else {
|
||||||
setOuterLineFix(false)
|
setOuterLineFix(false)
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === 'outerLinePoint')
|
||||||
|
.forEach((obj) => {
|
||||||
|
canvas.remove(obj)
|
||||||
|
})
|
||||||
|
points.forEach((point, idx) => {
|
||||||
|
const circle = new fabric.Circle({
|
||||||
|
left: point.x,
|
||||||
|
top: point.y,
|
||||||
|
visible: false,
|
||||||
|
name: 'outerLinePoint',
|
||||||
|
})
|
||||||
|
canvas.add(circle)
|
||||||
|
})
|
||||||
points.forEach((point, idx) => {
|
points.forEach((point, idx) => {
|
||||||
if (idx === 0) {
|
if (idx === 0) {
|
||||||
return
|
return
|
||||||
@ -272,6 +292,10 @@ export function useOuterLineWall() {
|
|||||||
idx: idx,
|
idx: idx,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
name: 'outerLine',
|
name: 'outerLine',
|
||||||
|
x1: point1.x,
|
||||||
|
y1: point1.y,
|
||||||
|
x2: point2.x,
|
||||||
|
y2: point2.y,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
import { LINE_TYPE } from '@/common/common'
|
import { LINE_TYPE } from '@/common/common'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useMode } from '@/hooks/useMode'
|
import { useMode } from '@/hooks/useMode'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
|
|
||||||
export function usePropertiesSetting() {
|
export function usePropertiesSetting() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -12,9 +13,10 @@ export function usePropertiesSetting() {
|
|||||||
const currentObject = useRecoilValue(currentObjectState)
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
|
|
||||||
const { drawRoofPolygon } = useMode()
|
const { drawRoofPolygon } = useMode()
|
||||||
|
const setPoints = useResetRecoilState(outerLinePointsState)
|
||||||
|
|
||||||
const { addPolygonByLines } = usePolygon()
|
const { addPolygonByLines } = usePolygon()
|
||||||
const { removeLine } = useLine()
|
const { removeLine, hideLine } = useLine()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentObject) {
|
if (!currentObject) {
|
||||||
@ -125,7 +127,8 @@ export function usePropertiesSetting() {
|
|||||||
stroke: '#000000',
|
stroke: '#000000',
|
||||||
strokeWidth: 4,
|
strokeWidth: 4,
|
||||||
})
|
})
|
||||||
removeLine(line)
|
|
||||||
|
hideLine(hideLine)
|
||||||
})
|
})
|
||||||
|
|
||||||
const wall = addPolygonByLines(lines, { name: 'WallLine', fill: 'transparent', stroke: 'black' })
|
const wall = addPolygonByLines(lines, { name: 'WallLine', fill: 'transparent', stroke: 'black' })
|
||||||
@ -133,7 +136,7 @@ export function usePropertiesSetting() {
|
|||||||
wall.lines = [...lines]
|
wall.lines = [...lines]
|
||||||
|
|
||||||
drawRoofPolygon(wall)
|
drawRoofPolygon(wall)
|
||||||
|
setPoints([])
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +156,7 @@ export function usePropertiesSetting() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
setPoints([])
|
||||||
fn(false)
|
fn(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
496
src/hooks/roofcover/useRoofShapeSetting.js
Normal file
496
src/hooks/roofcover/useRoofShapeSetting.js
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { useRecoilValue } from 'recoil'
|
||||||
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
|
import { LINE_TYPE } from '@/common/common'
|
||||||
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
|
import { useMode } from '@/hooks/useMode'
|
||||||
|
import { useLine } from '@/hooks/useLine'
|
||||||
|
|
||||||
|
export function useRoofShapeSetting() {
|
||||||
|
const [shapeNum, setShapeNum] = useState(1)
|
||||||
|
const [buttonAct, setButtonAct] = useState(1)
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const { addPolygonByLines } = usePolygon()
|
||||||
|
const [pitch, setPitch] = useState(4)
|
||||||
|
const [eavesOffset, setEavesOffset] = useState(500) // 처마출폭
|
||||||
|
const [gableOffset, setGableOffset] = useState(300) // 케라바출폭
|
||||||
|
const [sleeveOffset, setSleeveOffset] = useState(300) // 소매출폭
|
||||||
|
const [jerkinHeadWidth, setJerkinHeadWidth] = useState(800) // 반절처 폭
|
||||||
|
const [jerkinHeadPitch, setJerkinHeadPitch] = useState(4.5) // 반절처 경사
|
||||||
|
const [hipAndGableWidth, setHipAndGableWidth] = useState(800) // 팔작지붕 폭
|
||||||
|
const [shedWidth, setShedWidth] = useState(300) // 한쪽흐름 폭
|
||||||
|
const [hasSleeve, setHasSleeve] = useState('0')
|
||||||
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
|
const { drawRoofPolygon } = useMode()
|
||||||
|
const { hideLine, showLine } = useLine()
|
||||||
|
|
||||||
|
const history = useRef([])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const wallLine = canvas.getObjects().find((obj) => obj.name === 'wallLine')
|
||||||
|
canvas?.remove(wallLine)
|
||||||
|
|
||||||
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
showLine(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 === 'wallLine'))
|
||||||
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
showLine(line)
|
||||||
|
line.bringToFront()
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas?.renderAll()
|
||||||
|
}
|
||||||
|
setPitch(4)
|
||||||
|
setEavesOffset(500)
|
||||||
|
setGableOffset(300)
|
||||||
|
setSleeveOffset(300)
|
||||||
|
setJerkinHeadWidth(800)
|
||||||
|
setJerkinHeadPitch(4.5)
|
||||||
|
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 = (fn) => {
|
||||||
|
//기존 wallLine 삭제
|
||||||
|
|
||||||
|
let outerLines
|
||||||
|
canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'wallLine'))
|
||||||
|
canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'roofBase'))
|
||||||
|
|
||||||
|
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')
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
hideLine(line)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5: {
|
||||||
|
// 서쪽
|
||||||
|
initLineSetting()
|
||||||
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
setWestAndEastRoof(line)
|
||||||
|
if (line.direction === 'bottom') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.direction === 'top') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: shedWidth / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.SHED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideLine(line)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
initLineSetting()
|
||||||
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
setWestAndEastRoof(line)
|
||||||
|
if (line.direction === 'top') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.direction === 'bottom') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: shedWidth / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.SHED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideLine(line)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 7: {
|
||||||
|
initLineSetting()
|
||||||
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
setWestAndEastRoof(line)
|
||||||
|
if (line.direction === 'left') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.direction === 'right') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: shedWidth / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.SHED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideLine(line)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 8: {
|
||||||
|
initLineSetting()
|
||||||
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
setWestAndEastRoof(line)
|
||||||
|
if (line.direction === 'right') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.direction === 'left') {
|
||||||
|
line.attributes = {
|
||||||
|
offset: shedWidth / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.SHED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideLine(line)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const polygon = addPolygonByLines(outerLines, { name: 'wallLine' })
|
||||||
|
polygon.lines = [...outerLines]
|
||||||
|
|
||||||
|
drawRoofPolygon(polygon)
|
||||||
|
|
||||||
|
canvas?.renderAll()
|
||||||
|
|
||||||
|
console.log(canvas.getObjects())
|
||||||
|
|
||||||
|
fn && fn(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 첫번째 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 동, 서 선택 시 가로라인을 케라바로 설정
|
||||||
|
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: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
hideLine(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
return outerLines
|
||||||
|
}
|
||||||
|
|
||||||
|
// 패턴 A : 가로선이 모두 케라바
|
||||||
|
const saveAPattern = () => {
|
||||||
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
outerLines
|
||||||
|
.filter((line) => line.direction === 'left' || line.direction === 'right')
|
||||||
|
.forEach((line) => {
|
||||||
|
line.attributes = {
|
||||||
|
offset: gableOffset / 10,
|
||||||
|
type: LINE_TYPE.WALLLINE.GABLE,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
outerLines
|
||||||
|
.filter((line) => line.direction === 'top' || line.direction === 'bottom')
|
||||||
|
.forEach((line) => {
|
||||||
|
line.attributes = {
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return outerLines
|
||||||
|
}
|
||||||
|
|
||||||
|
// 패턴 B : 세로선이 모두 케라바
|
||||||
|
const saveBPattern = () => {
|
||||||
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
outerLines
|
||||||
|
.filter((line) => line.direction === 'left' || line.direction === 'right')
|
||||||
|
.forEach((line) => {
|
||||||
|
line.attributes = {
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
pitch: pitch,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
outerLines
|
||||||
|
.filter((line) => line.direction === 'top' || line.direction === 'bottom')
|
||||||
|
.forEach((line) => {
|
||||||
|
line.attributes = {
|
||||||
|
offset: gableOffset / 10,
|
||||||
|
type: LINE_TYPE.WALLLINE.GABLE,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return outerLines
|
||||||
|
}
|
||||||
|
|
||||||
|
// 변별로 설정 팝업 내 적용
|
||||||
|
const handleConfirm = () => {
|
||||||
|
const selectedLine = canvas?.getActiveObject()
|
||||||
|
if (!selectedLine) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let attributes
|
||||||
|
switch (buttonAct) {
|
||||||
|
case 1: {
|
||||||
|
// 처마
|
||||||
|
attributes = {
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
pitch: pitch,
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
// 케라바
|
||||||
|
attributes = {
|
||||||
|
type: LINE_TYPE.WALLLINE.GABLE,
|
||||||
|
offset: gableOffset / 10,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
// 벽
|
||||||
|
attributes = {
|
||||||
|
type: LINE_TYPE.WALLLINE.WALL,
|
||||||
|
offset: hasSleeve === '0' ? 0 : sleeveOffset / 10,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
// 팔작지붕
|
||||||
|
attributes = {
|
||||||
|
type: LINE_TYPE.WALLLINE.HIPANDGABLE,
|
||||||
|
pitch: pitch,
|
||||||
|
offset: eavesOffset / 10,
|
||||||
|
width: hipAndGableWidth / 10,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
// 반절처
|
||||||
|
attributes = {
|
||||||
|
type: LINE_TYPE.WALLLINE.JERKINHEAD,
|
||||||
|
offset: gableOffset / 10,
|
||||||
|
width: jerkinHeadWidth / 10,
|
||||||
|
pitch: jerkinHeadPitch,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
// 한쪽흐름
|
||||||
|
attributes = {
|
||||||
|
type: LINE_TYPE.WALLLINE.SHED,
|
||||||
|
offset: shedWidth / 10,
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedLine.attributes = attributes
|
||||||
|
history.current.push(selectedLine)
|
||||||
|
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]
|
||||||
|
canvas.setActiveObject(nextLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 변별로 설정 내 일변 전으로 돌아가기
|
||||||
|
const handleRollBack = () => {
|
||||||
|
if (history.current.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const lastLine = history.current.pop()
|
||||||
|
|
||||||
|
lastLine.set({
|
||||||
|
stroke: '#000000',
|
||||||
|
strokeWidth: 4,
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.setActiveObject(lastLine)
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,26 +14,38 @@ export const useLine = () => {
|
|||||||
fontFamily: fontFamily,
|
fontFamily: fontFamily,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (line.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
canvas?.add(line)
|
canvas?.add(line)
|
||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
|
|
||||||
const addLineText = (line, length = getLengthByLine(line)) => {
|
const hideLine = (line) => {
|
||||||
removeLineText(line)
|
line.set({
|
||||||
|
visible: false,
|
||||||
const lengthTxt = isNaN(Number(length)) ? length : length.toFixed(0)
|
|
||||||
|
|
||||||
const text = new fabric.Text(lengthTxt, {
|
|
||||||
left: (line.x2 + line.x1) / 2,
|
|
||||||
top: (line.y2 + line.y1) / 2,
|
|
||||||
parent: line,
|
|
||||||
name: 'lengthTxt',
|
|
||||||
fontSize: fontSize,
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
})
|
})
|
||||||
|
canvas
|
||||||
|
?.getObjects()
|
||||||
|
.find((obj) => obj.parent === line)
|
||||||
|
.set({
|
||||||
|
visible: false,
|
||||||
|
})
|
||||||
|
canvas?.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
canvas?.add(text)
|
const showLine = (line) => {
|
||||||
return text
|
line.set({
|
||||||
|
visible: true,
|
||||||
|
})
|
||||||
|
canvas
|
||||||
|
?.getObjects()
|
||||||
|
.find((obj) => obj.parent === line)
|
||||||
|
.set({
|
||||||
|
visible: true,
|
||||||
|
})
|
||||||
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeLine = (line) => {
|
const removeLine = (line) => {
|
||||||
@ -62,5 +74,7 @@ export const useLine = () => {
|
|||||||
return {
|
return {
|
||||||
addLine,
|
addLine,
|
||||||
removeLine,
|
removeLine,
|
||||||
|
hideLine,
|
||||||
|
showLine,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,11 @@ export function usePlan() {
|
|||||||
'minY',
|
'minY',
|
||||||
'x',
|
'x',
|
||||||
'y',
|
'y',
|
||||||
|
'x1',
|
||||||
|
'x2',
|
||||||
|
'y1',
|
||||||
|
'y2',
|
||||||
|
'attributes',
|
||||||
'stickeyPoint',
|
'stickeyPoint',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,8 @@ export const usePolygon = () => {
|
|||||||
const addPolygon = (points, options) => {
|
const addPolygon = (points, options) => {
|
||||||
const polygon = new QPolygon(points, {
|
const polygon = new QPolygon(points, {
|
||||||
...options,
|
...options,
|
||||||
|
fill: options.fill || 'transparent',
|
||||||
|
stroke: options.stroke || '#000000',
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
fontFamily: fontFamily,
|
fontFamily: fontFamily,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
|||||||
@ -303,6 +303,7 @@
|
|||||||
"gable": "ケラバ",
|
"gable": "ケラバ",
|
||||||
"wall": "壁",
|
"wall": "壁",
|
||||||
"hipandgable": "八作屋根",
|
"hipandgable": "八作屋根",
|
||||||
|
"hipandgable.width": "八作屋根 出幅",
|
||||||
"jerkinhead": "半折",
|
"jerkinhead": "半折",
|
||||||
"shed": "片側の流れ",
|
"shed": "片側の流れ",
|
||||||
"apply": "適用",
|
"apply": "適用",
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
"modal.roof.shape.setting": "지붕형상 설정",
|
"modal.roof.shape.setting": "지붕형상 설정",
|
||||||
"modal.roof.shape.setting.ridge": "용마루",
|
"modal.roof.shape.setting.ridge": "용마루",
|
||||||
"modal.roof.shape.setting.patten.a": "A 패턴",
|
"modal.roof.shape.setting.patten.a": "A 패턴",
|
||||||
"modal.roof.shape.setting.patten.b": "A 패턴",
|
"modal.roof.shape.setting.patten.b": "B 패턴",
|
||||||
"modal.roof.shape.setting.side": "변별로 설정",
|
"modal.roof.shape.setting.side": "변별로 설정",
|
||||||
"plan.menu.roof.cover": "지붕덮개",
|
"plan.menu.roof.cover": "지붕덮개",
|
||||||
"plan.menu.roof.cover.outline.drawing": "외벽선 그리기",
|
"plan.menu.roof.cover.outline.drawing": "외벽선 그리기",
|
||||||
@ -305,6 +305,7 @@
|
|||||||
"gable": "케라바",
|
"gable": "케라바",
|
||||||
"wall": "벽",
|
"wall": "벽",
|
||||||
"hipandgable": "팔작지붕",
|
"hipandgable": "팔작지붕",
|
||||||
|
"hipandgable.width": "팔작지붕의 폭",
|
||||||
"jerkinhead": "반절처",
|
"jerkinhead": "반절처",
|
||||||
"shed": "한쪽흐름",
|
"shed": "한쪽흐름",
|
||||||
"apply": "적용",
|
"apply": "적용",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// 숫자만 입력 가능한 input onChange 함수
|
// 숫자만 입력 가능한 input onChange 함수
|
||||||
export const onlyNumberInputChange = (e, callback) => {
|
export const onlyNumberInputChange = (e, callback) => {
|
||||||
let value = e.target.value.replace(/^0+/, '')
|
let value = e.target.value
|
||||||
value = value.replace(/[^-0-9]/g, '')
|
value = value.replace(/[^-0-9]/g, '')
|
||||||
callback(value, e)
|
callback(value, e)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1197,6 +1197,7 @@ export const drawHippedRoof = (polygon, chon) => {
|
|||||||
alert('대각선이 존재합니다.')
|
alert('대각선이 존재합니다.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
drawRidgeRoof(polygon, chon)
|
drawRidgeRoof(polygon, chon)
|
||||||
drawHips(polygon)
|
drawHips(polygon)
|
||||||
connectLinePoint(polygon)
|
connectLinePoint(polygon)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user