외벽선 편집 및 오프셋 작업중
This commit is contained in:
parent
1599f48e70
commit
aaf32d4904
@ -3,14 +3,29 @@ import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import { useState } from 'react'
|
||||
import WallLine from '@/components/floor-plan/modal/wallLineOffset/type/WallLine'
|
||||
import Offset from '@/components/floor-plan/modal/wallLineOffset/type/Offset'
|
||||
import { useWallLineOffsetSetting } from '@/hooks/roofcover/useWallLineOffsetSetting'
|
||||
|
||||
export default function WallLineOffsetSetting({ setShowWallLineOffsetSettingModal }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { type, setType, buttonMenu, currentWallLineRef, TYPES, radioTypeRef, arrow1Ref, arrow2Ref, length1Ref, length2Ref, handleSave } =
|
||||
useWallLineOffsetSetting()
|
||||
const [buttonAct, setButtonAct] = useState(1)
|
||||
const buttonMenu = [
|
||||
{ id: 1, name: getMessage('modal.wallline.offset.setting.wallline.edit') },
|
||||
{ id: 2, name: getMessage('modal.wallline.offset.setting.offset') },
|
||||
]
|
||||
|
||||
const wallLineProps = {
|
||||
length1Ref,
|
||||
length2Ref,
|
||||
arrow1Ref,
|
||||
arrow2Ref,
|
||||
radioTypeRef,
|
||||
currentWallLineRef,
|
||||
}
|
||||
|
||||
const offsetProps = {
|
||||
length1Ref,
|
||||
arrow1Ref,
|
||||
currentWallLineRef,
|
||||
}
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}>
|
||||
<div className={`modal-pop-wrap r`}>
|
||||
@ -23,18 +38,20 @@ export default function WallLineOffsetSetting({ setShowWallLineOffsetSettingModa
|
||||
<div className="modal-body">
|
||||
<div className="modal-btn-wrap">
|
||||
{buttonMenu.map((item) => (
|
||||
<button key={item.id} className={`btn-frame modal ${buttonAct === item.id ? 'act' : ''}`} onClick={() => setButtonAct(item.id)}>
|
||||
<button key={item.id} className={`btn-frame modal ${type === item.type ? 'act' : ''}`} onClick={() => setType(item.type)}>
|
||||
{item.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="properties-setting-wrap outer">
|
||||
<div className="setting-tit">{getMessage('setting')}</div>
|
||||
{buttonAct === 1 && <WallLine />}
|
||||
{buttonAct === 2 && <Offset />}
|
||||
{type === TYPES.WALL_LINE_EDIT && <WallLine {...wallLineProps} />}
|
||||
{type === TYPES.OFFSET && <Offset {...offsetProps} />}
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
|
||||
<button className="btn-frame modal act" onClick={handleSave}>
|
||||
{getMessage('modal.common.save')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,67 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
|
||||
export default function Offset({ setShowSlopeSettingModal }) {
|
||||
export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
|
||||
const { getMessage } = useMessage()
|
||||
const { addDocumentEventListener, initEvent } = useEvent()
|
||||
|
||||
useEffect(() => {
|
||||
addDocumentEventListener('keydown', document, keyDown)
|
||||
|
||||
return () => {
|
||||
initEvent()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleBtnClick = (direction) => {
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: direction }))
|
||||
}
|
||||
|
||||
const [arrow, setArrow] = useState(null)
|
||||
|
||||
const keyDown = (e) => {
|
||||
if (currentWallLineRef.current === null) {
|
||||
alert('보조선을 먼저 선택하세요')
|
||||
return
|
||||
}
|
||||
|
||||
const direction = currentWallLineRef.current.direction
|
||||
|
||||
const key = e.key
|
||||
|
||||
switch (key) {
|
||||
case 'Down': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowDown': {
|
||||
if (direction === 'left' || direction === 'right') {
|
||||
setArrow('down')
|
||||
arrow1Ref.current = 'down'
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'Up': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowUp':
|
||||
if (direction === 'left' || direction === 'right') {
|
||||
setArrow('up')
|
||||
arrow1Ref.current = 'up'
|
||||
}
|
||||
break
|
||||
case 'Left': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowLeft':
|
||||
if (direction === 'bottom' || direction === 'top') {
|
||||
setArrow('left')
|
||||
arrow1Ref.current = 'left'
|
||||
}
|
||||
break
|
||||
case 'Right': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowRight':
|
||||
if (direction === 'bottom' || direction === 'top') {
|
||||
setArrow('right')
|
||||
arrow1Ref.current = 'right'
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="outline-wrap">
|
||||
@ -13,7 +73,7 @@ export default function Offset({ setShowSlopeSettingModal }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={100} />
|
||||
<input type="text" className="input-origin block" defaultValue={0} ref={length1Ref} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -24,10 +84,10 @@ export default function Offset({ setShowSlopeSettingModal }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<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 ${arrow === 'up' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowUp')}></button>
|
||||
<button className={`direction down ${arrow === 'down' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowDown')}></button>
|
||||
<button className={`direction left ${arrow === 'left' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowLeft')}></button>
|
||||
<button className={`direction right ${arrow === 'right' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowRight')}></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,17 +1,92 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
|
||||
export default function WallLine({ setShowSlopeSettingModal }) {
|
||||
export default function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef }) {
|
||||
const { getMessage } = useMessage()
|
||||
const [position1, setPosition1] = useState()
|
||||
const [position2, setPosition2] = useState()
|
||||
const { addDocumentEventListener, initEvent } = useEvent()
|
||||
const [type, setType] = useState(1)
|
||||
const [arrow1, setArrow1] = useState('up')
|
||||
const [arrow2, setArrow2] = useState('up')
|
||||
|
||||
useEffect(() => {
|
||||
addDocumentEventListener('keydown', document, keyDown)
|
||||
|
||||
return () => {
|
||||
initEvent()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onChange = (e) => {
|
||||
setType(Number(e.target.value))
|
||||
radioTypeRef.current = e.target.value
|
||||
}
|
||||
|
||||
const handleBtnClick = (direction) => {
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: direction }))
|
||||
}
|
||||
|
||||
const keyDown = (e) => {
|
||||
if (currentWallLineRef.current === null) {
|
||||
alert('보조선을 먼저 선택하세요')
|
||||
return
|
||||
}
|
||||
|
||||
const key = e.key
|
||||
|
||||
switch (key) {
|
||||
case 'Down': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowDown': {
|
||||
if (radioTypeRef.current === '1') {
|
||||
setArrow1('down')
|
||||
arrow1Ref.current = 'down'
|
||||
} else {
|
||||
setArrow2('down')
|
||||
arrow2Ref.current = 'down'
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
case 'Up': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowUp':
|
||||
if (radioTypeRef.current === '1') {
|
||||
setArrow1('up')
|
||||
arrow1Ref.current = 'up'
|
||||
} else {
|
||||
setArrow2('up')
|
||||
arrow2Ref.current = 'up'
|
||||
}
|
||||
break
|
||||
case 'Left': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowLeft':
|
||||
if (radioTypeRef.current === '1') {
|
||||
setArrow1('left')
|
||||
arrow1Ref.current = 'left'
|
||||
} else {
|
||||
setArrow2('left')
|
||||
arrow2Ref.current = 'left'
|
||||
}
|
||||
break
|
||||
case 'Right': // IE/Edge에서 사용되는 값
|
||||
case 'ArrowRight':
|
||||
if (radioTypeRef.current === '1') {
|
||||
setArrow1('right')
|
||||
arrow1Ref.current = 'right'
|
||||
} else {
|
||||
setArrow2('right')
|
||||
arrow2Ref.current = 'right'
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="outline-wrap">
|
||||
<div className="guide sm">{getMessage('modal.wallline.offset.setting.wallline.edit.info')}</div>
|
||||
<div className="discrimination-box mb10">
|
||||
<div className="d-check-radio pop mb10">
|
||||
<input type="radio" name="radio01" id="ra01" />
|
||||
<input type="radio" name="radio01" id="ra01" value="1" checked={type === 1} onChange={(e) => onChange(e)} />
|
||||
<label htmlFor="ra01">1{getMessage('modal.wallline.offset.setting.wallline.edit.position')}</label>
|
||||
</div>
|
||||
<div className="padding-form">
|
||||
@ -21,7 +96,7 @@ export default function WallLine({ setShowSlopeSettingModal }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={100} />
|
||||
<input type="text" className="input-origin block" defaultValue={0} readOnly={type !== 1} ref={length1Ref} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -32,10 +107,10 @@ export default function WallLine({ setShowSlopeSettingModal }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<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 === 'up' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowUp')}></button>
|
||||
<button className={`direction down ${arrow1 === 'down' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowDown')}></button>
|
||||
<button className={`direction left ${arrow1 === 'left' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowLeft')}></button>
|
||||
<button className={`direction right ${arrow1 === 'right' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowRight')}></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -45,7 +120,7 @@ export default function WallLine({ setShowSlopeSettingModal }) {
|
||||
</div>
|
||||
<div className="discrimination-box">
|
||||
<div className="d-check-radio pop mb10">
|
||||
<input type="radio" name="radio01" id="ra02" />
|
||||
<input type="radio" name="radio01" id="ra02" value="2" checked={type === 2} onChange={(e) => onChange(e)} />
|
||||
<label htmlFor="ra02">2{getMessage('modal.wallline.offset.setting.wallline.edit.position')}</label>
|
||||
</div>
|
||||
<div className="padding-form">
|
||||
@ -55,7 +130,7 @@ export default function WallLine({ setShowSlopeSettingModal }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={100} />
|
||||
<input type="text" className="input-origin block" defaultValue={0} readOnly={type !== 2} ref={length2Ref} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -66,10 +141,10 @@ export default function WallLine({ setShowSlopeSettingModal }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<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 === 'up' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowUp')}></button>
|
||||
<button className={`direction down ${arrow2 === 'down' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowDown')}></button>
|
||||
<button className={`direction left ${arrow2 === 'left' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowLeft')}></button>
|
||||
<button className={`direction right ${arrow2 === 'right' ? 'act' : ''} `} onClick={() => handleBtnClick('ArrowRight')}></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
128
src/hooks/roofcover/useWallLineOffsetSetting.js
Normal file
128
src/hooks/roofcover/useWallLineOffsetSetting.js
Normal file
@ -0,0 +1,128 @@
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import { useLine } from '@/hooks/useLine'
|
||||
|
||||
export function useWallLineOffsetSetting() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const { showLine, addLine } = useLine()
|
||||
const { getMessage } = useMessage()
|
||||
const { addCanvasMouseEventListener, initEvent } = useEvent()
|
||||
const length1Ref = useRef(null)
|
||||
const length2Ref = useRef(null)
|
||||
const radioTypeRef = useRef('1')
|
||||
const currentWallLineRef = useRef(null)
|
||||
const arrow1Ref = useRef(null)
|
||||
const arrow2Ref = useRef(null)
|
||||
|
||||
const TYPES = {
|
||||
WALL_LINE_EDIT: 'wallLineEdit',
|
||||
OFFSET: 'offset',
|
||||
}
|
||||
|
||||
const buttonMenu = [
|
||||
{ id: 1, name: getMessage('modal.wallline.offset.setting.wallline.edit'), type: TYPES.WALL_LINE_EDIT },
|
||||
{ id: 2, name: getMessage('modal.wallline.offset.setting.offset'), type: TYPES.OFFSET },
|
||||
]
|
||||
|
||||
const [type, setType] = useState(TYPES.WALL_LINE_EDIT)
|
||||
|
||||
useEffect(() => {
|
||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
outerLines.forEach((outerLine) => {
|
||||
outerLine.set({ selectable: true })
|
||||
showLine(outerLine)
|
||||
})
|
||||
|
||||
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
|
||||
roofs.forEach((roof) => {
|
||||
roof.innerLines.forEach((innerLine) => {
|
||||
canvas.remove(innerLine)
|
||||
})
|
||||
canvas.remove(roof)
|
||||
})
|
||||
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
wallLines.forEach((wallLine) => {
|
||||
canvas.remove(wallLine)
|
||||
})
|
||||
|
||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||
|
||||
return () => {
|
||||
canvas.discardActiveObject()
|
||||
initEvent()
|
||||
}
|
||||
}, [])
|
||||
|
||||
const mouseDown = (e) => {
|
||||
if (!e.target || (e.target && e.target.name !== 'outerLine')) {
|
||||
return
|
||||
}
|
||||
|
||||
currentWallLineRef.current = e.target
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
switch (type) {
|
||||
case TYPES.WALL_LINE_EDIT:
|
||||
handleWallLineEditSave()
|
||||
break
|
||||
case TYPES.OFFSET:
|
||||
handleOffsetSave()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const handleWallLineEditSave = () => {
|
||||
const direction = currentWallLineRef.current.direction
|
||||
let canDirections = direction === 'left' || direction === 'right' ? ['up', 'down'] : ['left', 'right']
|
||||
if (radioTypeRef === 1) {
|
||||
if (!canDirections.includes(arrow1Ref.current)) {
|
||||
alert('방향을 다시 선택하세요')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!canDirections.includes(arrow2Ref.current)) {
|
||||
alert('방향을 다시 선택하세요')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleOffsetSave = () => {
|
||||
const direction = currentWallLineRef.current.direction
|
||||
let canDirections = direction === 'left' || direction === 'right' ? ['up', 'down'] : ['left', 'right']
|
||||
|
||||
if (!canDirections.includes(arrow1Ref.current)) {
|
||||
alert('방향을 다시 선택하세요')
|
||||
return
|
||||
}
|
||||
|
||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
const idx = currentWallLineRef.current.idx
|
||||
const prevLine = outerLines.find((line) => (line.idx === idx - 1 < 0 ? outerLines.length - 1 : idx - 1))
|
||||
const currentLine = currentWallLineRef.current
|
||||
const nextLine = outerLines.find((line) => (line.idx === idx + 1 > outerLines.length - 1 ? 0 : idx + 1))
|
||||
switch (arrow1Ref.current) {
|
||||
case 'up': {
|
||||
console.log(prevLine, currentLine, nextLine)
|
||||
break
|
||||
}
|
||||
case 'down': {
|
||||
break
|
||||
}
|
||||
case 'left': {
|
||||
break
|
||||
}
|
||||
case 'right': {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { type, setType, buttonMenu, TYPES, length1Ref, length2Ref, radioTypeRef, currentWallLineRef, arrow1Ref, arrow2Ref, handleSave }
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user