이벤트 분리

This commit is contained in:
hyojun.choi 2024-08-28 13:35:51 +09:00
parent bc77a9725e
commit 5cf29ec019
3 changed files with 292 additions and 246 deletions

View File

@ -425,6 +425,8 @@ export function useCanvas(id) {
'maxY', 'maxY',
'minX', 'minX',
'minY', 'minY',
'x',
'y',
]) ])
const str = JSON.stringify(objs) const str = JSON.stringify(objs)

View File

@ -19,9 +19,9 @@ export function useCanvasEvent() {
canvas?.on('selection:cleared', selectionEvent.cleared) canvas?.on('selection:cleared', selectionEvent.cleared)
canvas?.on('selection:created', selectionEvent.created) canvas?.on('selection:created', selectionEvent.created)
canvas?.on('selection:updated', selectionEvent.updated) canvas?.on('selection:updated', selectionEvent.updated)
canvas?.on('object:added', () => { /*canvas?.on('object:added', () => {
document.addEventListener('keydown', handleKeyDown) document.addEventListener('keydown', handleKeyDown)
}) })*/
canvas?.on('object:removed', objectEvent.removed) canvas?.on('object:removed', objectEvent.removed)
} }

View File

@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react' import { useCallback, useEffect, useRef, useState } from 'react'
import { import {
calculateIntersection, calculateIntersection,
distanceBetweenPoints, distanceBetweenPoints,
@ -64,23 +64,22 @@ export function useMode() {
const compass = useRecoilValue(compassState) const compass = useRecoilValue(compassState)
const [isCellCenter, setIsCellCenter] = useState(false) const [isCellCenter, setIsCellCenter] = useState(false)
const guideLineInfo = useRecoilValue(guideLineState) const [guideLineInfo, setGuideLineInfo] = useRecoilState(guideLineState)
const [guideLineMode, setGuideLineMode] = useState(false) const [guideLineMode, setGuideLineMode] = useState(false)
const [guideDotMode, setGuideDotMode] = useState(false) const [guideDotMode, setGuideDotMode] = useState(false)
const [horiGuideLines, setHoriGuideLines] = useState([])
const [vertGuideLines, setVertGuideLines] = useState([])
useEffect(() => { useEffect(() => {
// 이벤트 리스너 추가
// if (!canvas) { // if (!canvas) {
// canvas?.setZoom(0.8) // canvas?.setZoom(0.8)
// return // return
// } // }
document.addEventListener('keydown', handleKeyDown) if (!canvas) return
setCanvas(canvas)
canvas?.on('mouse:move', drawMouseLines) canvas?.on('mouse:move', drawMouseLines)
// 컴포넌트가 언마운트될 때 이벤트 리스너 제거
return () => {
document.removeEventListener('keydown', handleKeyDown)
}
}, [canvas]) // 빈 배열을 전달하여 컴포넌트가 마운트될 때만 실행되도록 함 }, [canvas]) // 빈 배열을 전달하여 컴포넌트가 마운트될 때만 실행되도록 함
useEffect(() => { useEffect(() => {
@ -103,11 +102,6 @@ export function useMode() {
canvas?.off('mouse:move') canvas?.off('mouse:move')
canvas?.on('mouse:move', drawMouseLines) canvas?.on('mouse:move', drawMouseLines)
changeMode(canvas, mode) changeMode(canvas, mode)
/*
if (mode === Mode.EDIT) {
canvas?.off('mouse:down')
canvas?.on('mouse:down', mouseEvent.editMode)
}*/
}, [mode]) }, [mode])
useEffect(() => { useEffect(() => {
@ -117,6 +111,9 @@ export function useMode() {
const guideLineState = guideLineInfo.filter((item) => item.guideMode === 'guideLine') const guideLineState = guideLineInfo.filter((item) => item.guideMode === 'guideLine')
const guideDotState = guideLineInfo.filter((item) => item.guideMode === 'guideDot') const guideDotState = guideLineInfo.filter((item) => item.guideMode === 'guideDot')
setHoriGuideLines(guideLineState[0].horizontalLineArray)
setVertGuideLines(guideLineState[0].verticalLineArray)
setGuideLineMode(guideLineState.length > 0) setGuideLineMode(guideLineState.length > 0)
setGuideDotMode(guideDotState.length > 0) setGuideDotMode(guideDotState.length > 0)
} }
@ -142,8 +139,8 @@ export function useMode() {
} }
if (isGuideLineMode) { if (isGuideLineMode) {
horizontalLineArray = [...guideLineState[0].horizontalLineArray] horizontalLineArray = [...horiGuideLines]
verticalLineArray = [...guideLineState[0].verticalLineArray] verticalLineArray = [...vertGuideLines]
guideLineLengthHori = Number(guideLineState[0].moduleHoriLength) guideLineLengthHori = Number(guideLineState[0].moduleHoriLength)
guideLineLengthVert = Number(guideLineState[0].moduleVertLength) guideLineLengthVert = Number(guideLineState[0].moduleVertLength)
} }
@ -163,7 +160,6 @@ export function useMode() {
if (mode === Mode.EDIT || mode === Mode.ADSORPTION_POINT) { if (mode === Mode.EDIT || mode === Mode.ADSORPTION_POINT) {
let adsorptionPoint = adsorptionPointList.length > 0 ? findClosestPoint(pointer, adsorptionPointList) : null let adsorptionPoint = adsorptionPointList.length > 0 ? findClosestPoint(pointer, adsorptionPointList) : null
if (isGuideLineMode && isGuideDotMode) { if (isGuideLineMode && isGuideDotMode) {
const closestHorizontalLine = getClosestHorizontalLine(pointer, horizontalLineArray) const closestHorizontalLine = getClosestHorizontalLine(pointer, horizontalLineArray)
const closetVerticalLine = getClosestVerticalLine(pointer, verticalLineArray) const closetVerticalLine = getClosestVerticalLine(pointer, verticalLineArray)
@ -362,12 +358,12 @@ export function useMode() {
// 모드에 따른 마우스 이벤트 변경 // 모드에 따른 마우스 이벤트 변경
const changeMouseEvent = (mode) => { const changeMouseEvent = (mode) => {
canvas?.off('mouse:down') document.removeEventListener('contextmenu', mouseEvent.drawLineModeRightClick)
switch (mode) { switch (mode) {
case 'drawLine': case 'drawLine':
canvas?.on('mouse:down', mouseEvent.drawLineModeLeftClick) canvas?.on('mouse:down', mouseEvent.drawLineModeLeftClick)
window.document.removeEventListener('contextmenu', mouseEvent.drawLineModeRightClick) document.addEventListener('contextmenu', mouseEvent.drawLineModeRightClick)
window.document.addEventListener('contextmenu', mouseEvent.drawLineModeRightClick)
break break
case 'edit': case 'edit':
canvas?.on('mouse:down', mouseEvent.editMode) canvas?.on('mouse:down', mouseEvent.editMode)
@ -394,9 +390,6 @@ export function useMode() {
} }
} }
// 모드에 따른 키보드 이벤트 변경
const changeKeyboardEvent = (mode) => {}
const keyValid = () => { const keyValid = () => {
if (points.current.length === 0) { if (points.current.length === 0) {
alert('시작점을 선택해주세요') alert('시작점을 선택해주세요')
@ -552,7 +545,19 @@ export function useMode() {
} }
} }
const handleKeyDown = (e) => { const mouseAndkeyboardEventClear = () => {
Object.keys(mouseEvent).forEach((key) => {
canvas?.off('mouse:down', mouseEvent[key])
})
Object.keys(keyboardEvent).forEach((key) => {
window.removeEventListener('keydown', keyboardEvent[key])
})
}
const keyboardEvent = {
// rerendering을 막기 위해 useCallback 사용
editMode: useCallback(
(e) => {
switch (e.key) { switch (e.key) {
case 'ArrowDown': { case 'ArrowDown': {
if (!keyValid()) { if (!keyValid()) {
@ -616,6 +621,9 @@ export function useMode() {
} }
} }
} }
},
[canvas],
),
} }
const changeMode = (canvas, mode) => { const changeMode = (canvas, mode) => {
@ -623,6 +631,7 @@ export function useMode() {
setCanvas(canvas) setCanvas(canvas)
// mode별 이벤트 변경 // mode별 이벤트 변경
mouseAndkeyboardEventClear()
changeMouseEvent(mode) changeMouseEvent(mode)
changeKeyboardEvent(mode) changeKeyboardEvent(mode)
@ -657,40 +666,71 @@ export function useMode() {
} }
} }
const changeKeyboardEvent = (mode) => {
if (mode === Mode.EDIT) {
switch (mode) {
case 'edit':
window.addEventListener('keydown', keyboardEvent.editMode)
break
}
}
}
const mouseEvent = { const mouseEvent = {
drawLineModeLeftClick: (options) => { drawLineModeLeftClick: useCallback(
(options) => {
const pointer = canvas?.getPointer(options.e) const pointer = canvas?.getPointer(options.e)
const line = new QLine( const line = new QLine(
[pointer.x, 0, pointer.x, canvas.height], // y축에 1자 선을 그립니다. [pointer.x, 0, pointer.x, canvas.height], // y축에 1자 선을 그립니다.
{ {
stroke: 'black', stroke: 'gray',
strokeWidth: 2, strokeWidth: 1,
viewLengthText: true, selectable: true,
selectable: false, lockMovementX: true,
fontSize: fontSize, lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
name: 'guideLine',
}, },
) )
canvas?.add(line) canvas?.add(line)
canvas?.renderAll() canvas?.renderAll()
const newVerticalLineArray = [...vertGuideLines, line]
setVertGuideLines(newVerticalLineArray)
}, },
drawLineModeRightClick: (options) => { [canvas, vertGuideLines],
),
drawLineModeRightClick: useCallback(
(options) => {
const line = new fabric.Line( const line = new fabric.Line(
[0, options.offsetY, canvas.width, options.offsetY], // y축에 1자 선을 그립니다. [0, options.offsetY, canvasSize.horizontal, options.offsetY], // y축에 1자 선을 그립니다.
{ {
stroke: 'black', stroke: 'gray',
strokeWidth: 2, strokeWidth: 1,
viewLengthText: true, selectable: true,
selectable: false, lockMovementX: true,
fontSize: fontSize, lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
name: 'guideLine',
}, },
) )
canvas?.add(line) canvas?.add(line)
canvas?.renderAll() canvas?.renderAll()
const newHorizontalLineArray = [...horiGuideLines, line]
setHoriGuideLines(newHorizontalLineArray)
}, },
editMode: (options) => { [canvas, horiGuideLines],
),
editMode: useCallback(
(options) => {
let pointer = canvas?.getPointer(options.e) let pointer = canvas?.getPointer(options.e)
if (getInterSectPointByMouseLine()) { if (getInterSectPointByMouseLine()) {
@ -801,7 +841,9 @@ export function useMode() {
canvas?.renderAll() canvas?.renderAll()
}, },
textboxMode: (options) => { [canvas],
),
textboxMode: useCallback((options) => {
if (canvas?.getActiveObject()?.type === 'textbox') return if (canvas?.getActiveObject()?.type === 'textbox') return
const pointer = canvas?.getPointer(options.e) const pointer = canvas?.getPointer(options.e)
@ -819,8 +861,8 @@ export function useMode() {
textbox?.on('editing:exited', function () { textbox?.on('editing:exited', function () {
changeMode(canvas, Mode.EDIT) changeMode(canvas, Mode.EDIT)
}) })
}, }, []),
drawRectMode: (o) => { drawRectMode: useCallback((o) => {
let rect, isDown, origX, origY let rect, isDown, origX, origY
isDown = true isDown = true
const pointer = canvas.getPointer(o.e) const pointer = canvas.getPointer(o.e)
@ -860,9 +902,10 @@ export function useMode() {
canvas.off('mouse:up') canvas.off('mouse:up')
setMode(Mode.DEFAULT) setMode(Mode.DEFAULT)
}) })
}, }, []),
// 흡착점 추가 // 흡착점 추가
adsorptionPoint(o) { adsorptionPoint: useCallback(
(o) => {
const pointer = canvas.getPointer(o.e) const pointer = canvas.getPointer(o.e)
let newX = pointer.x let newX = pointer.x
let newY = pointer.y let newY = pointer.y
@ -890,6 +933,8 @@ export function useMode() {
canvas.add(circle) canvas.add(circle)
canvas.renderAll() canvas.renderAll()
}, },
[canvas],
),
} }
const getInterSectPointByMouseLine = () => { const getInterSectPointByMouseLine = () => {
@ -4484,7 +4529,6 @@ export function useMode() {
canvas?.off('mouse:move') canvas?.off('mouse:move')
canvas?.off('mouse:out') canvas?.off('mouse:out')
document.removeEventListener('keydown', handleKeyDown)
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof') const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof')
roofs.forEach((roof, index) => { roofs.forEach((roof, index) => {
const offsetPolygonPoint = offsetPolygon(roof.points, -20) const offsetPolygonPoint = offsetPolygon(roof.points, -20)