diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx
index e6261edc..2f946deb 100644
--- a/src/components/floor-plan/CanvasFrame.jsx
+++ b/src/components/floor-plan/CanvasFrame.jsx
@@ -11,11 +11,16 @@ import { currentObjectState } from '@/store/canvasAtom'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import QContextMenu from '@/components/common/context-menu/QContextMenu'
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
+import { useCommonUtils } from '@/hooks/common/useCommonUtils'
+import { useObjectBatch } from '@/hooks/object/useObjectBatch'
+import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
export default function CanvasFrame({ plan }) {
const canvasRef = useRef(null)
const { canvas } = useCanvas('canvas')
const { handleZoomClear } = useCanvasEvent()
+ const { testAlert } = useCommonUtils({})
+
const { contextMenu, currentContextMenu, setCurrentContextMenu, handleClick } = useContextMenu({
externalFn: {
handleZoomClear,
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx
index 07411efb..4017342d 100644
--- a/src/components/floor-plan/CanvasMenu.jsx
+++ b/src/components/floor-plan/CanvasMenu.jsx
@@ -27,6 +27,7 @@ import { usePopup } from '@/hooks/usePopup'
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
import { useCommonUtils } from '@/hooks/common/useCommonUtils'
+import { commonUtilsState } from '@/store/commonUtilsAtom'
const canvasMenus = [
{ index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING },
@@ -61,17 +62,8 @@ export default function CanvasMenu(props) {
const { saveCanvas } = usePlan()
const { swalFire } = useSwal()
const { initEvent, addCanvasMouseEventListener, addDocumentEventListener } = useEvent()
-
- const [commonFunctionState, setCommonFunctionState] = useState({
- text: false,
- dimension: false,
- distance: false,
- })
-
- const { commonFunctions } = useCommonUtils({
- commonFunctionState,
- setCommonFunctionState,
- })
+ const commonUtils = useRecoilValue(commonUtilsState)
+ const { commonFunctions } = useCommonUtils()
const [popup, setPopup] = useRecoilState(popupState)
@@ -188,9 +180,9 @@ export default function CanvasMenu(props) {
}
-
-
-
+
+
+
diff --git a/src/components/floor-plan/modal/distance/Distance.jsx b/src/components/floor-plan/modal/distance/Distance.jsx
index 06a7a483..70ddfb35 100644
--- a/src/components/floor-plan/modal/distance/Distance.jsx
+++ b/src/components/floor-plan/modal/distance/Distance.jsx
@@ -1,15 +1,20 @@
-import WithDraggable from '@/components/common/draggable/withDraggable'
+import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
-import { useRecoilValue } from 'recoil'
+import WithDraggable from '@/components/common/draggable/WithDraggable'
import { contextPopupPositionState } from '@/store/popupAtom'
export default function Distance(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
- const { id, pos = contextPopupPosition, distance } = props
+ const { id, pos = contextPopupPosition, distance, deleteDistance } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
+ const handleClose = () => {
+ deleteDistance()
+ closePopup(id)
+ }
+
return (
@@ -58,7 +63,9 @@ export default function Distance(props) {
-
+
diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js
index 70447ae8..5f02900d 100644
--- a/src/hooks/common/useCommonUtils.js
+++ b/src/hooks/common/useCommonUtils.js
@@ -1,5 +1,5 @@
import { useEffect } from 'react'
-import { useRecoilValue } from 'recoil'
+import { useRecoilValue, useRecoilState } from 'recoil'
import { wordDisplaySelector } from '@/store/settingAtom'
import { useEvent } from '@/hooks/useEvent'
import { checkLineOrientation, getDistance } from '@/util/canvas-util'
@@ -9,30 +9,34 @@ import { canvasState } from '@/store/canvasAtom'
import { v4 as uuidv4 } from 'uuid'
import { usePopup } from '@/hooks/usePopup'
import Distance from '@/components/floor-plan/modal/distance/Distance'
+import { commonUtilsState } from '@/store/commonUtilsAtom'
+import { point } from '@turf/turf'
-export function useCommonUtils({ commonFunctionState, setCommonFunctionState }) {
+export function useCommonUtils() {
const canvas = useRecoilValue(canvasState)
const wordDisplay = useRecoilValue(wordDisplaySelector)
const { addCanvasMouseEventListener, addDocumentEventListener, initEvent } = useEvent()
const dimensionSettings = useRecoilValue(dimensionLineSettingsState)
const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText'))
const commonTextFont = useRecoilValue(fontSelector('commonText'))
+ const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState)
+
const { addPopup } = usePopup()
useEffect(() => {
initEvent()
- if (commonFunctionState.text) {
+ if (commonUtils.text) {
commonTextMode()
- } else if (commonFunctionState.dimension) {
+ } else if (commonUtils.dimension) {
commonDimensionMode()
- } else if (commonFunctionState.distance) {
+ } else if (commonUtils.distance) {
commonDistanceMode()
}
- }, [commonFunctionState, dimensionSettings, commonTextFont, dimensionLineTextFont])
+ }, [commonUtils, dimensionSettings, commonTextFont, dimensionLineTextFont])
const commonTextMode = () => {
let textbox
- if (commonFunctionState.text) {
+ if (commonUtils.text) {
addCanvasMouseEventListener('mouse:down', (event) => {
const pointer = canvas?.getPointer(event.e)
textbox = new fabric.Textbox('', {
@@ -46,6 +50,11 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
fontFamily: commonTextFont.fontFamily.value,
fontSize: commonTextFont.fontSize.value,
fontStyle: commonTextFont.fontWeight.value,
+ selectable: true,
+ lockMovementX: true,
+ lockMovementY: true,
+ originX: 'center',
+ originY: 'center',
})
canvas?.add(textbox)
@@ -53,70 +62,120 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
textbox.enterEditing()
textbox.selectAll()
})
+ }
+ }
- addDocumentEventListener('keydown', document, (e) => {
- if (e.key === 'Enter') {
- if (commonFunctionState.text) {
- const activeObject = canvas.getActiveObject()
- if (activeObject && activeObject.isEditing) {
- if (activeObject.text === '') {
- canvas?.remove(activeObject)
- } else {
- activeObject.exitEditing()
- }
- //정책 협의
- const texts = canvas.getObjects().filter((obj) => obj.name === 'commonText')
- texts.forEach((text) => {
- text.set({ editable: false })
- })
+ const createDimensionArrow = (x, y, angle, id) => {
+ return new fabric.Triangle({
+ left: x,
+ top: y,
+ originX: 'center',
+ originY: 'center',
+ angle: angle,
+ width: 15,
+ height: 15,
+ fill: dimensionSettings.color,
+ selectable: true,
+ name: 'arrow',
+ id: id,
+ })
+ }
- canvas.renderAll()
- }
- }
- }
- })
+ const createDimensionExtendLine = (line, lineDirection, extendLength) => {
+ let extendLine = []
+
+ const extendLineLength = extendLength ? extendLength : 0
+
+ if (lineDirection === 'horizontal') {
+ if (extendLineLength >= 0) {
+ extendLine = [
+ [line.x1, line.y1 - 20 - extendLineLength, line.x1, line.y1 + 20],
+ [line.x2, line.y2 - 20 - extendLineLength, line.x2, line.y2 + 20],
+ ]
+ } else {
+ extendLine = [
+ [line.x1, line.y1 + 20 - extendLineLength, line.x1, line.y1 - 20],
+ [line.x2, line.y2 + 20 - extendLineLength, line.x2, line.y2 - 20],
+ ]
+ }
+ } else {
+ if (extendLineLength >= 0) {
+ extendLine = [
+ [line.x1 - 20 - extendLineLength, line.y1, line.x1 + 20, line.y1],
+ [line.x2 - 20 - extendLineLength, line.y2, line.x2 + 20, line.y2],
+ ]
+ } else {
+ extendLine = [
+ [line.x1 - 20 - extendLineLength, line.y1, line.x1 - 20, line.y1],
+ [line.x2 - 20 - extendLineLength, line.y2, line.x2 - 20, line.y2],
+ ]
+ }
+ }
+
+ return extendLine
+ }
+
+ const calcDimensionPosition = (lineDirection, p1CenterX, p1CenterY, p2CenterX, p2CenterY) => {
+ // 첫 번째 포인트에 화살표 추가 좌측 -> 우측으로 그릴때
+ let paddingX = lineDirection === 'horizontal' ? p1CenterX + 7.5 : p1CenterX + 0.5
+ let paddingX2 = lineDirection === 'horizontal' ? p2CenterX - 7.5 : p2CenterX + 0.5
+ let paddingY = lineDirection === 'horizontal' ? p1CenterY + 0.5 : p1CenterY + 8
+ let paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 0.5 : p2CenterY - 8
+ let angle1 = lineDirection === 'horizontal' ? -90 : 0
+ let angle2 = lineDirection === 'horizontal' ? 90 : 180
+
+ // 우측 -> 좌측으로 그릴땐 반대
+ if (paddingX > paddingX2 || paddingY > paddingY2) {
+ paddingX = lineDirection === 'horizontal' ? p1CenterX - 7.5 : p1CenterX + 0.5
+ paddingX2 = lineDirection === 'horizontal' ? p2CenterX + 7.5 : p2CenterX + 0.5
+ paddingY = lineDirection === 'horizontal' ? p1CenterY + 0.5 : p1CenterY - 7.5
+ paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 0.5 : p2CenterY + 7.5
+ angle1 = lineDirection === 'horizontal' ? 90 : 180
+ angle2 = lineDirection === 'horizontal' ? 270 : 0
+ }
+
+ return {
+ paddingX,
+ paddingX2,
+ paddingY,
+ paddingY2,
+ angle1,
+ angle2,
}
}
const commonDimensionMode = () => {
- if (commonFunctionState.dimension) {
+ if (commonUtils.dimension) {
+ const uuid = uuidv4()
+
let points = []
let distanceText = null
let minX, minY, maxX, maxY
// 화살표를 생성하는 함수
- function createArrow(x, y, angle) {
- return new fabric.Triangle({
- left: x,
- top: y,
- originX: 'center',
- originY: 'center',
- angle: angle,
- width: 15,
- height: 15,
- fill: dimensionSettings.color,
- selectable: false,
- })
- }
const circleOptions = {
radius: 5,
strokeWidth: 2,
stroke: 'red',
fill: 'white',
- selectable: false,
+ selectable: true,
}
const lineOptions = {
stroke: dimensionSettings.color,
strokeWidth: dimensionSettings.pixel,
- name: 'dimensionLine',
selectable: true,
+ originX: 'center',
+ originY: 'center',
}
// 캔버스에 클릭 이벤트 추가
addCanvasMouseEventListener('mouse:down', (e) => {
+ let groupObjects = []
+
const pointer = canvas.getPointer(e.e)
+
let point
if (points.length === 0) {
@@ -165,40 +224,60 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
})
// 두 포인트 간에 직선을 그림 (중심을 기준으로)
- const line = new fabric.Line([p1CenterX, p1CenterY, p2CenterX, p2CenterY], lineOptions)
+ const line = new fabric.Line([p1CenterX, p1CenterY, p2CenterX, p2CenterY], { ...lineOptions, name: 'centerLine', id: uuid })
canvas.add(line)
+ // groupObjects.push(line)
+
const distance = getDistance(p1CenterX, p1CenterY, p2CenterX, p2CenterY)
const lineDirection = checkLineOrientation(line)
- let extendLine = []
- if (lineDirection === 'horizontal') {
- extendLine = [
- [line.x1, line.y1 - 20, line.x1, line.y1 + 20],
- [line.x2, line.y2 - 20, line.x2, line.y2 + 20],
- ]
- } else {
- extendLine = [
- [line.x1 - 20, line.y1, line.x1 + 20, line.y1],
- [line.x2 - 20, line.y2, line.x2 + 20, line.y2],
- ]
- }
+ const extendListArray = createDimensionExtendLine(line, lineDirection)
- extendLine.forEach((line) => {
- const extendLine = new fabric.Line(line, lineOptions)
- canvas.add(extendLine)
+ extendListArray.forEach((line) => {
+ const extendLine = new fabric.Line(line, { ...lineOptions, name: 'extendLine', id: uuid })
+ // canvas.add(extendLine)
+ groupObjects.push(extendLine)
})
- // 첫 번째 포인트에 화살표 추가
- const paddingX = lineDirection === 'horizontal' ? p1CenterX + 7.5 : p1CenterX + 1
- const paddingX2 = lineDirection === 'horizontal' ? p2CenterX - 6.5 : p2CenterX + 1
- const paddingY = lineDirection === 'horizontal' ? p1CenterY + 1 : p1CenterY + 8
- const paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 1 : p2CenterY - 8
+ // // 첫 번째 포인트에 화살표 추가 좌측 -> 우측으로 그릴때
+ // let paddingX = lineDirection === 'horizontal' ? p1CenterX + 7.5 : p1CenterX + 0.5
+ // let paddingX2 = lineDirection === 'horizontal' ? p2CenterX - 7.5 : p2CenterX + 0.5
+ // let paddingY = lineDirection === 'horizontal' ? p1CenterY + 0.5 : p1CenterY + 8
+ // let paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 0.5 : p2CenterY - 8
+ // let angle1 = lineDirection === 'horizontal' ? -90 : 0
+ // let angle2 = lineDirection === 'horizontal' ? 90 : 180
- const arrow1 = createArrow(paddingX, paddingY, lineDirection === 'horizontal' ? -90 : 0) // 반대 방향 화살표
- const arrow2 = createArrow(paddingX2, paddingY2, lineDirection === 'horizontal' ? 90 : 180) // 정방향 화살표
- canvas.add(arrow1)
- canvas.add(arrow2)
+ // // 우측 -> 좌측으로 그릴땐 반대
+ // if (paddingX > paddingX2 || paddingY > paddingY2) {
+ // paddingX = lineDirection === 'horizontal' ? p1CenterX - 7.5 : p1CenterX + 0.5
+ // paddingX2 = lineDirection === 'horizontal' ? p2CenterX + 7.5 : p2CenterX + 0.5
+ // paddingY = lineDirection === 'horizontal' ? p1CenterY + 0.5 : p1CenterY - 7.5
+ // paddingY2 = lineDirection === 'horizontal' ? p2CenterY + 0.5 : p2CenterY + 7.5
+ // angle1 = lineDirection === 'horizontal' ? 90 : 180
+ // angle2 = lineDirection === 'horizontal' ? 270 : 0
+ // }
+
+ const dimensionPosition = calcDimensionPosition(lineDirection, p1CenterX, p1CenterY, p2CenterX, p2CenterY)
+
+ const arrow1 = createDimensionArrow(dimensionPosition.paddingX, dimensionPosition.paddingY, dimensionPosition.angle1, uuid) // 반대 방향 화살표
+ const arrow2 = createDimensionArrow(dimensionPosition.paddingX2, dimensionPosition.paddingY2, dimensionPosition.angle2, uuid) // 정방향 화살표
+ // canvas.add(arrow1)
+ // canvas.add(arrow2)
+
+ groupObjects.push(arrow1)
+ groupObjects.push(arrow2)
+
+ const group = new fabric.Group(groupObjects, {
+ name: 'dimensionLine',
+ selectable: true,
+ originX: 'center',
+ originY: 'center',
+ lineDirection: lineDirection,
+ id: uuid,
+ })
+
+ canvas.add(group)
distanceText = new fabric.Text(`${distance * 10} `, {
left: (p1CenterX + p2CenterX) / 2 + (lineDirection === 'horizontal' ? 0 : -15),
@@ -213,18 +292,24 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
originY: 'center',
angle: lineDirection === 'horizontal' ? 0 : 270,
name: 'dimensionLineText',
+ id: uuid,
// lockMovementX: false,
// lockMovementY: false,
})
canvas.add(distanceText)
- // minX = p1CenterX
- // maxX = p2CenterX
- // minY = p1CenterY
- // maxY = p2CenterY
+ // groupObjects.push(distanceText)
+
+ canvas.renderAll()
// 거리 계산 후, 다음 측정을 위해 초기화
points = []
+
+ if (setCommonUtilsState)
+ setCommonUtilsState({
+ ...commonUtilsState,
+ dimension: false,
+ })
}
// 캔버스 다시 그리기
@@ -251,7 +336,7 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
}
const commonDistanceMode = () => {
- if (commonFunctionState.distance) {
+ if (commonUtils.distance) {
let points = []
let distanceText = null
let drawPoints = []
@@ -261,13 +346,15 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
strokeWidth: 1,
originX: 'center',
originY: 'center',
+ name: 'distance',
}
const lineOptions = {
stroke: 'black',
- strokeWidth: 2,
+ strokeWidth: 1,
selectable: false,
- strokeDashArray: [9, 5],
+ strokeDashArray: [10, 5],
+ name: 'distance',
}
const textOptions = {
@@ -277,11 +364,12 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
textAlign: 'center',
originX: 'center',
originY: 'center',
+ name: 'distance',
}
// 캔버스에 클릭 이벤트 추가
- addCanvasMouseEventListener('mouse:down', function (options) {
- const pointer = canvas.getPointer(options.e)
+ addCanvasMouseEventListener('mouse:down', function (e) {
+ const pointer = canvas.getPointer(e.e)
let point
let cross = {}
@@ -338,7 +426,7 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
top: (p1CenterY + p2CenterY) / 2,
...textOptions,
})
- // canvas.add(distanceText)
+ canvas.add(distanceText)
let distance2 = 0
let distance3 = 0
@@ -355,13 +443,13 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
top: (p2CenterY + p3.y) / 2,
...textOptions,
})
- // canvas.add(distanceText)
+ canvas.add(distanceText)
distanceText = new fabric.Text(`${distance3 * 10}`, {
left: (p3.x + p1CenterX) / 2,
top: (p3.y + p1CenterY) / 2,
...textOptions,
})
- // canvas.add(distanceText)
+ canvas.add(distanceText)
}
const id = uuidv4()
@@ -375,9 +463,16 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
vertical: distance2 * 10,
diagonal: distance1 * 10,
}}
+ deleteDistance={closeDistancePopup}
/>,
)
+ if (setCommonUtilsState)
+ setCommonUtilsState({
+ ...commonUtils,
+ distance: false,
+ })
+
// 거리 계산 후, 다음 측정을 위해 초기화
points = []
}
@@ -387,8 +482,34 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
})
}
}
+
+ //텍스트 모드일때 엔터 이벤트
+ addDocumentEventListener('keydown', document, (e) => {
+ if (e.key === 'Enter') {
+ const activeObject = canvas.getActiveObject()
+ if (activeObject.name === 'commonText') {
+ if (activeObject && activeObject.isEditing) {
+ if (activeObject.text === '') {
+ canvas?.remove(activeObject)
+ } else {
+ activeObject.exitEditing()
+ }
+ //정책 협의
+ const texts = canvas.getObjects().filter((obj) => obj.name === 'commonText')
+ texts.forEach((text) => {
+ text.set({ editable: false })
+ })
+
+ canvas.renderAll()
+ if (setCommonUtilsState) setCommonUtilsState({ ...commonUtils, text: false })
+ }
+ }
+ initEvent()
+ }
+ })
+
const commonFunctions = (mode) => {
- let tempStates = { ...commonFunctionState }
+ let tempStates = { ...commonUtils }
if (tempStates[mode]) {
tempStates[mode] = false
@@ -402,11 +523,258 @@ export function useCommonUtils({ commonFunctionState, setCommonFunctionState })
}
}
- if (setCommonFunctionState) setCommonFunctionState(tempStates)
+ if (setCommonUtilsState) setCommonUtilsState(tempStates)
+ }
+
+ const commonDeleteText = (object) => {
+ if (object) {
+ canvas?.remove(object)
+
+ if (object.id) {
+ const group = canvas.getObjects().filter((obj) => obj.id === object.id)
+ group.forEach((obj) => canvas?.remove(obj))
+ }
+ }
+ }
+
+ const commonMoveObject = (obj) => {
+ if (obj) {
+ obj.set({
+ lockMovementX: false,
+ lockMovementY: false,
+ })
+
+ addCanvasMouseEventListener('mouse:up', (e) => {
+ obj.set({
+ lockMovementX: true,
+ lockMovementY: true,
+ })
+ initEvent()
+ })
+
+ obj.setCoords()
+ canvas?.renderAll()
+ }
+ }
+
+ const commonCopyObject = (obj) => {
+ if (obj) {
+ let clonedObj = null
+
+ console.log(obj)
+
+ obj.clone((cloned) => {
+ clonedObj = cloned
+ })
+
+ addCanvasMouseEventListener('mouse:move', (e) => {
+ const pointer = canvas?.getPointer(e.e)
+ if (!clonedObj) return
+
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === 'clonedObj')
+ .forEach((obj) => canvas?.remove(obj))
+
+ clonedObj.set({
+ left: pointer.x,
+ top: pointer.y,
+ name: 'clonedObj',
+ })
+ canvas.add(clonedObj)
+ })
+
+ addCanvasMouseEventListener('mouse:down', (e) => {
+ clonedObj.set({
+ lockMovementX: true,
+ lockMovementY: true,
+ name: obj.name,
+ editable: false,
+ id: uuidv4(), //복사된 객체라 새로 따준다
+ })
+ initEvent()
+ })
+ }
+ }
+
+ const editText = () => {
+ const obj = canvas?.getActiveObject()
+ obj.set({ editable: true })
+ obj.enterEditing()
+ }
+
+ const deleteObject = () => {
+ const obj = canvas?.getActiveObject()
+ commonDeleteText(obj)
+ }
+
+ const moveObject = () => {
+ const obj = canvas?.getActiveObject()
+ commonMoveObject(obj)
+ }
+
+ const copyObject = () => {
+ const obj = canvas?.getActiveObject()
+ commonCopyObject(obj)
+ }
+
+ const closeDistancePopup = () => {
+ const obj = canvas?.getObjects().filter((obj) => obj.name === 'distance')
+ if (obj) canvas.remove(...obj)
+ }
+
+ const changeDimensionExtendLine = () => {
+ const group = canvas?.getActiveObject()
+ const id = group.id
+ const textObj = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText' && obj.id === id)[0]
+ const items = group._objects
+ const originLineDirection = group.lineDirection
+
+ let groupObj = []
+
+ canvas?.remove(group)
+
+ items.forEach((item) => {
+ item.set({
+ selectable: true,
+ })
+ canvas?.add(item)
+ })
+ canvas?.renderAll()
+
+ const centerLine = canvas?.getObjects().filter((obj) => obj.name === 'centerLine' && obj.id === id)[0]
+ const extendLine = canvas?.getObjects().filter((obj) => obj.name === 'extendLine' && obj.id === id)
+ const arrows = canvas?.getObjects().filter((obj) => obj.name === 'arrow' && obj.id === id)
+
+ const originX = centerLine.x1
+ const originY = centerLine.y1
+
+ const lineOptions = {
+ stroke: dimensionSettings.color,
+ strokeWidth: dimensionSettings.pixel,
+ selectable: true,
+ originX: 'center',
+ originY: 'center',
+ }
+
+ addCanvasMouseEventListener('mouse:down', (e) => {
+ const pointer = canvas?.getPointer(e.e)
+
+ if (originLineDirection === 'horizontal') {
+ centerLine.set({
+ x1: centerLine.x1,
+ y1: pointer.y,
+ x2: centerLine.x2,
+ y2: pointer.y,
+ })
+
+ centerLine.setCoords()
+ canvas?.renderAll()
+
+ const differenceY = centerLine.y1 - originY
+
+ arrows.forEach((arrow) => {
+ canvas?.remove(arrow)
+ })
+
+ const { paddingX, paddingX2, paddingY, paddingY2, angle1, angle2 } = calcDimensionPosition(
+ originLineDirection,
+ centerLine.x1,
+ pointer.y,
+ centerLine.x2,
+ pointer.y,
+ )
+
+ const newArrow1 = createDimensionArrow(paddingX, paddingY, angle1, id)
+ const newArraw2 = createDimensionArrow(paddingX2, paddingY2, angle2, id)
+ canvas?.add(newArrow1, newArraw2)
+
+ groupObj.push(centerLine, newArrow1, newArraw2)
+
+ extendLine.forEach((line) => canvas?.remove(line))
+
+ const newExtendLine = createDimensionExtendLine(centerLine, originLineDirection, differenceY)
+
+ newExtendLine.forEach((line) => {
+ const extendLine = new fabric.Line(line, { ...lineOptions, name: 'extendLine', id: id })
+ canvas.add(extendLine)
+ groupObj.push(extendLine)
+ })
+
+ textObj.set({
+ top: pointer.y + 15,
+ })
+ textObj.setCoords()
+ } else {
+ centerLine.set({
+ x1: pointer.x,
+ y1: centerLine.y1,
+ x2: pointer.x,
+ y2: centerLine.y2,
+ })
+
+ centerLine.setCoords()
+ canvas?.renderAll()
+
+ const differenceX = centerLine.x1 - originX
+
+ arrows.forEach((arrow) => {
+ canvas?.remove(arrow)
+ })
+
+ const { paddingX, paddingX2, paddingY, paddingY2, angle1, angle2 } = calcDimensionPosition(
+ originLineDirection,
+ pointer.x,
+ centerLine.y1,
+ pointer.x,
+ centerLine.y2,
+ )
+
+ const newArrow1 = createDimensionArrow(paddingX, paddingY, angle1, id)
+ const newArraw2 = createDimensionArrow(paddingX2, paddingY2, angle2, id)
+ canvas?.add(newArrow1, newArraw2)
+
+ groupObj.push(centerLine, newArrow1, newArraw2)
+
+ extendLine.forEach((line) => canvas?.remove(line))
+
+ const newExtendLine = createDimensionExtendLine(centerLine, originLineDirection, differenceX)
+
+ newExtendLine.forEach((line) => {
+ const extendLine = new fabric.Line(line, { ...lineOptions, name: 'extendLine', id: id })
+ canvas.add(extendLine)
+ groupObj.push(extendLine)
+ })
+
+ textObj.set({
+ left: pointer.x - 15,
+ })
+ textObj.setCoords()
+ }
+
+ const reGroup = new fabric.Group(groupObj, {
+ name: 'dimensionLine',
+ selectable: true,
+ originX: 'center',
+ originY: 'center',
+ lineDirection: originLineDirection,
+ id: id,
+ })
+ canvas.add(reGroup)
+ initEvent()
+ })
}
return {
commonFunctions,
dimensionSettings,
+ commonDeleteText,
+ commonMoveObject,
+ commonDeleteText,
+ deleteObject,
+ moveObject,
+ copyObject,
+ editText,
+ changeDimensionExtendLine,
}
}
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index bbd5115b..adb9b680 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -20,6 +20,8 @@ import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/Di
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
import LinePropertySetting from '@/components/floor-plan/modal/lineProperty/LinePropertySetting'
import FlowDirectionSetting from '@/components/floor-plan/modal/flowDirection/FlowDirectionSetting'
+import { useCommonUtils } from './common/useCommonUtils'
+import { canvasState } from '@/store/canvasAtom'
export function useContextMenu({ externalFn }) {
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
@@ -30,6 +32,9 @@ export function useContextMenu({ externalFn }) {
const { addPopup } = usePopup()
const [popupId, setPopupId] = useState(uuidv4())
const [gridColor, setGridColor] = useRecoilState(gridColorState)
+ const canvas = useRecoilValue(canvasState)
+ const { deleteObject, moveObject, copyObject, editText, changeDimensionExtendLine } = useCommonUtils({})
+
const currentMenuSetting = (position) => {
switch (currentMenu) {
case MENU.PLAN_DRAWING:
@@ -200,7 +205,7 @@ export function useContextMenu({ externalFn }) {
}, [currentContextMenu])
useEffect(() => {
- console.log('object name', currentObject?.name)
+ console.log('object name', currentObject)
if (currentObject?.name) {
switch (currentObject.name) {
case 'triangleDormer':
@@ -331,14 +336,17 @@ export function useContextMenu({ externalFn }) {
{
id: 'commonTextRemove',
name: '삭제',
+ fn: () => deleteObject(),
},
{
id: 'commonTextMove',
name: '이동',
+ fn: () => moveObject(),
},
{
id: 'commonTextCopy',
name: '복사',
+ fn: () => copyObject(),
},
{
id: 'commonTextFontSetting',
@@ -348,6 +356,7 @@ export function useContextMenu({ externalFn }) {
{
id: 'commonTextEdit',
name: '편집',
+ fn: () => editText(),
},
],
])
@@ -384,14 +393,17 @@ export function useContextMenu({ externalFn }) {
{
id: 'dimensionLineRemove',
name: '삭제',
+ fn: () => deleteObject(),
},
{
id: 'dimensionLineMove',
name: '이동',
+ fn: () => moveObject(),
},
{
id: 'dimensionAuxiliaryLineEdit',
name: '치수 보조선 변경',
+ fn: () => changeDimensionExtendLine(),
},
{
id: 'dimensionLineDisplayEdit',
diff --git a/src/store/commonUtilsAtom.js b/src/store/commonUtilsAtom.js
index 3fe8dbb7..545f8196 100644
--- a/src/store/commonUtilsAtom.js
+++ b/src/store/commonUtilsAtom.js
@@ -1,5 +1,11 @@
import { atom } from 'recoil'
+const defaultUtils = {
+ text: false,
+ dimension: false,
+ distance: false,
+}
+
export const dimensionLineSettingsState = atom({
key: 'dimensionLineSettingsState',
default: {
@@ -11,3 +17,8 @@ export const dimensionLineSettingsState = atom({
fontStyle: 'normal',
},
})
+
+export const commonUtilsState = atom({
+ key: 'commonUtilsState',
+ default: defaultUtils,
+})