모듈회로구성 기본설정 => 방위 설정 추가

This commit is contained in:
hyojun.choi 2024-11-12 13:32:07 +09:00
parent 99aa175a1f
commit 0f1e7709b6
8 changed files with 192 additions and 26 deletions

View File

@ -76,7 +76,6 @@ export const LINE_TYPE = {
HIP: 'hip',
RIDGE: 'ridge',
GABLE: 'gable',
VALLEY: 'valley',
VERGE: 'verge',
ONESIDE_FLOW_RIDGE: 'onesideFlowRidge', //한쪽흐름 용마루
YOSEMUNE: 'yosemune', //요세무네
@ -158,6 +157,8 @@ export const SAVE_KEY = [
'lines',
'offset',
'arrow',
'surfaceCompass',
'moduleCompass',
]
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype]

View File

@ -1,7 +1,6 @@
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useState } from 'react'
import Orientation from '@/components/floor-plan/modal/basic/step/Orientation'
import { useEffect, useRef, useState } from 'react'
import Module from '@/components/floor-plan/modal/basic/step/Module'
import PitchModule from '@/components/floor-plan/modal/basic/step/pitch/PitchModule'
import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement'
@ -9,12 +8,22 @@ import Placement from '@/components/floor-plan/modal/basic/step/Placement'
import { useRecoilState } from 'recoil'
import { canvasSettingState } from '@/store/canvasAtom'
import { usePopup } from '@/hooks/usePopup'
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [tabNum, setTabNum] = useState(1)
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
const orientationRef = useRef(null)
const handleBtnNextStep = () => {
if (tabNum === 1) {
orientationRef.current.handleNextStep()
}
setTabNum(tabNum + 1)
}
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lx-2`}>
@ -32,7 +41,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
<span className={`tab-arr ${tabNum === 3 ? 'act' : ''}`}></span>
<div className={`module-tab-bx ${tabNum === 3 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
</div>
{tabNum === 1 && <Orientation setTabNum={setTabNum} />}
{tabNum === 1 && <Orientation ref={orientationRef} tabNum={tabNum} setTabNum={setTabNum} />}
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 2 && <Module setTabNum={setTabNum} />}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 3 && <Placement setTabNum={setTabNum} />}
@ -49,7 +58,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
)}
{/*{tabNum !== 3 && <button className="btn-frame modal act mr5">{getMessage('modal.common.save')}</button>}*/}
{tabNum !== 3 && (
<button className="btn-frame modal" onClick={() => setTabNum(tabNum + 1)}>
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}

View File

@ -1,22 +1,21 @@
import { useState } from 'react'
import { forwardRef, useImperativeHandle, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { useOrientation } from '@/hooks/popup/useOrientation'
import { getDegreeInOrientation } from '@/util/canvas-util'
export default function Orientation({ setTabNum }) {
export const Orientation = forwardRef(({ tabNum }, ref) => {
const { getMessage } = useMessage()
const [compasDeg, setCompasDeg] = useState(0)
const { nextStep, compasDeg, setCompasDeg } = useOrientation()
const [hasAnglePassivity, setHasAnglePassivity] = useState(false)
const getDegree = (degree) => {
if (degree % 15 === 0) return degree
useImperativeHandle(ref, () => ({
handleNextStep,
}))
let value = Math.floor(degree / 15)
const remain = ((degree / 15) % 1).toFixed(5)
if (remain > 0.4) {
value++
}
return value * 15
const handleNextStep = () => {
nextStep()
}
return (
@ -31,7 +30,7 @@ export default function Orientation({ setTabNum }) {
{Array.from({ length: 180 / 15 }).map((dot, index) => (
<div
key={index}
className={`circle ${getDegree(compasDeg) === 15 * (12 + index) ? 'act' : ''}`}
className={`circle ${getDegreeInOrientation(compasDeg) === 15 * (12 + index) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (12 + index))}
>
{index === 0 && <i>180°</i>}
@ -39,13 +38,17 @@ export default function Orientation({ setTabNum }) {
</div>
))}
{Array.from({ length: 180 / 15 }).map((dot, index) => (
<div key={index} className={`circle ${getDegree(compasDeg) === 15 * index ? 'act' : ''}`} onClick={() => setCompasDeg(15 * index)}>
<div
key={index}
className={`circle ${getDegreeInOrientation(compasDeg) === 15 * index ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * index)}
>
{index === 0 && <i>0°</i>}
{index === 6 && <i>90°</i>}
</div>
))}
<div className="compas">
<div className="compas-arr" style={{ transform: `rotate(${getDegree(compasDeg)}deg)` }}></div>
<div className="compas-arr" style={{ transform: `rotate(${getDegreeInOrientation(compasDeg)}deg)` }}></div>
</div>
</div>
</div>
@ -62,7 +65,11 @@ export default function Orientation({ setTabNum }) {
className="input-origin block"
value={compasDeg}
readOnly={hasAnglePassivity}
onChange={(e) => setCompasDeg(e.target.value !== '' ? Number.parseInt(e.target.value) : 0)}
onChange={(e) =>
setCompasDeg(
e.target.value !== '' && parseInt(e.target.value) <= 360 && parseInt(e.target.value) >= 0 ? Number.parseInt(e.target.value) : 0,
)
}
/>
</div>
<span className="thin">°</span>
@ -72,4 +79,4 @@ export default function Orientation({ setTabNum }) {
</div>
</>
)
}
})

View File

@ -21,7 +21,7 @@ export function useFlowDirectionSetting(id) {
direction: direction,
surfaceCompass: orientation,
})
// drawDirectionArrow(roof)
drawDirectionArrow(roof)
canvas?.renderAll()
closePopup(id)
}

View File

@ -0,0 +1,25 @@
import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom'
import { usePolygon } from '@/hooks/usePolygon'
import { POLYGON_TYPE } from '@/common/common'
import { compasDegAtom } from '@/store/orientationAtom'
// 모듈,회로 구성 탭 기본설정 > 방위설정 탭
export function useOrientation() {
const canvas = useRecoilValue(canvasState)
const [compasDeg, setCompasDeg] = useRecoilState(compasDegAtom)
const { drawDirectionArrow } = usePolygon()
const nextStep = () => {
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
roofs.forEach((roof) => {
roof.set({
moduleCompass: compasDeg,
})
drawDirectionArrow(roof)
})
}
return { nextStep, compasDeg, setCompasDeg }
}

View File

@ -1,7 +1,7 @@
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, fontFamilyState, fontSizeState, pitchTextSelector } from '@/store/canvasAtom'
import { useRecoilValue } from 'recoil'
import { fabric } from 'fabric'
import { getDegreeByChon, getDirectionByPoint, isPointOnLine } from '@/util/canvas-util'
import { getDegreeByChon, getDegreeInOrientation, getDirectionByPoint, isPointOnLine } from '@/util/canvas-util'
import { QPolygon } from '@/components/fabric/QPolygon'
import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils'
import { flowDisplaySelector } from '@/store/settingAtom'
@ -283,12 +283,113 @@ export const usePolygon = () => {
//arrow의 compass 값으로 방향 글자 설정 필요
const drawDirectionStringToArrow2 = (polygon) => {
const { direction, surfaceCompass, moduleCompass, arrow } = polygon
if (moduleCompass === null || moduleCompass === undefined) {
const textObj = new fabric.Text(`${currentAngleType === ANGLE_TYPE.SLOPE ? arrow.pitch : getDegreeByChon(arrow.pitch)}${pitchText}`, {
fontSize: flowFontOptions.fontSize.value,
fill: flowFontOptions.fontColor.value,
fontFamily: flowFontOptions.fontFamily.value,
fontWeight: flowFontOptions.fontWeight.value,
originX: 'center',
originY: 'center',
name: 'flowText',
selectable: false,
left: arrow.stickeyPoint.x,
top: arrow.stickeyPoint.y,
parent: arrow,
parentId: arrow.id,
visible: isFlowDisplay,
})
if (!surfaceCompass && !moduleCompass) {
polygon.canvas.add(textObj)
return
}
let text = ''
console.log('direction', direction, surfaceCompass, moduleCompass)
const compassType = (375 - moduleCompass) / 15
if ([1, 25].includes(compassType)) {
direction === 'north' ? (text = '北') : direction === 'south' ? (text = '南') : direction === 'west' ? (text = '西') : (text = '東')
} else if ([2, 3].includes(compassType)) {
direction === 'north'
? (text = '北北東')
: direction === 'south'
? (text = '南南西')
: direction === 'west'
? (text = '西北西')
: (text = '東南東')
} else if ([4].includes(compassType)) {
direction === 'north' ? (text = '北東') : direction === 'south' ? (text = '南西') : direction === 'west' ? (text = '北西') : (text = '南東')
} else if ([5, 6].includes(compassType)) {
direction === 'north'
? (text = '東北東')
: direction === 'south'
? (text = '西南西')
: direction === 'west'
? (text = '北北西')
: (text = '南南東')
} else if ([7].includes(compassType)) {
direction === 'north' ? (text = '東') : direction === 'south' ? (text = '西') : direction === 'west' ? (text = '北') : (text = '南')
} else if ([8, 9].includes(compassType)) {
direction === 'north'
? (text = '東南東')
: direction === 'south'
? (text = '西北西')
: direction === 'west'
? (text = '北北東')
: (text = '南南西')
} else if ([10].includes(compassType)) {
direction === 'north' ? (text = '南東') : direction === 'south' ? (text = '北西') : direction === 'west' ? (text = '南西') : (text = '北東')
} else if ([11, 12].includes(compassType)) {
direction === 'north'
? (text = '南南東')
: direction === 'south'
? (text = '北北西')
: direction === 'west'
? (text = '東北東')
: (text = '西南西')
} else if ([13].includes(compassType)) {
direction === 'north' ? (text = '南') : direction === 'south' ? (text = '北') : direction === 'west' ? (text = '東') : (text = '西')
} else if ([14, 15].includes(compassType)) {
direction === 'north'
? (text = '南南西')
: direction === 'south'
? (text = '北北東')
: direction === 'west'
? (text = '東南東')
: (text = '西北西')
} else if ([16].includes(compassType)) {
direction === 'north' ? (text = '南西') : direction === 'south' ? (text = '北東') : direction === 'west' ? (text = '南東') : (text = '北西')
} else if ([17, 18].includes(compassType)) {
direction === 'north'
? (text = '西南西')
: direction === 'south'
? (text = '東北東')
: direction === 'west'
? (text = '南南東')
: (text = '北北西')
} else if ([19].includes(compassType)) {
direction === 'north' ? (text = '西') : direction === 'south' ? (text = '東') : direction === 'west' ? (text = '南') : (text = '北')
} else if ([20, 21].includes(compassType)) {
direction === 'north'
? (text = '西北西')
: direction === 'south'
? (text = '東南東')
: direction === 'west'
? (text = '南南西')
: (text = '北北東')
} else if ([22].includes(compassType)) {
direction === 'north' ? (text = '北西') : direction === 'south' ? (text = '南東') : direction === 'west' ? (text = '南西') : (text = '北東')
} else if ([23, 24].includes(compassType)) {
direction === 'north'
? (text = '北北西')
: direction === 'south'
? (text = '南南東')
: direction === 'west'
? (text = '西南西')
: (text = '東北東')
}
// 東,西,南,北
if ([360].includes(surfaceCompass)) {

View File

@ -0,0 +1,6 @@
import { atom } from 'recoil'
export const compasDegAtom = atom({
key: 'compasDegAtom',
default: 0,
})

View File

@ -954,3 +954,20 @@ export const getAllRelatedObjects = (id, canvas) => {
return result
}
// 모듈,회로 구성에서 사용하는 degree 범위 별 값
export const getDegreeInOrientation = (degree) => {
if (degree >= 352) {
return 0
}
if (degree % 15 === 0) return degree
let value = Math.floor(degree / 15)
const remain = ((degree / 15) % 1).toFixed(5)
if (remain > 0.4) {
value++
}
return value * 15
}