diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx
index 93e03304..ecbc083b 100644
--- a/src/components/Roof2.jsx
+++ b/src/components/Roof2.jsx
@@ -5,7 +5,7 @@ import { useEffect, useRef, useState } from 'react'
import { v4 as uuidv4 } from 'uuid'
import { useMode } from '@/hooks/useMode'
import { Mode } from '@/common/common'
-import { Button } from '@nextui-org/react'
+import { Button, Input } from '@nextui-org/react'
import RangeSlider from './ui/RangeSlider'
import { useRecoilState, useRecoilValue } from 'recoil'
import {
@@ -15,6 +15,7 @@ import {
compassState,
currentObjectState,
fontSizeState,
+ globalCompassState,
roofMaterialState,
roofState,
sortedPolygonArray,
@@ -24,20 +25,20 @@ import {
} from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
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 ThumbnailList from './ui/ThumbnailLIst'
import QContextMenu from './common/context-menu/QContextMenu'
import { modalContent, modalState } from '@/store/modalAtom'
import { useAxios } from '@/hooks/useAxios'
import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu'
import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu'
import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu'
-import { degreesToRadians, point, radiansToDegrees } from '@turf/turf'
import InitSettingsModal from './InitSettingsModal'
import GridSettingsModal from './GridSettingsModal'
import { SurfaceShapeModal } from '@/components/ui/SurfaceShape'
+import { drawDirectionStringToArrow } from '@/util/qpolygon-utils'
+import ThumbnailList from '@/components/ui/ThumbnailLIst'
export default function Roof2(props) {
const { name, userId, email, isLoggedIn } = props
@@ -105,6 +106,8 @@ export default function Roof2(props) {
let imgPath
useCadFile && (imgPath = `/cadImages/${cadFileName}`)
+ const [globalCampass, setGlobalCampass] = useRecoilState(globalCompassState)
+
const {
mode,
setMode,
@@ -608,6 +611,10 @@ export default function Roof2(props) {
const moduleConfiguration = () => {
createRoofRack()
}
+
+ const setDirectionStringToArrow = () => {
+ drawDirectionStringToArrow(canvas, globalCampass)
+ }
return (
<>
{canvas && (
@@ -854,6 +861,58 @@ export default function Roof2(props) {
>
)}
+
+
각도 입력(0~360) 후 방향설정 클릭
+
{
+ const val = e.target.value.replace(/[^-0-9]/g, '')
+ if (val < 0 || val > 360) {
+ setGlobalCampass(0)
+ } else {
+ setGlobalCampass(Number(val))
+ }
+ }}
+ />
+
+
+
+ {/* Compass Circle */}
+
+ {/* N, S, E, W Labels */}
+
N
+
S
+
+ E
+
+
+ W
+
+
+
+ {/* Compass Pointer */}
+
+ {/* Red Upper Triangle */}
+
+
+
{!canvas ? null : mode === Mode.DRAW_LINE ? (
diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js
index e4902c33..043a561f 100644
--- a/src/hooks/useCanvas.js
+++ b/src/hooks/useCanvas.js
@@ -428,6 +428,7 @@ export function useCanvas(id) {
'minY',
'x',
'y',
+ 'stickeyPoint',
])
const str = JSON.stringify(objs)
diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js
index f2bbfa3a..a675b508 100644
--- a/src/store/canvasAtom.js
+++ b/src/store/canvasAtom.js
@@ -144,3 +144,9 @@ export const cadFileCompleteState = atom({
key: 'cadFileComplete',
default: false,
})
+
+export const globalCompassState = atom({
+ key: 'globalCompass',
+ default: 0,
+ dangerouslyAllowMutability: true,
+})
diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js
index f89652f1..5e00b197 100644
--- a/src/util/qpolygon-utils.js
+++ b/src/util/qpolygon-utils.js
@@ -2717,7 +2717,12 @@ export const drawDirectionArrow = (polygon) => {
let arrow = null
let points = []
+ if (polygon.arrow) {
+ polygon.canvas.remove(polygon.arrow)
+ }
+
let centerPoint = polygon.getCenterPoint()
+ let stickeyPoint
const polygonMaxX = Math.max(...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 - 20 },
]
+
+ stickeyPoint = { x: centerPoint.x, y: polygonMinY - 80 }
break
case 'south':
points = [
@@ -2748,6 +2755,7 @@ export const drawDirectionArrow = (polygon) => {
{ x: centerPoint.x - 20, y: polygonMaxY + 50 },
{ x: centerPoint.x - 20, y: polygonMaxY + 20 },
]
+ stickeyPoint = { x: centerPoint.x, y: polygonMaxY + 80 }
break
case 'west':
points = [
@@ -2760,6 +2768,8 @@ export const drawDirectionArrow = (polygon) => {
{ x: polygonMinX - 50, y: centerPoint.y - 20 },
{ x: polygonMinX - 20, y: centerPoint.y - 20 },
]
+
+ stickeyPoint = { x: polygonMinX - 80, y: centerPoint.y }
break
case 'east':
points = [
@@ -2772,16 +2782,227 @@ export const drawDirectionArrow = (polygon) => {
{ x: polygonMaxX + 50, y: centerPoint.y - 20 },
{ x: polygonMaxX + 20, y: centerPoint.y - 20 },
]
+
+ stickeyPoint = { x: polygonMaxX + 80, y: centerPoint.y }
break
}
arrow = new fabric.Polygon(points, {
selectable: false,
+ name: 'arrow',
fill: 'transparent',
stroke: 'black',
+ direction: direction,
+ parent: polygon,
+ stickeyPoint: stickeyPoint,
})
polygon.arrow = arrow
polygon.canvas.add(arrow)
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)
+ })
+}