Merge branch 'dev' into dev-ds
This commit is contained in:
commit
ee91d65c85
@ -53,8 +53,9 @@ export const Mode = {
|
||||
export const LINE_TYPE = {
|
||||
WALLLINE: {
|
||||
/**
|
||||
* 처마 / 캐라바 / 벽 / 팔작지붕 / 반절처 / 한쪽흐름
|
||||
* 없음 / 처마 / 캐라바 / 벽 / 팔작지붕 / 반절처 / 한쪽흐름
|
||||
*/
|
||||
DEFAULT: 'default',
|
||||
EAVES: 'eaves',
|
||||
GABLE: 'gable',
|
||||
WALL: 'wall',
|
||||
|
||||
@ -34,6 +34,7 @@ export default function FloorPlan() {
|
||||
|
||||
const outlineProps = {
|
||||
setShowOutlineModal,
|
||||
setShowPropertiesSettingModal,
|
||||
}
|
||||
|
||||
const modalProps = {
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import Image from 'next/image'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||
|
||||
export default function Angle() {
|
||||
export default function Angle({ props }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { angle1, setAngle1, angle1Ref, length1, setLength1, length1Ref } = props
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="outline-wrap">
|
||||
@ -11,16 +14,40 @@ export default function Angle() {
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={4} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={angle1}
|
||||
ref={angle1Ref}
|
||||
onChange={(e) => onlyNumberWithDotInputChange(e, setAngle1)}
|
||||
placeholder="45"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={(e) => {
|
||||
setAngle1(0)
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.arrow')}</span>
|
||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={5000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setLength1(0)
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="cul-box">
|
||||
|
||||
@ -1,7 +1,24 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||
|
||||
export default function Diagonal() {
|
||||
export default function Diagonal({ props }) {
|
||||
const { getMessage } = useMessage()
|
||||
|
||||
const {
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
length2,
|
||||
setLength2,
|
||||
length2Ref,
|
||||
outerLineDiagonalLength,
|
||||
setOuterLineDiagonalLength,
|
||||
outerLineDiagonalLengthRef,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
arrow2,
|
||||
setArrow2,
|
||||
} = props
|
||||
return (
|
||||
<>
|
||||
<div className="outline-wrap">
|
||||
@ -13,26 +30,77 @@ export default function Diagonal() {
|
||||
{getMessage('modal.cover.outline.length')}
|
||||
</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={1000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={outerLineDiagonalLength}
|
||||
ref={outerLineDiagonalLengthRef}
|
||||
onChange={(e) => onlyNumberInputChange(e, setOuterLineDiagonalLength)}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setOuterLineDiagonalLength(0)
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="outline-inner">
|
||||
<div className="outline-form">
|
||||
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={5000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setLength1(0)
|
||||
setLength2(0)
|
||||
setArrow1('')
|
||||
setArrow2('')
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span> {getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className="direction up"></button>
|
||||
<button className="direction down act"></button>
|
||||
<button className="direction left"></button>
|
||||
<button className="direction right"></button>
|
||||
<button
|
||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -40,16 +108,48 @@ export default function Diagonal() {
|
||||
<div className="outline-form">
|
||||
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '98px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={8000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length2}
|
||||
ref={length2Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength2)}
|
||||
readOnly={true}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span> {getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className="direction up"></button>
|
||||
<button className="direction down act"></button>
|
||||
<button className="direction left"></button>
|
||||
<button className="direction right"></button>
|
||||
<button
|
||||
className={`direction up ${arrow2 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow2 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow2 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow2 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,48 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
||||
import { getDegreeByChon } from '@/util/canvas-util'
|
||||
|
||||
export default function DoublePitch() {
|
||||
export default function DoublePitch({ props }) {
|
||||
const { getMessage } = useMessage()
|
||||
const {
|
||||
angle1,
|
||||
setAngle1,
|
||||
angle1Ref,
|
||||
angle2,
|
||||
setAngle2,
|
||||
angle2Ref,
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
length2,
|
||||
setLength2,
|
||||
length2Ref,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
arrow2,
|
||||
setArrow2,
|
||||
arrow1Ref,
|
||||
arrow2Ref,
|
||||
} = props
|
||||
|
||||
const getLength2 = () => {
|
||||
const angle1Value = angle1Ref.current.value
|
||||
const angle2Value = angle2Ref.current.value
|
||||
const length1Value = length1Ref.current.value
|
||||
|
||||
const arrow1Value = arrow1Ref.current
|
||||
const arrow2Value = arrow2Ref.current
|
||||
|
||||
if (angle1Value !== 0 && length1Value !== 0 && angle2Value !== 0 && arrow1Value !== '') {
|
||||
const radian1 = (getDegreeByChon(angle1Value) * Math.PI) / 180
|
||||
|
||||
const radian2 = (getDegreeByChon(angle2Value) * Math.PI) / 180
|
||||
return Math.floor((Math.tan(radian1) * length1Value) / Math.tan(radian2))
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="outline-wrap">
|
||||
@ -9,26 +50,70 @@ export default function DoublePitch() {
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={4} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={angle1}
|
||||
ref={angle1Ref}
|
||||
onChange={(e) => onlyNumberWithDotInputChange(e, setAngle1)}
|
||||
placeholder="45"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button className="reset-btn" onClick={() => setAngle1(0)}></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="outline-inner">
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={5000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setLength1(0)
|
||||
setArrow1('')
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className="direction up"></button>
|
||||
<button className="direction down act"></button>
|
||||
<button className="direction left"></button>
|
||||
<button className="direction right"></button>
|
||||
<button
|
||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -38,26 +123,80 @@ export default function DoublePitch() {
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={6} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={angle2}
|
||||
ref={angle2Ref}
|
||||
onChange={(e) => {
|
||||
onlyNumberWithDotInputChange(e, setAngle2)
|
||||
console.log(getLength2())
|
||||
setLength2(getLength2())
|
||||
}}
|
||||
placeholder="45"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setAngle2(0)
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="outline-inner">
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={3000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length2}
|
||||
ref={length2Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength2)}
|
||||
readOnly={true}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setLength2(0)
|
||||
setArrow2('')
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className="direction up"></button>
|
||||
<button className="direction down act"></button>
|
||||
<button className="direction left"></button>
|
||||
<button className="direction right"></button>
|
||||
<button
|
||||
className={`direction up ${arrow2 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow2 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow2 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow2 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall'
|
||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||
|
||||
export default function OuterLineWall(props) {
|
||||
export default function OuterLineWall({ props }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { length1, setLength1, length1Ref, arrow1, setArrow1 } = useOuterLineWall()
|
||||
|
||||
const { length1, setLength1, length1Ref, arrow1, setArrow1 } = props
|
||||
return (
|
||||
<div className="outline-wrap">
|
||||
<div className="outline-inner">
|
||||
@ -22,15 +22,39 @@ export default function OuterLineWall(props) {
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button className="reset-btn" onClick={() => setLength1(0)}></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className={`direction up ${arrow1 === '↑' ? 'act' : ''}`} onClick={() => setArrow1('↑')}></button>
|
||||
<button className={`direction down ${arrow1 === '↓' ? 'act' : ''}`} onClick={() => setArrow1('↓')}></button>
|
||||
<button className={`direction left ${arrow1 === '←' ? 'act' : ''}`} onClick={() => setArrow1('←')}></button>
|
||||
<button className={`direction right ${arrow1 === '→' ? 'act' : ''}`} onClick={() => setArrow1('→')}></button>
|
||||
<button
|
||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
|
||||
export default function PropertiesSetting(props) {
|
||||
const { getMessage } = useMessage()
|
||||
const { setShowPropertiesSettingModal } = props
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true}>
|
||||
<div className={`modal-pop-wrap ssm`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage('modal.canvas.setting.wallline.properties.setting')}</h1>
|
||||
<button className="modal-close" onClick={() => setShowPropertiesSettingModal(false)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="properties-guide">{getMessage('modal.canvas.setting.wallline.properties.setting.info')}</div>
|
||||
<div className="properties-setting-wrap">
|
||||
<div className="setting-tit">{getMessage('setting')}</div>
|
||||
<div className="setting-btn-wrap">
|
||||
<button className="setting-btn green mr5">{getMessage('modal.canvas.setting.wallline.properties.setting.eaves')}</button>
|
||||
<button className="setting-btn blue">{getMessage('modal.canvas.setting.wallline.properties.setting.edge')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal mr5">{getMessage('modal.cover.outline.rollback')}</button>
|
||||
<button className="btn-frame modal act">{getMessage('modal.cover.outline.finish')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
)
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { usePropertiesSetting } from '@/hooks/roofcover/usePropertiesSetting'
|
||||
|
||||
export default function PropertiesSetting(props) {
|
||||
const { getMessage } = useMessage()
|
||||
const { setShowPropertiesSettingModal } = props
|
||||
|
||||
const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting()
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true}>
|
||||
<div className={`modal-pop-wrap ssm`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage('modal.canvas.setting.wallline.properties.setting')}</h1>
|
||||
<button
|
||||
className="modal-close"
|
||||
onClick={() => {
|
||||
closeModal(setShowPropertiesSettingModal)
|
||||
}}
|
||||
>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="properties-guide">{getMessage('modal.canvas.setting.wallline.properties.setting.info')}</div>
|
||||
<div className="properties-setting-wrap">
|
||||
<div className="setting-tit">{getMessage('setting')}</div>
|
||||
<div className="setting-btn-wrap">
|
||||
<button className="setting-btn green mr5" onClick={handleSetEaves}>
|
||||
{getMessage('modal.canvas.setting.wallline.properties.setting.eaves')}
|
||||
</button>
|
||||
<button className="setting-btn blue" onClick={handleSetGable}>
|
||||
{getMessage('modal.canvas.setting.wallline.properties.setting.edge')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal mr5" onClick={handleRollback}>
|
||||
{getMessage('modal.cover.outline.rollback')}
|
||||
</button>
|
||||
<button
|
||||
className="btn-frame modal act"
|
||||
onClick={() => {
|
||||
handleFix()
|
||||
setShowPropertiesSettingModal(false)
|
||||
}}
|
||||
>
|
||||
{getMessage('modal.cover.outline.finish')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
)
|
||||
}
|
||||
@ -1,24 +1,63 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||
|
||||
export default function RightAngle() {
|
||||
export default function RightAngle({ props }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { length1, setLength1, length1Ref, length2, setLength2, length2Ref, arrow1, setArrow1, arrow2, setArrow2 } = props
|
||||
return (
|
||||
<div className="outline-wrap">
|
||||
<div className="outline-inner">
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={1000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setLength1(0)
|
||||
setArrow1('')
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className="direction up"></button>
|
||||
<button className="direction down act"></button>
|
||||
<button className="direction left"></button>
|
||||
<button className="direction right"></button>
|
||||
<button
|
||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow1('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -26,17 +65,53 @@ export default function RightAngle() {
|
||||
<div className="outline-form">
|
||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={1000} />
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={length2}
|
||||
ref={length2Ref}
|
||||
onChange={(e) => onlyNumberInputChange(e, setLength2)}
|
||||
placeholder="3000"
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn"></button>
|
||||
<button
|
||||
className="reset-btn"
|
||||
onClick={() => {
|
||||
setLength2(0)
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.cover.outline.arrow')}</span>
|
||||
<div className="grid-direction">
|
||||
<button className="direction up"></button>
|
||||
<button className="direction down act"></button>
|
||||
<button className="direction left"></button>
|
||||
<button className="direction right"></button>
|
||||
<button
|
||||
className={`direction up ${arrow2 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow2 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow2 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow2 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setArrow2('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -11,9 +11,102 @@ import DoublePitch from '@/components/floor-plan/modal/outerlinesetting/DoublePi
|
||||
import Diagonal from '@/components/floor-plan/modal/outerlinesetting/Diagonal'
|
||||
|
||||
export default function WallLineSetting(props) {
|
||||
const { setShowOutlineModal } = props
|
||||
const { setShowOutlineModal, setShowPropertiesSettingModal } = props
|
||||
const { getMessage } = useMessage()
|
||||
const { type, setType, handleFix, handleRollback } = useOuterLineWall()
|
||||
const {
|
||||
length1,
|
||||
setLength1,
|
||||
length2,
|
||||
setLength2,
|
||||
length1Ref,
|
||||
length2Ref,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
arrow2,
|
||||
setArrow2,
|
||||
angle1,
|
||||
setAngle1,
|
||||
angle1Ref,
|
||||
angle2,
|
||||
setAngle2,
|
||||
angle2Ref,
|
||||
type,
|
||||
setType,
|
||||
arrow1Ref,
|
||||
arrow2Ref,
|
||||
outerLineDiagonalLength,
|
||||
setOuterLineDiagonalLength,
|
||||
outerLineDiagonalLengthRef,
|
||||
handleRollback,
|
||||
handleFix,
|
||||
} = useOuterLineWall()
|
||||
|
||||
const outerLineProps = {
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
}
|
||||
|
||||
const rightAngleProps = {
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
length2,
|
||||
setLength2,
|
||||
length2Ref,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
arrow2,
|
||||
setArrow2,
|
||||
}
|
||||
|
||||
const doublePitchProps = {
|
||||
angle1,
|
||||
setAngle1,
|
||||
angle1Ref,
|
||||
angle2,
|
||||
setAngle2,
|
||||
angle2Ref,
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
length2,
|
||||
setLength2,
|
||||
length2Ref,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
arrow2,
|
||||
setArrow2,
|
||||
arrow1Ref,
|
||||
arrow2Ref,
|
||||
}
|
||||
|
||||
const angleProps = {
|
||||
angle1,
|
||||
setAngle1,
|
||||
angle1Ref,
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
}
|
||||
|
||||
const diagonalLineProps = {
|
||||
length1,
|
||||
setLength1,
|
||||
length1Ref,
|
||||
length2,
|
||||
setLength2,
|
||||
length2Ref,
|
||||
outerLineDiagonalLength,
|
||||
setOuterLineDiagonalLength,
|
||||
outerLineDiagonalLengthRef,
|
||||
arrow1,
|
||||
setArrow1,
|
||||
arrow2,
|
||||
setArrow2,
|
||||
}
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: -1390, y: 30 }}>
|
||||
@ -58,15 +151,15 @@ export default function WallLineSetting(props) {
|
||||
<div className="properties-setting-wrap outer">
|
||||
<div className="setting-tit">{getMessage('modal.cover.outline.setting')}</div>
|
||||
{type === OUTER_LINE_TYPE.OUTER_LINE ? (
|
||||
<OuterLineWall />
|
||||
<OuterLineWall props={outerLineProps} />
|
||||
) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? (
|
||||
<RightAngle />
|
||||
<RightAngle props={rightAngleProps} />
|
||||
) : type === OUTER_LINE_TYPE.DOUBLE_PITCH ? (
|
||||
<DoublePitch />
|
||||
<DoublePitch props={doublePitchProps} />
|
||||
) : type === OUTER_LINE_TYPE.ANGLE ? (
|
||||
<Angle />
|
||||
<Angle props={angleProps} />
|
||||
) : type === OUTER_LINE_TYPE.DIAGONAL_LINE ? (
|
||||
<Diagonal />
|
||||
<Diagonal props={diagonalLineProps} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
@ -75,7 +168,13 @@ export default function WallLineSetting(props) {
|
||||
<button className="btn-frame modal mr5" onClick={handleRollback}>
|
||||
{getMessage('modal.cover.outline.rollback')}
|
||||
</button>
|
||||
<button className="btn-frame modal act" onClick={handleFix}>
|
||||
<button
|
||||
className="btn-frame modal act"
|
||||
onClick={() => {
|
||||
handleFix(setShowOutlineModal)
|
||||
setShowPropertiesSettingModal(true)
|
||||
}}
|
||||
>
|
||||
{getMessage('modal.cover.outline.fix')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { distanceBetweenPoints } from '@/util/canvas-util'
|
||||
import { distanceBetweenPoints, getDegreeByChon } from '@/util/canvas-util'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import {
|
||||
adsorptionPointAddModeState,
|
||||
@ -16,14 +16,17 @@ import { useTempGrid } from '@/hooks/useTempGrid'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import {
|
||||
outerLineAngle1State,
|
||||
outerLineAngle2State,
|
||||
outerLineArrow1State,
|
||||
outerLineArrow2State,
|
||||
outerLineDiagonalState,
|
||||
outerLineLength1State,
|
||||
outerLineLength2State,
|
||||
outerLinePointsState,
|
||||
outerLineTypeState,
|
||||
} from '@/store/outerLineAtom'
|
||||
import { calculateAngle } from '@/util/qpolygon-utils'
|
||||
import { fabric } from 'fabric'
|
||||
|
||||
export function useOuterLineWall() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
@ -33,6 +36,7 @@ export function useOuterLineWall() {
|
||||
const { addLine, removeLine } = useLine()
|
||||
const { tempGridMode } = useTempGrid()
|
||||
const { addPolygonByLines } = usePolygon()
|
||||
|
||||
const verticalHorizontalMode = useRecoilValue(verticalHorizontalModeState)
|
||||
const adsorptionPointAddMode = useRecoilValue(adsorptionPointAddModeState)
|
||||
const adsorptionPointMode = useRecoilValue(adsorptionPointModeState)
|
||||
@ -42,28 +46,31 @@ export function useOuterLineWall() {
|
||||
const length1Ref = useRef(null)
|
||||
const length2Ref = useRef(null)
|
||||
const angle1Ref = useRef(null)
|
||||
const angle2Ref = useRef(null)
|
||||
const [length1, setLength1] = useRecoilState(outerLineLength1State)
|
||||
const [length2, setLength2] = useRecoilState(outerLineLength2State)
|
||||
const [arrow1, setArrow1] = useRecoilState(outerLineArrow1State)
|
||||
const [arrow2, setArrow2] = useRecoilState(outerLineArrow2State)
|
||||
const [points, setPoints] = useRecoilState(outerLinePointsState)
|
||||
const [type, setType] = useRecoilState(outerLineTypeState)
|
||||
const [angle1, setAngle1] = useRecoilState(outerLineAngle1State)
|
||||
const [angle2, setAngle2] = useRecoilState(outerLineAngle2State)
|
||||
const [outerLineDiagonalLength, setOuterLineDiagonalLength] = useRecoilState(outerLineDiagonalState)
|
||||
const arrow1Ref = useRef(arrow1)
|
||||
const arrow2Ref = useRef(arrow2)
|
||||
|
||||
const outerLineDiagonalLengthRef = useRef(null)
|
||||
|
||||
const isFix = useRef(false)
|
||||
|
||||
const [angle1, setAngle1] = useRecoilState(outerLineAngle1State)
|
||||
const closeModalFn = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (adsorptionPointAddMode || tempGridMode) {
|
||||
return
|
||||
}
|
||||
removeMouseEvent('mouse:down', mouseDown)
|
||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||
clear()
|
||||
return () => {
|
||||
removeAllMouseEventListeners()
|
||||
}
|
||||
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
|
||||
|
||||
useEffect(() => {
|
||||
@ -75,9 +82,8 @@ export function useOuterLineWall() {
|
||||
}, [arrow2])
|
||||
|
||||
useEffect(() => {
|
||||
removeAllDocumentEventListeners()
|
||||
addDocumentEventListener('keydown', document, keydown[type])
|
||||
clear()
|
||||
addDocumentEventListener('keydown', document, keydown[type])
|
||||
}, [type])
|
||||
|
||||
const clear = () => {
|
||||
@ -88,6 +94,9 @@ export function useOuterLineWall() {
|
||||
setArrow2('')
|
||||
|
||||
setAngle1(0)
|
||||
setAngle2(0)
|
||||
|
||||
setOuterLineDiagonalLength(0)
|
||||
}
|
||||
|
||||
const mouseDown = (e) => {
|
||||
@ -143,14 +152,13 @@ export function useOuterLineWall() {
|
||||
|
||||
canvas?.remove(canvas?.getObjects().find((obj) => obj.name === 'startPoint'))
|
||||
|
||||
// point가 변경 될때마다 이벤트 리스너를 제거하고 다시 등록
|
||||
removeAllDocumentEventListeners()
|
||||
addDocumentEventListener('keydown', document, keydown[type])
|
||||
|
||||
if (points.length === 0) {
|
||||
removeAllDocumentEventListeners()
|
||||
return
|
||||
}
|
||||
|
||||
addDocumentEventListener('keydown', document, keydown[type])
|
||||
|
||||
if (points.length === 1) {
|
||||
const point = new fabric.Circle({
|
||||
radius: 5,
|
||||
@ -174,6 +182,13 @@ export function useOuterLineWall() {
|
||||
const lastPoint = points[points.length - 1]
|
||||
const firstPoint = points[0]
|
||||
|
||||
if (isFix.current) {
|
||||
canvas?.renderAll()
|
||||
closeModalFn.current(false)
|
||||
removeAllMouseEventListeners()
|
||||
removeAllDocumentEventListeners()
|
||||
}
|
||||
|
||||
if (points.length < 3) {
|
||||
return
|
||||
}
|
||||
@ -241,7 +256,7 @@ export function useOuterLineWall() {
|
||||
stroke: 'black',
|
||||
strokeWidth: 3,
|
||||
idx: idx,
|
||||
selectable: false,
|
||||
selectable: true,
|
||||
name: 'outerLine',
|
||||
})
|
||||
}
|
||||
@ -261,7 +276,26 @@ export function useOuterLineWall() {
|
||||
}
|
||||
|
||||
// 직각 완료될 경우 확인
|
||||
const checkRightAngle = () => {
|
||||
const checkRightAngle = (direction) => {
|
||||
const activeElem = document.activeElement
|
||||
|
||||
const canDirection =
|
||||
direction === '↓' || direction === '↑'
|
||||
? arrow1Ref.current === '←' || arrow1Ref.current === '→'
|
||||
: arrow1Ref.current === '↓' || arrow1Ref.current === '↑'
|
||||
|
||||
if (activeElem === length1Ref.current || activeElem === angle1Ref.current) {
|
||||
setArrow1(direction)
|
||||
arrow1Ref.current = direction
|
||||
length2Ref.current.focus()
|
||||
} else if (activeElem === length2Ref.current || activeElem === angle2Ref.current) {
|
||||
if (!canDirection) {
|
||||
return
|
||||
}
|
||||
setArrow2(direction)
|
||||
arrow2Ref.current = direction
|
||||
}
|
||||
|
||||
const length1Num = Number(length1Ref.current.value) / 10
|
||||
const length2Num = Number(length2Ref.current.value) / 10
|
||||
|
||||
@ -332,6 +366,191 @@ export function useOuterLineWall() {
|
||||
}
|
||||
}
|
||||
|
||||
//이구배 완료될 경우 확인 ↓, ↑, ←, →
|
||||
const checkDoublePitch = (direction) => {
|
||||
const activeElem = document.activeElement
|
||||
|
||||
const canDirection =
|
||||
direction === '↓' || direction === '↑'
|
||||
? arrow1Ref.current === '←' || arrow1Ref.current === '→'
|
||||
: arrow1Ref.current === '↓' || arrow1Ref.current === '↑'
|
||||
|
||||
if (activeElem === length1Ref.current || activeElem === angle1Ref.current) {
|
||||
setArrow1(direction)
|
||||
arrow1Ref.current = direction
|
||||
angle2Ref.current.focus()
|
||||
} else if (activeElem === length2Ref.current || activeElem === angle2Ref.current) {
|
||||
if (!canDirection) {
|
||||
return
|
||||
}
|
||||
setArrow2(direction)
|
||||
arrow2Ref.current = direction
|
||||
}
|
||||
|
||||
const angle1Value = angle1Ref.current.value
|
||||
const angle2Value = angle2Ref.current.value
|
||||
const length1Value = length1Ref.current.value
|
||||
const length2Value = length2Ref.current.value
|
||||
|
||||
const arrow1Value = arrow1Ref.current
|
||||
const arrow2Value = arrow2Ref.current
|
||||
|
||||
if (angle1Value !== 0 && length1Value !== 0 && angle2Value !== 0 && arrow1Value !== '' && arrow2Value !== '') {
|
||||
if (arrow1Value === '↓' && arrow2Value === '→') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length1Value / 10, y: prev[prev.length - 1].y + length2Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '↓' && arrow2Value === '←') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x - length1Value / 10, y: prev[prev.length - 1].y + length2Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '↑' && arrow2Value === '→') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length1Value / 10, y: prev[prev.length - 1].y - length2Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '↑' && arrow2Value === '←') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x - length1Value / 10, y: prev[prev.length - 1].y - length2Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '→' && arrow2Value === '↓') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length2Value / 10, y: prev[prev.length - 1].y + length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '→' && arrow2Value === '↑') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length2Value / 10, y: prev[prev.length - 1].y - length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '←' && arrow2Value === '↓') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x - length2Value / 10, y: prev[prev.length - 1].y + length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '←' && arrow2Value === '↑') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x - length2Value / 10, y: prev[prev.length - 1].y - length1Value / 10 }]
|
||||
})
|
||||
}
|
||||
|
||||
angle1Ref.current.focus()
|
||||
}
|
||||
}
|
||||
|
||||
//대각선 완료될 경우 확인
|
||||
const checkDiagonal = (direction) => {
|
||||
const activeElem = document.activeElement
|
||||
|
||||
const canDirection =
|
||||
direction === '↓' || direction === '↑'
|
||||
? arrow1Ref.current === '←' || arrow1Ref.current === '→'
|
||||
: arrow1Ref.current === '↓' || arrow1Ref.current === '↑'
|
||||
|
||||
if (activeElem === length1Ref.current) {
|
||||
setArrow1(direction)
|
||||
arrow1Ref.current = direction
|
||||
} else if (activeElem === length2Ref.current || activeElem === angle2Ref.current) {
|
||||
if (!canDirection) {
|
||||
return
|
||||
}
|
||||
setArrow2(direction)
|
||||
arrow2Ref.current = direction
|
||||
}
|
||||
|
||||
const diagonalLength = outerLineDiagonalLengthRef.current.value // 대각선 길이
|
||||
|
||||
const length1Value = length1Ref.current.value
|
||||
|
||||
const arrow1Value = arrow1Ref.current
|
||||
const arrow2Value = arrow2Ref.current
|
||||
|
||||
const getLength2 = () => {
|
||||
return Math.floor(Math.sqrt(diagonalLength ** 2 - length1Value ** 2))
|
||||
}
|
||||
|
||||
const length2Value = getLength2()
|
||||
|
||||
console.log(length2Value)
|
||||
|
||||
if (diagonalLength !== 0 && length1Value !== 0 && arrow1Value !== '') {
|
||||
setLength2(getLength2())
|
||||
length2Ref.current.focus()
|
||||
}
|
||||
|
||||
if (length1Value !== 0 && length2Value !== 0 && arrow1Value !== '' && arrow2Value !== '') {
|
||||
if (arrow1Value === '↓' && arrow2Value === '→') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length2Value / 10, y: prev[prev.length - 1].y + length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '↓' && arrow2Value === '←') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x - length2Value / 10, y: prev[prev.length - 1].y + length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '↑' && arrow2Value === '→') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length2Value / 10, y: prev[prev.length - 1].y - length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '↑' && arrow2Value === '←') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x - length2Value / 10, y: prev[prev.length - 1].y - length1Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '→' && arrow2Value === '↓') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [...prev, { x: prev[prev.length - 1].x + length1Value / 10, y: prev[prev.length - 1].y + length2Value / 10 }]
|
||||
})
|
||||
} else if (arrow1Value === '→' && arrow2Value === '↑') {
|
||||
setPoints((prev) => {
|
||||
if (prev.length === 0) {
|
||||
return []
|
||||
}
|
||||
return [
|
||||
...prev,
|
||||
{
|
||||
x: prev[prev.length - 1].x + length1Value / 10,
|
||||
y: prev[prev.length - 1].y - length2Value / 10,
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const keydown = {
|
||||
outerLine: (e) => {
|
||||
if (points.length === 0) {
|
||||
@ -411,75 +630,52 @@ export function useOuterLineWall() {
|
||||
switch (key) {
|
||||
case 'Down': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowDown': {
|
||||
if (activeElem === length1Ref.current) {
|
||||
setArrow1('↓')
|
||||
arrow1Ref.current = '↓'
|
||||
length2Ref.current.focus()
|
||||
} else if (activeElem === length2Ref.current) {
|
||||
if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') {
|
||||
break
|
||||
}
|
||||
setArrow2('↓')
|
||||
arrow2Ref.current = '↓'
|
||||
checkRightAngle()
|
||||
}
|
||||
|
||||
checkRightAngle('↓')
|
||||
break
|
||||
}
|
||||
case 'Up': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowUp':
|
||||
if (activeElem === length1Ref.current) {
|
||||
setArrow1('↑')
|
||||
arrow1Ref.current = '↑'
|
||||
length2Ref.current.focus()
|
||||
} else if (activeElem === length2Ref.current) {
|
||||
if (arrow1Ref.current === '↓' || arrow1Ref.current === '↑') {
|
||||
break
|
||||
}
|
||||
setArrow2('↑')
|
||||
arrow2Ref.current = '↑'
|
||||
checkRightAngle()
|
||||
}
|
||||
|
||||
checkRightAngle('↑')
|
||||
break
|
||||
case 'Left': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowLeft':
|
||||
if (activeElem === length1Ref.current) {
|
||||
setArrow1('←')
|
||||
arrow1Ref.current = '←'
|
||||
length2Ref.current.focus()
|
||||
} else if (activeElem === length2Ref.current) {
|
||||
if (arrow1Ref.current === '←' || arrow1Ref.current === '→') {
|
||||
break
|
||||
}
|
||||
setArrow2('←')
|
||||
arrow2Ref.current = '←'
|
||||
checkRightAngle()
|
||||
}
|
||||
|
||||
checkRightAngle('←')
|
||||
break
|
||||
case 'Right': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowRight':
|
||||
if (activeElem === length1Ref.current) {
|
||||
setArrow1('→')
|
||||
arrow1Ref.current = '→'
|
||||
length2Ref.current.focus()
|
||||
} else if (activeElem === length2Ref.current) {
|
||||
if (arrow1Ref.current === '←' || arrow1Ref.current === '→') {
|
||||
break
|
||||
}
|
||||
setArrow2('→')
|
||||
arrow2Ref.current = '→'
|
||||
checkRightAngle()
|
||||
}
|
||||
|
||||
checkRightAngle('→')
|
||||
break
|
||||
}
|
||||
},
|
||||
leeGubae: (e) => {
|
||||
console.log('leegubae')
|
||||
doublePitch: (e) => {
|
||||
if (points.length === 0) {
|
||||
return
|
||||
}
|
||||
const key = e.key
|
||||
switch (key) {
|
||||
case 'Down': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowDown': {
|
||||
checkDoublePitch('↓')
|
||||
break
|
||||
}
|
||||
case 'Up': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowUp':
|
||||
checkDoublePitch('↑')
|
||||
break
|
||||
case 'Left': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowLeft':
|
||||
checkDoublePitch('←')
|
||||
break
|
||||
case 'Right': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowRight':
|
||||
checkDoublePitch('→')
|
||||
break
|
||||
}
|
||||
},
|
||||
angle: (e) => {
|
||||
if (points.length === 0) {
|
||||
return
|
||||
}
|
||||
const key = e.key
|
||||
switch (key) {
|
||||
case 'Enter': {
|
||||
@ -501,7 +697,30 @@ export function useOuterLineWall() {
|
||||
}
|
||||
},
|
||||
diagonalLine: (e) => {
|
||||
console.log('diagonalLine')
|
||||
if (points.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const key = e.key
|
||||
switch (key) {
|
||||
case 'Down': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowDown': {
|
||||
checkDiagonal('↓')
|
||||
break
|
||||
}
|
||||
case 'Up': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowUp':
|
||||
checkDiagonal('↑')
|
||||
break
|
||||
case 'Left': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowLeft':
|
||||
checkDiagonal('←')
|
||||
break
|
||||
case 'Right': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowRight':
|
||||
checkDiagonal('→')
|
||||
break
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@ -513,7 +732,7 @@ export function useOuterLineWall() {
|
||||
setPoints((prev) => prev.slice(0, prev.length - 1))
|
||||
}
|
||||
|
||||
const handleFix = () => {
|
||||
const handleFix = (fn) => {
|
||||
if (points.length < 3) {
|
||||
return
|
||||
}
|
||||
@ -541,6 +760,9 @@ export function useOuterLineWall() {
|
||||
setPoints((prev) => {
|
||||
return [...prev, { x: prev[0].x, y: prev[0].y }]
|
||||
})
|
||||
|
||||
isFix.current = true
|
||||
closeModalFn.current = fn
|
||||
}
|
||||
|
||||
return {
|
||||
@ -558,6 +780,15 @@ export function useOuterLineWall() {
|
||||
setArrow2,
|
||||
arrow1Ref,
|
||||
arrow2Ref,
|
||||
angle1,
|
||||
setAngle1,
|
||||
angle1Ref,
|
||||
angle2,
|
||||
setAngle2,
|
||||
angle2Ref,
|
||||
outerLineDiagonalLength,
|
||||
setOuterLineDiagonalLength,
|
||||
outerLineDiagonalLengthRef,
|
||||
type,
|
||||
setType,
|
||||
handleFix,
|
||||
|
||||
129
src/hooks/roofcover/usePropertiesSetting.js
Normal file
129
src/hooks/roofcover/usePropertiesSetting.js
Normal file
@ -0,0 +1,129 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { LINE_TYPE } from '@/common/common'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
|
||||
export function usePropertiesSetting() {
|
||||
const currentLine = useRef(null)
|
||||
const currentIdx = useRef(-1)
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
|
||||
useEffect(() => {
|
||||
selectNextLine()
|
||||
}, [])
|
||||
|
||||
const handleSetEaves = () => {
|
||||
currentLine.current.set({
|
||||
stroke: '#45CD7D',
|
||||
strokeWidth: 4,
|
||||
attributes: {
|
||||
offset: 500,
|
||||
type: LINE_TYPE.WALLLINE.EAVES,
|
||||
pitch: 4,
|
||||
},
|
||||
})
|
||||
canvas.renderAll()
|
||||
selectNextLine()
|
||||
}
|
||||
|
||||
const handleSetGable = () => {
|
||||
currentLine.current.set({
|
||||
stroke: '#3FBAE6',
|
||||
strokeWidth: 4,
|
||||
attributes: {
|
||||
offset: 300,
|
||||
type: LINE_TYPE.WALLLINE.GABLE,
|
||||
},
|
||||
})
|
||||
canvas.renderAll()
|
||||
selectNextLine()
|
||||
}
|
||||
|
||||
const selectNextLine = () => {
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
currentIdx.current++
|
||||
|
||||
if (currentIdx.current >= lines.length) {
|
||||
currentIdx.current = lines.length
|
||||
currentLine.current = lines[currentIdx.current - 1]
|
||||
return
|
||||
}
|
||||
|
||||
currentLine.current = lines[currentIdx.current]
|
||||
|
||||
currentLine.current.set({
|
||||
stroke: '#EA10AC',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
const selectPrevLine = () => {
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
|
||||
currentIdx.current--
|
||||
|
||||
if (currentIdx.current <= -1) {
|
||||
currentIdx.current = -1
|
||||
selectNextLine()
|
||||
return
|
||||
} else {
|
||||
lines.forEach((line, index) => {
|
||||
if (index >= currentIdx.current) {
|
||||
delete line.attributes
|
||||
line.set({
|
||||
stroke: '#000000',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
}
|
||||
currentIdx.current--
|
||||
canvas.renderAll()
|
||||
selectNextLine()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleRollback = () => {
|
||||
selectPrevLine()
|
||||
}
|
||||
|
||||
const handleFix = () => {
|
||||
if (!confirm('외벽선 속성 설정을 완료하시겠습니까?')) {
|
||||
return
|
||||
}
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
|
||||
lines.forEach((line) => {
|
||||
line.set({
|
||||
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
||||
stroke: '#000000',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
})
|
||||
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
const closeModal = (fn) => {
|
||||
if (!confirm('외벽선 속성 설정을 종료 하시겠습니까?')) {
|
||||
return
|
||||
}
|
||||
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
|
||||
lines.forEach((line) => {
|
||||
line.set({
|
||||
attributes: { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
||||
stroke: '#000000',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
})
|
||||
|
||||
canvas.renderAll()
|
||||
|
||||
fn(false)
|
||||
}
|
||||
|
||||
return { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal }
|
||||
}
|
||||
@ -26,7 +26,7 @@ export function useAdsorptionPoint() {
|
||||
top: pointer.y - 3,
|
||||
x: pointer.x,
|
||||
y: pointer.y,
|
||||
selectable: false,
|
||||
selectable: true,
|
||||
name: 'adsorptionPoint',
|
||||
})
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ export function useCanvas(id) {
|
||||
|
||||
setCanvas(c)
|
||||
setCanvasForEvent(c)
|
||||
attachDefaultEventOnCanvas()
|
||||
|
||||
return () => {
|
||||
// c.dispose()
|
||||
@ -45,7 +46,6 @@ export function useCanvas(id) {
|
||||
|
||||
useEffect(() => {
|
||||
// canvas 사이즈가 변경되면 다시
|
||||
attachDefaultEventOnCanvas()
|
||||
}, [canvasSize])
|
||||
|
||||
useEffect(() => {
|
||||
@ -91,6 +91,13 @@ export function useCanvas(id) {
|
||||
// settings for all canvas in the app
|
||||
fabric.Object.prototype.transparentCorners = false
|
||||
fabric.Object.prototype.id = uuidv4()
|
||||
fabric.Object.prototype.selectable = true
|
||||
fabric.Object.prototype.lockMovementX = true
|
||||
fabric.Object.prototype.lockMovementY = true
|
||||
fabric.Object.prototype.lockRotation = true
|
||||
fabric.Object.prototype.lockScalingX = true
|
||||
fabric.Object.prototype.lockScalingY = true
|
||||
|
||||
fabric.Object.prototype.cornerColor = '#2BEBC8'
|
||||
fabric.Object.prototype.cornerStyle = 'rect'
|
||||
fabric.Object.prototype.cornerStrokeColor = '#2BEBC8'
|
||||
|
||||
@ -6,6 +6,7 @@ import { gridColorState } from '@/store/gridAtom'
|
||||
|
||||
export function useDotLineGrid() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
|
||||
const gridColor = useRecoilValue(gridColorState)
|
||||
const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState)
|
||||
const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격
|
||||
|
||||
@ -1,24 +1,16 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import {
|
||||
adsorptionPointAddModeState,
|
||||
adsorptionPointModeState,
|
||||
adsorptionRangeState,
|
||||
canvasState,
|
||||
canvasZoomState,
|
||||
currentMenuState,
|
||||
} from '@/store/canvasAtom'
|
||||
import { canvasState, canvasZoomState, currentMenuState } from '@/store/canvasAtom'
|
||||
import { fabric } from 'fabric'
|
||||
import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
|
||||
import { calculateDistance, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
|
||||
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
||||
import { useMouse } from '@/hooks/useMouse'
|
||||
import { useDotLineGrid } from '@/hooks/useDotLineGrid'
|
||||
import { useTempGrid } from '@/hooks/useTempGrid'
|
||||
|
||||
export function useEvent() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const currentMenu = useRecoilValue(currentMenuState)
|
||||
const keyboardEventListeners = useRef([])
|
||||
const documentEventListeners = useRef([])
|
||||
const mouseEventListeners = useRef([])
|
||||
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||
|
||||
@ -30,9 +22,8 @@ export function useEvent() {
|
||||
if (!canvas) {
|
||||
return
|
||||
}
|
||||
removeAllMouseEventListeners()
|
||||
removeAllDocumentEventListeners()
|
||||
|
||||
removeAllMouseEventListeners()
|
||||
/**
|
||||
* wheelEvent
|
||||
*/
|
||||
@ -193,13 +184,14 @@ export function useEvent() {
|
||||
}
|
||||
|
||||
const addCanvasMouseEventListener = (eventType, handler) => {
|
||||
canvas.off(eventType)
|
||||
canvas.on(eventType, handler)
|
||||
mouseEventListeners.current.push({ eventType, handler })
|
||||
}
|
||||
|
||||
const removeAllMouseEventListeners = () => {
|
||||
mouseEventListeners.current.forEach(({ eventType, handler }) => {
|
||||
canvas.off(eventType, handler)
|
||||
canvas.off(eventType)
|
||||
})
|
||||
mouseEventListeners.current.length = 0 // 배열 초기화
|
||||
}
|
||||
@ -211,24 +203,36 @@ export function useEvent() {
|
||||
* @param handler
|
||||
*/
|
||||
const addDocumentEventListener = (eventType, element, handler) => {
|
||||
removeDocumentEvent(eventType)
|
||||
element.addEventListener(eventType, handler)
|
||||
keyboardEventListeners.current.push({ eventType, element, handler })
|
||||
documentEventListeners.current.push({ eventType, element, handler })
|
||||
}
|
||||
|
||||
/**
|
||||
* document에 등록되는 event 제거
|
||||
*/
|
||||
const removeAllDocumentEventListeners = () => {
|
||||
keyboardEventListeners.current.forEach(({ eventType, element, handler }) => {
|
||||
documentEventListeners.current.forEach(({ eventType, element, handler }) => {
|
||||
element.removeEventListener(eventType, handler)
|
||||
})
|
||||
keyboardEventListeners.current.length = 0 // 배열 초기화
|
||||
documentEventListeners.current.length = 0 // 배열 초기화
|
||||
}
|
||||
|
||||
const removeMouseEvent = (type, handler) => {
|
||||
const removeMouseEvent = (type) => {
|
||||
mouseEventListeners.current = mouseEventListeners.current.filter((event) => {
|
||||
if (event.type === type && event.handler === handler) {
|
||||
canvas.off(type, handler)
|
||||
if (event.eventType === type) {
|
||||
canvas.off(type, event.handler)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
const removeDocumentEvent = (type) => {
|
||||
documentEventListeners.current = documentEventListeners.current.filter((event) => {
|
||||
if (event.eventType === type) {
|
||||
console.log(type)
|
||||
event.element.removeEventListener(type, event.handler)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@ -38,6 +38,7 @@ export const useLine = () => {
|
||||
const removeLine = (line) => {
|
||||
removeLineText(line)
|
||||
canvas?.remove(line)
|
||||
canvas?.renderAll()
|
||||
}
|
||||
|
||||
const removeLineText = (line) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user