우선 9번까지 모달화
This commit is contained in:
parent
77ec869d41
commit
cb0775c493
@ -34,6 +34,7 @@ import { degreesToRadians, radiansToDegrees } from '@turf/turf'
|
|||||||
|
|
||||||
import InitSettingsModal from './InitSettingsModal'
|
import InitSettingsModal from './InitSettingsModal'
|
||||||
import GridSettingsModal from './GridSettingsModal'
|
import GridSettingsModal from './GridSettingsModal'
|
||||||
|
import { SurfaceShapeModal } from '@/components/ui/SurfaceShape'
|
||||||
|
|
||||||
export default function Roof2(props) {
|
export default function Roof2(props) {
|
||||||
const { name, userId, email, isLoggedIn } = props
|
const { name, userId, email, isLoggedIn } = props
|
||||||
@ -534,6 +535,44 @@ export default function Roof2(props) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setCurrentPattern = (polygon) => {
|
||||||
|
const { width, height, roofStyle } = roofMaterial
|
||||||
|
const roofRatio = window.devicePixelRatio || 1
|
||||||
|
const patternSourceCanvas = document.createElement('canvas')
|
||||||
|
|
||||||
|
if (roofStyle === 1) {
|
||||||
|
patternSourceCanvas.width = width * roofRatio
|
||||||
|
patternSourceCanvas.height = height * roofRatio
|
||||||
|
} else if (roofStyle === 2) {
|
||||||
|
patternSourceCanvas.width = width * 2
|
||||||
|
patternSourceCanvas.height = height * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctx = patternSourceCanvas.getContext('2d')
|
||||||
|
|
||||||
|
ctx.scale(roofRatio, roofRatio)
|
||||||
|
ctx.strokeStyle = 'green'
|
||||||
|
ctx.lineWidth = 0.4
|
||||||
|
// 벽돌 패턴 그리기
|
||||||
|
if (roofStyle === 1) {
|
||||||
|
ctx.strokeRect(0, 0, 50, 30)
|
||||||
|
} else if (roofStyle === 2) {
|
||||||
|
// 지그재그
|
||||||
|
ctx.strokeRect(0, 0, 200, 100)
|
||||||
|
ctx.strokeRect(100, 100, 200, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 패턴 생성
|
||||||
|
const pattern = new fabric.Pattern({
|
||||||
|
source: patternSourceCanvas,
|
||||||
|
repeat: 'repeat',
|
||||||
|
})
|
||||||
|
polygon.set('fill', null)
|
||||||
|
|
||||||
|
polygon.set('fill', pattern)
|
||||||
|
canvas?.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* canvas 내용 불러오기
|
* canvas 내용 불러오기
|
||||||
*/
|
*/
|
||||||
@ -576,41 +615,6 @@ export default function Roof2(props) {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
const createTemplate1 = () => {
|
|
||||||
const length1 = prompt('1번')
|
|
||||||
const length2 = prompt('2번')
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x, y: pointer.y - parseInt(length2) / 2 },
|
|
||||||
{ x: pointer.x - parseInt(length1) / 2, y: pointer.y + parseInt(length1) / 2 },
|
|
||||||
{ x: pointer.x + parseInt(length1) / 2, y: pointer.y + parseInt(length1) / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const createPentagon2 = () => {
|
const createPentagon2 = () => {
|
||||||
const a = 400 //Number(prompt('a'))
|
const a = 400 //Number(prompt('a'))
|
||||||
const b = 200 //Number(prompt('b'))
|
const b = 200 //Number(prompt('b'))
|
||||||
@ -671,297 +675,6 @@ export default function Roof2(props) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const createTemplate2 = () => {
|
|
||||||
const length1 = prompt('1번')
|
|
||||||
const length2 = prompt('2번')
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const createTemplate3 = () => {
|
|
||||||
const length1 = Number(prompt('1번'))
|
|
||||||
const length2 = Number(prompt('2번'))
|
|
||||||
const length3 = Number(prompt('3번'))
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length3 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
{ x: pointer.x - length3 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const createTemplate4 = () => {
|
|
||||||
const length1 = Number(prompt('1번'))
|
|
||||||
const length2 = Number(prompt('2번'))
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const createTemplate5 = () => {
|
|
||||||
const length1 = Number(prompt('1번'))
|
|
||||||
const length2 = Number(prompt('2번'))
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const createTemplate6 = () => {
|
|
||||||
const length1 = Number(prompt('1번'))
|
|
||||||
const length2 = Number(prompt('2번'))
|
|
||||||
const length3 = Number(prompt('3번'))
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y - length3 / 2 },
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length3 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 - length2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const createTemplate7 = () => {
|
|
||||||
const length1 = Number(prompt('1번'))
|
|
||||||
const length2 = Number(prompt('2번'))
|
|
||||||
const length3 = Number(prompt('3번'))
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 },
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 - length3 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const createTemplate8 = () => {
|
|
||||||
const length1 = Number(prompt('1번')) // 밑변
|
|
||||||
const length2 = Number(prompt('2번')) // 높이
|
|
||||||
const length3 = Number(prompt('3번')) // 빗변
|
|
||||||
|
|
||||||
const angleInRadians = Math.asin(length2 / length3)
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x - length1 / 2 + length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
|
||||||
{ x: pointer.x + length1 / 2 + length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const createTemplate9 = () => {
|
|
||||||
const length1 = Number(prompt('1번')) // 밑변
|
|
||||||
const length2 = Number(prompt('2번')) // 높이
|
|
||||||
const length3 = Number(prompt('3번')) // 빗변
|
|
||||||
|
|
||||||
const angleInRadians = Math.asin(length2 / length3)
|
|
||||||
|
|
||||||
let isDrawing = true
|
|
||||||
canvas?.on('mouse:move', (e) => {
|
|
||||||
if (!isDrawing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
|
||||||
const pointer = canvas?.getPointer(e.e)
|
|
||||||
const triangle = new QPolygon(
|
|
||||||
[
|
|
||||||
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
{ x: pointer.x + length1 / 2 - length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
|
||||||
{ x: pointer.x - length1 / 2 - length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
|
||||||
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
|
||||||
],
|
|
||||||
{
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
name: 'guideTriangle',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
canvas?.add(triangle)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas?.on('mouse:down', (e) => {
|
|
||||||
isDrawing = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const createTemplate10 = () => {
|
const createTemplate10 = () => {
|
||||||
const length1 = Number(prompt('1번'))
|
const length1 = Number(prompt('1번'))
|
||||||
const length2 = Number(prompt('2번'))
|
const length2 = Number(prompt('2번'))
|
||||||
@ -1858,6 +1571,13 @@ export default function Roof2(props) {
|
|||||||
<Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`} onClick={() => setMode(Mode.EDIT)}>
|
<Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`} onClick={() => setMode(Mode.EDIT)}>
|
||||||
에디팅모드
|
에디팅모드
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="m-1 p-2"
|
||||||
|
color={`${mode === Mode.MOUSE_DISTANCE ? 'primary' : 'default'}`}
|
||||||
|
onClick={() => setMode(Mode.MOUSE_DISTANCE)}
|
||||||
|
>
|
||||||
|
마우스거리 모드
|
||||||
|
</Button>
|
||||||
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setMode(Mode.TEMPLATE)}>
|
<Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`} onClick={() => setMode(Mode.TEMPLATE)}>
|
||||||
템플릿(기둥)
|
템플릿(기둥)
|
||||||
</Button>
|
</Button>
|
||||||
@ -1947,6 +1667,15 @@ export default function Roof2(props) {
|
|||||||
<Button className="m-1 p-2" onClick={() => saveImage(uuidv4(), userId, setThumbnails)}>
|
<Button className="m-1 p-2" onClick={() => saveImage(uuidv4(), userId, setThumbnails)}>
|
||||||
저장
|
저장
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="m-1 p-2"
|
||||||
|
onClick={() => {
|
||||||
|
setContent(<SurfaceShapeModal canvas={canvas} />)
|
||||||
|
setOpen(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
면형상
|
||||||
|
</Button>
|
||||||
{/*<Button className="m-1 p-2" onClick={rotateShape}>
|
{/*<Button className="m-1 p-2" onClick={rotateShape}>
|
||||||
회전
|
회전
|
||||||
</Button>*/}
|
</Button>*/}
|
||||||
@ -1981,33 +1710,6 @@ export default function Roof2(props) {
|
|||||||
<Button className="m-1 p-2" onClick={deleteCell}>
|
<Button className="m-1 p-2" onClick={deleteCell}>
|
||||||
선택 셀 지우기
|
선택 셀 지우기
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="m-1 p-2" onClick={createTemplate1}>
|
|
||||||
1번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate2}>
|
|
||||||
2번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate3}>
|
|
||||||
3번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate4}>
|
|
||||||
4번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate5}>
|
|
||||||
5번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate6}>
|
|
||||||
6번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate7}>
|
|
||||||
7번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate8}>
|
|
||||||
8번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate9}>
|
|
||||||
9번 추가
|
|
||||||
</Button>
|
|
||||||
<Button className="m-1 p-2" onClick={createTemplate10}>
|
<Button className="m-1 p-2" onClick={createTemplate10}>
|
||||||
10번 추가
|
10번 추가
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
387
src/components/ui/SurfaceShape.jsx
Normal file
387
src/components/ui/SurfaceShape.jsx
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
import { Button, Input } from '@nextui-org/react'
|
||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
|
import { modalState } from '@/store/modalAtom'
|
||||||
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import { fontSizeState } from '@/store/canvasAtom'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 면형상 배치 모달
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export const SurfaceShapeModal = ({ canvas }) => {
|
||||||
|
const [type, setType] = useState(0)
|
||||||
|
const setOpen = useSetRecoilState(modalState)
|
||||||
|
const fontSize = useRecoilValue(fontSizeState)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 최대 5개의 length
|
||||||
|
*/
|
||||||
|
const [length1, setLength1] = useState(0)
|
||||||
|
const [length2, setLength2] = useState(0)
|
||||||
|
const [length3, setLength3] = useState(0)
|
||||||
|
const [length4, setLength4] = useState(0)
|
||||||
|
const [length5, setLength5] = useState(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 최대 5개의 length
|
||||||
|
*/
|
||||||
|
const onChangeType = (e) => {
|
||||||
|
setType(Number(e.target.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSave = () => {
|
||||||
|
let isDrawing = true
|
||||||
|
let obj = null
|
||||||
|
canvas?.on('mouse:move', (e) => {
|
||||||
|
if (!isDrawing) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch (type) {
|
||||||
|
case 1: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x, y: pointer.y - parseInt(length2) / 2 },
|
||||||
|
{ x: pointer.x - parseInt(length1) / 2, y: pointer.y + parseInt(length1) / 2 },
|
||||||
|
{ x: pointer.x + parseInt(length1) / 2, y: pointer.y + parseInt(length1) / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length3 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
{ x: pointer.x - length3 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case 6: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y - length3 / 2 },
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length3 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length3 / 2 - length2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case 7: {
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y - length2 / 2 },
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 - length3 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case 8: {
|
||||||
|
const angleInRadians = Math.asin(length2 / length3)
|
||||||
|
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'guideTriangle'))
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x - length1 / 2 + length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
||||||
|
{ x: pointer.x + length1 / 2 + length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
case 9: {
|
||||||
|
const angleInRadians = Math.asin(length2 / length3)
|
||||||
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
obj = new QPolygon(
|
||||||
|
[
|
||||||
|
{ x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
{ x: pointer.x + length1 / 2 - length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
||||||
|
{ x: pointer.x - length1 / 2 - length3 * Math.cos(angleInRadians), y: pointer.y + length2 / 2 - length3 * Math.sin(angleInRadians) },
|
||||||
|
{ x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 },
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: fontSize,
|
||||||
|
name: 'guideTriangle',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas?.add(obj)
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas?.on('mouse:down', (e) => {
|
||||||
|
isDrawing = false
|
||||||
|
obj.set('name', 'roof')
|
||||||
|
})
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const setLength = (e) => {
|
||||||
|
const { name, value } = e.target
|
||||||
|
switch (name) {
|
||||||
|
case 'length1':
|
||||||
|
setLength1(value)
|
||||||
|
break
|
||||||
|
case 'length2':
|
||||||
|
setLength2(value)
|
||||||
|
break
|
||||||
|
case 'length3':
|
||||||
|
setLength3(value)
|
||||||
|
break
|
||||||
|
case 'length4':
|
||||||
|
setLength4(value)
|
||||||
|
break
|
||||||
|
case 'length5':
|
||||||
|
setLength5(value)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<div>면형상배치{type}</div>
|
||||||
|
<Button className="m-1 p-2" value="1" onClick={onChangeType}>
|
||||||
|
1번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="2" onClick={onChangeType}>
|
||||||
|
2번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="3" onClick={onChangeType}>
|
||||||
|
3번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="4" onClick={onChangeType}>
|
||||||
|
4번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="5" onClick={onChangeType}>
|
||||||
|
5번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="6" onClick={onChangeType}>
|
||||||
|
6번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="7" onClick={onChangeType}>
|
||||||
|
7번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="8" onClick={onChangeType}>
|
||||||
|
8번
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" value="9" onClick={onChangeType}>
|
||||||
|
9번
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{type === 1 ? (
|
||||||
|
<div>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
길이3 <Input type="number" name={'length3'} value={length3} onChange={setLength} />
|
||||||
|
</div>
|
||||||
|
) : type === 2 ? (
|
||||||
|
<div>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
</div>
|
||||||
|
) : type === 3 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
길이3
|
||||||
|
<Input type="number" name={'length3'} value={length3} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : type === 4 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : type === 5 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : type === 6 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
길이3
|
||||||
|
<Input type="number" name={'length3'} value={length3} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : type === 7 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
길이3
|
||||||
|
<Input type="number" name={'length3'} value={length3} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : type === 8 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
길이3
|
||||||
|
<Input type="number" name={'length3'} value={length3} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : type === 9 ? (
|
||||||
|
<>
|
||||||
|
길이1
|
||||||
|
<Input type="number" name={'length1'} value={length1} onChange={setLength} />
|
||||||
|
길이2
|
||||||
|
<Input type="number" name={'length2'} value={length2} onChange={setLength} />
|
||||||
|
길이3
|
||||||
|
<Input type="number" name={'length3'} value={length3} onChange={setLength} />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
<div>
|
||||||
|
<Button className="m-1 p-2" color={'primary'} onClick={closeModal}>
|
||||||
|
닫기
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" color={'primary'} onClick={onSave}>
|
||||||
|
저장
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -99,7 +99,7 @@ export const currentObjectState = atom({
|
|||||||
export const horiGuideLinesState = atom({
|
export const horiGuideLinesState = atom({
|
||||||
key: 'horiGuideLines',
|
key: 'horiGuideLines',
|
||||||
default: [],
|
default: [],
|
||||||
dangerouslyAllowMutability: true,
|
// dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const vertGuideLinesState = atom({
|
export const vertGuideLinesState = atom({
|
||||||
@ -112,3 +112,10 @@ export const canvasSettingState = atom({
|
|||||||
default: {},
|
default: {},
|
||||||
dangerouslyAllowMutability: true,
|
dangerouslyAllowMutability: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 현재 지붕 패턴
|
||||||
|
export const currentPatternState = atom({
|
||||||
|
key: 'currentPattern',
|
||||||
|
default: {},
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user