면 형상 배치 후 방향 설정 시 방향 글자 넣기 추가
This commit is contained in:
parent
dbb5a56126
commit
466314da78
@ -5,7 +5,7 @@ import { useEffect, useRef, useState } from 'react'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { useMode } from '@/hooks/useMode'
|
import { useMode } from '@/hooks/useMode'
|
||||||
import { Mode } from '@/common/common'
|
import { Mode } from '@/common/common'
|
||||||
import { Button } from '@nextui-org/react'
|
import { Button, Input } from '@nextui-org/react'
|
||||||
import RangeSlider from './ui/RangeSlider'
|
import RangeSlider from './ui/RangeSlider'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import {
|
import {
|
||||||
@ -15,6 +15,7 @@ import {
|
|||||||
compassState,
|
compassState,
|
||||||
currentObjectState,
|
currentObjectState,
|
||||||
fontSizeState,
|
fontSizeState,
|
||||||
|
globalCompassState,
|
||||||
roofMaterialState,
|
roofMaterialState,
|
||||||
roofState,
|
roofState,
|
||||||
sortedPolygonArray,
|
sortedPolygonArray,
|
||||||
@ -24,20 +25,20 @@ import {
|
|||||||
} from '@/store/canvasAtom'
|
} from '@/store/canvasAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
||||||
import { calculateIntersection, distanceBetweenPoints, getIntersectionPoint } from '@/util/canvas-util'
|
import { calculateIntersection } from '@/util/canvas-util'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import ThumbnailList from './ui/ThumbnailLIst'
|
|
||||||
import QContextMenu from './common/context-menu/QContextMenu'
|
import QContextMenu from './common/context-menu/QContextMenu'
|
||||||
import { modalContent, modalState } from '@/store/modalAtom'
|
import { modalContent, modalState } from '@/store/modalAtom'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu'
|
import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu'
|
||||||
import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu'
|
import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu'
|
||||||
import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu'
|
import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu'
|
||||||
import { degreesToRadians, point, 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'
|
import { SurfaceShapeModal } from '@/components/ui/SurfaceShape'
|
||||||
|
import { drawDirectionStringToArrow } from '@/util/qpolygon-utils'
|
||||||
|
import ThumbnailList from '@/components/ui/ThumbnailLIst'
|
||||||
|
|
||||||
export default function Roof2(props) {
|
export default function Roof2(props) {
|
||||||
const { name, userId, email, isLoggedIn } = props
|
const { name, userId, email, isLoggedIn } = props
|
||||||
@ -105,6 +106,8 @@ export default function Roof2(props) {
|
|||||||
let imgPath
|
let imgPath
|
||||||
useCadFile && (imgPath = `/cadImages/${cadFileName}`)
|
useCadFile && (imgPath = `/cadImages/${cadFileName}`)
|
||||||
|
|
||||||
|
const [globalCampass, setGlobalCampass] = useRecoilState(globalCompassState)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mode,
|
mode,
|
||||||
setMode,
|
setMode,
|
||||||
@ -608,6 +611,10 @@ export default function Roof2(props) {
|
|||||||
const moduleConfiguration = () => {
|
const moduleConfiguration = () => {
|
||||||
createRoofRack()
|
createRoofRack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setDirectionStringToArrow = () => {
|
||||||
|
drawDirectionStringToArrow(canvas, globalCampass)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{canvas && (
|
{canvas && (
|
||||||
@ -854,6 +861,58 @@ export default function Roof2(props) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<ThumbnailList {...thumbnailProps} />
|
<ThumbnailList {...thumbnailProps} />
|
||||||
|
<div className={'flex'}>
|
||||||
|
<p className={'m-1 p-3'}>각도 입력(0~360) 후 방향설정 클릭</p>
|
||||||
|
<Input
|
||||||
|
className="m-1 p-3"
|
||||||
|
type={'text'}
|
||||||
|
value={globalCampass}
|
||||||
|
onChange={(e) => {
|
||||||
|
const val = e.target.value.replace(/[^-0-9]/g, '')
|
||||||
|
if (val < 0 || val > 360) {
|
||||||
|
setGlobalCampass(0)
|
||||||
|
} else {
|
||||||
|
setGlobalCampass(Number(val))
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button className="m-1 p-3" onClick={setDirectionStringToArrow}>
|
||||||
|
방향 설정
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="relative w-48 h-48 flex justify-center items-center border-2 border-gray-300 rounded-full">
|
||||||
|
{/* Compass Circle */}
|
||||||
|
<div
|
||||||
|
className="absolute w-full h-full border-2 border-gray-300 rounded-full flex justify-center items-center"
|
||||||
|
style={{ rotate: `${globalCampass}deg` }}
|
||||||
|
>
|
||||||
|
{/* N, S, E, W Labels */}
|
||||||
|
<div className="absolute top-2 text-lg font-bold">N</div>
|
||||||
|
<div className="absolute bottom-2 text-lg font-bold">S</div>
|
||||||
|
<div className="absolute right-2 text-lg font-bold" style={{ rotate: '90deg' }}>
|
||||||
|
E
|
||||||
|
</div>
|
||||||
|
<div className="absolute left-2 text-lg font-bold" style={{ rotate: '-90deg' }}>
|
||||||
|
W
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Compass Pointer */}
|
||||||
|
<div className="relative w-10 h-10">
|
||||||
|
{/* Red Upper Triangle */}
|
||||||
|
<div
|
||||||
|
className="absolute top-0"
|
||||||
|
style={{
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
rotate: `${globalCampass - 180}deg`,
|
||||||
|
borderLeft: '15px solid transparent',
|
||||||
|
borderRight: '15px solid transparent',
|
||||||
|
borderTop: '60px solid red',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex justify-start my-8 mx-2 w-full">
|
<div className="flex justify-start my-8 mx-2 w-full">
|
||||||
<canvas ref={canvasRef} id="canvas" style={{ border: '1px solid black' }} />
|
<canvas ref={canvasRef} id="canvas" style={{ border: '1px solid black' }} />
|
||||||
{!canvas ? null : mode === Mode.DRAW_LINE ? (
|
{!canvas ? null : mode === Mode.DRAW_LINE ? (
|
||||||
|
|||||||
@ -428,6 +428,7 @@ export function useCanvas(id) {
|
|||||||
'minY',
|
'minY',
|
||||||
'x',
|
'x',
|
||||||
'y',
|
'y',
|
||||||
|
'stickeyPoint',
|
||||||
])
|
])
|
||||||
|
|
||||||
const str = JSON.stringify(objs)
|
const str = JSON.stringify(objs)
|
||||||
|
|||||||
@ -144,3 +144,9 @@ export const cadFileCompleteState = atom({
|
|||||||
key: 'cadFileComplete',
|
key: 'cadFileComplete',
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const globalCompassState = atom({
|
||||||
|
key: 'globalCompass',
|
||||||
|
default: 0,
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|||||||
@ -2717,7 +2717,12 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
let arrow = null
|
let arrow = null
|
||||||
let points = []
|
let points = []
|
||||||
|
|
||||||
|
if (polygon.arrow) {
|
||||||
|
polygon.canvas.remove(polygon.arrow)
|
||||||
|
}
|
||||||
|
|
||||||
let centerPoint = polygon.getCenterPoint()
|
let centerPoint = polygon.getCenterPoint()
|
||||||
|
let stickeyPoint
|
||||||
|
|
||||||
const polygonMaxX = Math.max(...polygon.points.map((point) => point.x))
|
const polygonMaxX = Math.max(...polygon.points.map((point) => point.x))
|
||||||
const polygonMinX = Math.min(...polygon.points.map((point) => point.x))
|
const polygonMinX = Math.min(...polygon.points.map((point) => point.x))
|
||||||
@ -2736,6 +2741,8 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
{ x: centerPoint.x - 20, y: polygonMinY - 50 },
|
{ x: centerPoint.x - 20, y: polygonMinY - 50 },
|
||||||
{ x: centerPoint.x - 20, y: polygonMinY - 20 },
|
{ x: centerPoint.x - 20, y: polygonMinY - 20 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
stickeyPoint = { x: centerPoint.x, y: polygonMinY - 80 }
|
||||||
break
|
break
|
||||||
case 'south':
|
case 'south':
|
||||||
points = [
|
points = [
|
||||||
@ -2748,6 +2755,7 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
{ x: centerPoint.x - 20, y: polygonMaxY + 50 },
|
{ x: centerPoint.x - 20, y: polygonMaxY + 50 },
|
||||||
{ x: centerPoint.x - 20, y: polygonMaxY + 20 },
|
{ x: centerPoint.x - 20, y: polygonMaxY + 20 },
|
||||||
]
|
]
|
||||||
|
stickeyPoint = { x: centerPoint.x, y: polygonMaxY + 80 }
|
||||||
break
|
break
|
||||||
case 'west':
|
case 'west':
|
||||||
points = [
|
points = [
|
||||||
@ -2760,6 +2768,8 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
{ x: polygonMinX - 50, y: centerPoint.y - 20 },
|
{ x: polygonMinX - 50, y: centerPoint.y - 20 },
|
||||||
{ x: polygonMinX - 20, y: centerPoint.y - 20 },
|
{ x: polygonMinX - 20, y: centerPoint.y - 20 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
stickeyPoint = { x: polygonMinX - 80, y: centerPoint.y }
|
||||||
break
|
break
|
||||||
case 'east':
|
case 'east':
|
||||||
points = [
|
points = [
|
||||||
@ -2772,16 +2782,227 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
{ x: polygonMaxX + 50, y: centerPoint.y - 20 },
|
{ x: polygonMaxX + 50, y: centerPoint.y - 20 },
|
||||||
{ x: polygonMaxX + 20, y: centerPoint.y - 20 },
|
{ x: polygonMaxX + 20, y: centerPoint.y - 20 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
stickeyPoint = { x: polygonMaxX + 80, y: centerPoint.y }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
arrow = new fabric.Polygon(points, {
|
arrow = new fabric.Polygon(points, {
|
||||||
selectable: false,
|
selectable: false,
|
||||||
|
name: 'arrow',
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
|
direction: direction,
|
||||||
|
parent: polygon,
|
||||||
|
stickeyPoint: stickeyPoint,
|
||||||
})
|
})
|
||||||
|
|
||||||
polygon.arrow = arrow
|
polygon.arrow = arrow
|
||||||
polygon.canvas.add(arrow)
|
polygon.canvas.add(arrow)
|
||||||
polygon.canvas.renderAll()
|
polygon.canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 방향을 나타낸 화살표에 각도에 따라 글씨 추가
|
||||||
|
* @param canvas
|
||||||
|
* @param compass
|
||||||
|
*/
|
||||||
|
export const drawDirectionStringToArrow = (canvas, compass, fontSize) => {
|
||||||
|
const arrows = canvas?.getObjects().filter((obj) => obj.name === 'arrow')
|
||||||
|
|
||||||
|
if (arrows.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const eastArrows = arrows.filter((arrow) => arrow.direction === 'east')
|
||||||
|
const westArrows = arrows.filter((arrow) => arrow.direction === 'west')
|
||||||
|
const northArrows = arrows.filter((arrow) => arrow.direction === 'north')
|
||||||
|
const southArrows = arrows.filter((arrow) => arrow.direction === 'south')
|
||||||
|
|
||||||
|
let southText = '南'
|
||||||
|
let eastText = '東'
|
||||||
|
let westText = '西'
|
||||||
|
let northText = '北'
|
||||||
|
|
||||||
|
if (compass === 0 || compass === 360) {
|
||||||
|
// 남,동,서 가능
|
||||||
|
// 그대로
|
||||||
|
} else if (compass < 45) {
|
||||||
|
//남(남남동),동(동북동),서(서남서) 가능
|
||||||
|
//북(북북서)
|
||||||
|
southText = '南南東'
|
||||||
|
eastText = '東北東'
|
||||||
|
westText = '西南西'
|
||||||
|
northText = '北北西'
|
||||||
|
} else if (compass === 45) {
|
||||||
|
// 남, 서 가능
|
||||||
|
// 남(남동)
|
||||||
|
// 서(남서)
|
||||||
|
// 북(북서)
|
||||||
|
// 동(북동)
|
||||||
|
southText = '南東'
|
||||||
|
westText = '南西'
|
||||||
|
northText = '北西'
|
||||||
|
eastText = '北東'
|
||||||
|
} else if (compass < 90) {
|
||||||
|
// 북(서북서)
|
||||||
|
// 동 (북북동)
|
||||||
|
// 남(동남동)
|
||||||
|
// 서(남남서)
|
||||||
|
northText = '北西北'
|
||||||
|
eastText = '北北東'
|
||||||
|
southText = '東南東'
|
||||||
|
westText = '南南西'
|
||||||
|
} else if (compass === 90) {
|
||||||
|
// 동(북)
|
||||||
|
// 서(남)
|
||||||
|
// 남(동)
|
||||||
|
// 북(서)
|
||||||
|
eastText = '北'
|
||||||
|
westText = '南'
|
||||||
|
southText = '東'
|
||||||
|
northText = '西'
|
||||||
|
} else if (compass < 135) {
|
||||||
|
// 남,서,북 가능
|
||||||
|
// 동(북북서)
|
||||||
|
// 서(남남동)
|
||||||
|
// 남(동북동)
|
||||||
|
// 북(서남서)
|
||||||
|
eastText = '北北西'
|
||||||
|
westText = '南南東'
|
||||||
|
southText = '東北東'
|
||||||
|
northText = '西南西'
|
||||||
|
} else if (compass === 135) {
|
||||||
|
// 서,북 가능
|
||||||
|
|
||||||
|
// 서(남동)
|
||||||
|
// 북(남서)
|
||||||
|
// 남(북동)
|
||||||
|
// 동(북서)
|
||||||
|
|
||||||
|
westText = '南東'
|
||||||
|
northText = '南西'
|
||||||
|
southText = '北東'
|
||||||
|
eastText = '北西'
|
||||||
|
} else if (compass < 180) {
|
||||||
|
// 북,동,서 가능
|
||||||
|
// 북(남남서)
|
||||||
|
// 동(서북서)
|
||||||
|
// 남(북북동)
|
||||||
|
// 서(동남동)
|
||||||
|
|
||||||
|
northText = '南南西'
|
||||||
|
eastText = '西北西'
|
||||||
|
southText = '北北東'
|
||||||
|
westText = '東南東'
|
||||||
|
} else if (compass === 180) {
|
||||||
|
// 북,동,서 가능
|
||||||
|
// 북(남)
|
||||||
|
// 동(서)
|
||||||
|
// 남(북)
|
||||||
|
// 서(동)
|
||||||
|
northText = '南'
|
||||||
|
eastText = '西'
|
||||||
|
southText = '北'
|
||||||
|
westText = '東'
|
||||||
|
} else if (compass < 225) {
|
||||||
|
// 서,북,동 가능
|
||||||
|
// 북(남남동)
|
||||||
|
// 동(서남서)
|
||||||
|
// 남(북북서)
|
||||||
|
// 서(동남동)
|
||||||
|
northText = '南南東'
|
||||||
|
eastText = '西南西'
|
||||||
|
southText = '北北西'
|
||||||
|
westText = '東南東'
|
||||||
|
} else if (compass === 225) {
|
||||||
|
// 북,동 가능
|
||||||
|
// 북(남동)
|
||||||
|
// 동(남서)
|
||||||
|
// 남(북서)
|
||||||
|
// 서(북동)
|
||||||
|
northText = '南東'
|
||||||
|
eastText = '南西'
|
||||||
|
southText = '北西'
|
||||||
|
westText = '北東'
|
||||||
|
} else if (compass < 270) {
|
||||||
|
// 북동남 가능
|
||||||
|
// 북(동남동)
|
||||||
|
// 동(남남서)
|
||||||
|
// 남(서북서)
|
||||||
|
// 서(북북동)
|
||||||
|
northText = '東南東'
|
||||||
|
eastText = '南南西'
|
||||||
|
southText = '西北西'
|
||||||
|
westText = '北北東'
|
||||||
|
} else if (compass === 270) {
|
||||||
|
// 북동남 가능
|
||||||
|
// 북(동)
|
||||||
|
// 동(남)
|
||||||
|
// 남(서)
|
||||||
|
// 서(북)
|
||||||
|
northText = '東'
|
||||||
|
eastText = '南'
|
||||||
|
southText = '西'
|
||||||
|
westText = '北'
|
||||||
|
} else if (compass < 315) {
|
||||||
|
// 북,동,남 가능
|
||||||
|
// 북(동북동)
|
||||||
|
// 동(남남동)
|
||||||
|
// 남(서남서)
|
||||||
|
// 서(북북서)
|
||||||
|
northText = '東北東'
|
||||||
|
eastText = '南南東'
|
||||||
|
southText = '西南西'
|
||||||
|
westText = '北北西'
|
||||||
|
} else if (compass === 315) {
|
||||||
|
// 동,남 가능
|
||||||
|
// 북(북동)
|
||||||
|
// 동(남동)
|
||||||
|
// 남(남서)
|
||||||
|
// 서(북서)
|
||||||
|
northText = '北東'
|
||||||
|
eastText = '南東'
|
||||||
|
southText = '南西'
|
||||||
|
westText = '北西'
|
||||||
|
} else if (compass < 360) {
|
||||||
|
// 남,동,서 가능
|
||||||
|
// 북(북북동)
|
||||||
|
// 동(동남동)
|
||||||
|
// 남(남남서)
|
||||||
|
// 서(서북서)
|
||||||
|
northText = '北北東'
|
||||||
|
eastText = '東南東'
|
||||||
|
southText = '南南西'
|
||||||
|
westText = '西北西'
|
||||||
|
}
|
||||||
|
|
||||||
|
clearDirectionText(canvas)
|
||||||
|
|
||||||
|
addTextByArrows(eastArrows, eastText, canvas)
|
||||||
|
addTextByArrows(westArrows, westText, canvas)
|
||||||
|
addTextByArrows(northArrows, northText, canvas)
|
||||||
|
addTextByArrows(southArrows, southText, canvas)
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearDirectionText = (canvas) => {
|
||||||
|
const texts = canvas.getObjects().filter((obj) => obj.name === 'directionText')
|
||||||
|
texts.forEach((text) => {
|
||||||
|
canvas.remove(text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addTextByArrows = (arrows, txt, canvas) => {
|
||||||
|
arrows.forEach((arrow, index) => {
|
||||||
|
const text = new fabric.Text(`${txt}${index + 1}`, {
|
||||||
|
fontSize: arrow.parent.fontSize,
|
||||||
|
fill: 'black',
|
||||||
|
originX: 'center',
|
||||||
|
originY: 'center',
|
||||||
|
name: 'directionText',
|
||||||
|
left: arrow.stickeyPoint.x,
|
||||||
|
top: arrow.stickeyPoint.y,
|
||||||
|
})
|
||||||
|
canvas.add(text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user