# Conflicts: # src/common/common.js # src/components/floor-plan/CanvasFrame.jsx # src/hooks/roofcover/useWallLineOffsetSetting.js # src/util/qpolygon-utils.js
201 lines
7.2 KiB
JavaScript
201 lines
7.2 KiB
JavaScript
'use client'
|
|
|
|
import { useContext, useEffect, useRef } from 'react'
|
|
|
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
|
|
|
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
|
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
|
|
import { useCanvas } from '@/hooks/useCanvas'
|
|
import { usePlan } from '@/hooks/usePlan'
|
|
import { useContextMenu } from '@/hooks/useContextMenu'
|
|
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
|
import { currentMenuState } from '@/store/canvasAtom'
|
|
import { roofMaterialsAtom, totalDisplaySelector } from '@/store/settingAtom'
|
|
import { MENU, POLYGON_TYPE } from '@/common/common'
|
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
|
import { QcastContext } from '@/app/QcastProvider'
|
|
import {
|
|
makersState,
|
|
modelsState,
|
|
moduleStatisticsState,
|
|
pcsCheckState,
|
|
selectedMakerState,
|
|
selectedModelsState,
|
|
seriesState,
|
|
} from '@/store/circuitTrestleAtom'
|
|
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
|
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
|
import { useEvent } from '@/hooks/useEvent'
|
|
import { compasDegAtom } from '@/store/orientationAtom'
|
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
|
import { hotkeyStore } from '@/store/hotkeyAtom'
|
|
import { usePopup } from '@/hooks/usePopup'
|
|
|
|
export default function CanvasFrame() {
|
|
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
|
const { getRoofMaterialList } = useMasterController()
|
|
useEffect(() => {
|
|
async function initRoofMaterial() {
|
|
if (roofMaterials.length !== 0) {
|
|
return
|
|
}
|
|
const { data } = await getRoofMaterialList()
|
|
|
|
const roofLists = data.map((item, idx) => ({
|
|
...item,
|
|
id: item.roofMatlCd,
|
|
name: item.roofMatlNm,
|
|
selected: idx === 0,
|
|
index: idx,
|
|
nameJp: item.roofMatlNmJp,
|
|
length: item.lenBase && parseInt(item.lenBase),
|
|
width: item.widBase && parseInt(item.widBase),
|
|
raft: item.raftBase && parseInt(item.raftBase),
|
|
layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL,
|
|
hajebichi: item.roofPchBase && parseInt(item.roofPchBase),
|
|
pitch: item.pitch ? parseInt(item.pitch) : 4,
|
|
angle: item.angle ? parseInt(item.angle) : 21.8,
|
|
}))
|
|
setRoofMaterials(roofLists)
|
|
}
|
|
initRoofMaterial()
|
|
}, [])
|
|
const canvasRef = useRef(null)
|
|
const { canvas } = useCanvas('canvas')
|
|
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
|
|
const { closeAll } = usePopup()
|
|
const currentMenu = useRecoilValue(currentMenuState)
|
|
const { floorPlanState } = useContext(FloorPlanContext)
|
|
const { contextMenu, handleClick } = useContextMenu()
|
|
const { plans, currentCanvasPlan, resetCanvasStatus } = usePlan()
|
|
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
|
const resetModuleStatisticsState = useResetRecoilState(moduleStatisticsState)
|
|
const resetMakersState = useResetRecoilState(makersState)
|
|
const resetSelectedMakerState = useResetRecoilState(selectedMakerState)
|
|
const resetSeriesState = useResetRecoilState(seriesState)
|
|
const resetModelsState = useResetRecoilState(modelsState)
|
|
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
|
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
|
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
|
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
|
const { basicSetting, fetchBasicSettings } = useCanvasSetting()
|
|
const { selectedMenu, setSelectedMenu } = useCanvasMenu()
|
|
const { initEvent } = useEvent()
|
|
const loadCanvas = () => {
|
|
if (!canvas) return
|
|
|
|
canvas?.clear() // 캔버스를 초기화합니다.
|
|
if (currentCanvasPlan) {
|
|
const plan = plans.find((plan) => plan.id === currentCanvasPlan.id)
|
|
if (plan?.canvasStatus && floorPlanState.objectNo === currentCanvasPlan.objectNo) {
|
|
canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
|
|
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
|
canvas?.renderAll() // 캔버스를 다시 그립니다.
|
|
|
|
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
|
|
setSelectedMenu('module')
|
|
} else {
|
|
setSelectedMenu('surface')
|
|
}
|
|
initEvent()
|
|
})
|
|
}
|
|
Object.keys(currentCanvasPlan).length > 0 && canvas && handleModuleSelectionTotal()
|
|
}
|
|
gridInit()
|
|
}
|
|
|
|
useEffect(() => {
|
|
loadCanvas()
|
|
resetRecoilData()
|
|
|
|
/* 플랜번호가 있으면 베이직세팅 팝업 데이터 로드 */
|
|
if (currentCanvasPlan.planNo) {
|
|
/* 약간의 지연을 줘서 roofMaterials가 로드될 시간을 확보 */
|
|
setTimeout(() => {
|
|
fetchBasicSettings(Number(currentCanvasPlan.planNo), null)
|
|
}, 100)
|
|
}
|
|
}, [currentCanvasPlan, canvas])
|
|
|
|
useEffect(() => {
|
|
setIsGlobalLoading(false)
|
|
// 혹시 모를 팝업이 떠있는 경우 닫고 시작한다.
|
|
closeAll()
|
|
|
|
return () => {
|
|
canvas?.clear()
|
|
resetCanvasStatus()
|
|
}
|
|
}, [])
|
|
|
|
const resetRecoilData = () => {
|
|
// resetModuleStatisticsState()
|
|
resetMakersState()
|
|
resetSelectedMakerState()
|
|
resetSeriesState()
|
|
resetModelsState()
|
|
resetCompasDeg()
|
|
resetSelectedModelsState()
|
|
resetPcsCheckState()
|
|
}
|
|
|
|
/**
|
|
* 캔버스가 있을 경우 핫키 이벤트 처리
|
|
* hotkeyStore에 핫키 이벤트 리스너 추가
|
|
*
|
|
* const hotkeys = [
|
|
{ key: 'c', fn: () => asdf() },
|
|
{ key: 'v', fn: () => qwer() },
|
|
]
|
|
setHotkeyStore(hotkeys)
|
|
*/
|
|
const hotkeyState = useRecoilValue(hotkeyStore)
|
|
const hotkeyHandlerRef = useRef(null)
|
|
|
|
useEffect(() => {
|
|
hotkeyHandlerRef.current = (e) => {
|
|
hotkeyState.forEach((hotkey) => {
|
|
if (e.key === hotkey.key) {
|
|
hotkey.fn()
|
|
}
|
|
})
|
|
}
|
|
|
|
document.addEventListener('keyup', hotkeyHandlerRef.current)
|
|
|
|
return () => {
|
|
if (hotkeyHandlerRef.current) {
|
|
document.removeEventListener('keyup', hotkeyHandlerRef.current)
|
|
}
|
|
}
|
|
}, [hotkeyState])
|
|
/** 핫키 이벤트 처리 끝 */
|
|
|
|
return (
|
|
<div className="canvas-frame">
|
|
<canvas ref={canvasRef} id="canvas" style={{ position: 'relative' }}></canvas>
|
|
|
|
<QContextMenu contextRef={canvasRef} canvasProps={canvas}>
|
|
{contextMenu?.map((menus, index) => (
|
|
<ul key={index}>
|
|
{menus.map((menu) => (
|
|
<li key={menu.id} onClick={(e) => handleClick(e, menu)}>
|
|
{menu.name}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
))}
|
|
</QContextMenu>
|
|
{selectedMenu === 'module' && totalDisplay && <PanelBatchStatistics />}
|
|
{/* 이미지 로드 팝업 */}
|
|
<ImgLoad />
|
|
</div>
|
|
)
|
|
}
|