This commit is contained in:
changkyu choi 2024-08-28 08:33:22 +09:00
commit cebe226491
4 changed files with 118 additions and 27 deletions

View File

@ -30,6 +30,7 @@ import SettingsModal from './SettingsModal'
import { useAxios } from '@/hooks/useAxios' import { useAxios } from '@/hooks/useAxios'
import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu' import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu'
import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu' import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu'
import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu'
export default function Roof2(props) { export default function Roof2(props) {
const { name, userId, email, isLoggedIn } = props const { name, userId, email, isLoggedIn } = props
@ -588,7 +589,7 @@ export default function Roof2(props) {
모드 DEFAULT 모드 DEFAULT
</Button> </Button>
<Button className="m-1 p-2" color={`${mode === Mode.DRAW_LINE ? 'primary' : 'default'}`} onClick={() => setMode(Mode.DRAW_LINE)}> <Button className="m-1 p-2" color={`${mode === Mode.DRAW_LINE ? 'primary' : 'default'}`} onClick={() => setMode(Mode.DRAW_LINE)}>
기준선 긋기 모드 임의 그리드 모드
</Button> </Button>
<Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`} onClick={() => setMode(Mode.EDIT)}> <Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`} onClick={() => setMode(Mode.EDIT)}>
에디팅모드 에디팅모드
@ -632,6 +633,9 @@ export default function Roof2(props) {
<Button className="m-1 p-2" color={`${mode === Mode.TEXTBOX ? 'primary' : 'default'}`} onClick={() => setMode(Mode.TEXTBOX)}> <Button className="m-1 p-2" color={`${mode === Mode.TEXTBOX ? 'primary' : 'default'}`} onClick={() => setMode(Mode.TEXTBOX)}>
텍스트박스 모드 텍스트박스 모드
</Button> </Button>
<Button className="m-1 p-2" color={`${mode === Mode.DRAW_RECT ? 'primary' : 'default'}`} onClick={() => setMode(Mode.DRAW_RECT)}>
도머 추가 모드
</Button>
<Button <Button
className="m-1 p-2" className="m-1 p-2"
color={`${mode === Mode.ADSORPTION_POINT ? 'primary' : 'default'}`} color={`${mode === Mode.ADSORPTION_POINT ? 'primary' : 'default'}`}
@ -753,7 +757,9 @@ export default function Roof2(props) {
<ThumbnailList {...thumbnailProps} /> <ThumbnailList {...thumbnailProps} />
<div className="flex justify-start my-8 mx-2 w-full"> <div className="flex justify-start my-8 mx-2 w-full">
<canvas ref={canvasRef} id="canvas" style={{ border: '1px solid black' }} /> <canvas ref={canvasRef} id="canvas" style={{ border: '1px solid black' }} />
{!canvas ? null : currentObject?.type === 'QPolygon' ? ( {!canvas ? null : mode === Mode.DRAW_LINE ? (
<QEmptyContextMenu contextRef={canvasRef} canvasProps={canvas} />
) : currentObject?.type === 'QPolygon' ? (
<QPolygonContextMenu contextRef={canvasRef} canvasProps={canvas} /> <QPolygonContextMenu contextRef={canvasRef} canvasProps={canvas} />
) : currentObject?.type === 'QLine' ? ( ) : currentObject?.type === 'QLine' ? (
<QLineContextMenu contextRef={canvasRef} canvasProps={canvas} /> <QLineContextMenu contextRef={canvasRef} canvasProps={canvas} />

View File

@ -56,7 +56,12 @@ export default function SettingsModal(props) {
{ {
stroke: 'gray', stroke: 'gray',
strokeWidth: 1, strokeWidth: 1,
selectable: false, selectable: true,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
name: 'guideLine', name: 'guideLine',
}, },
) )
@ -70,7 +75,12 @@ export default function SettingsModal(props) {
{ {
stroke: 'gray', stroke: 'gray',
strokeWidth: 1, strokeWidth: 1,
selectable: false, selectable: true,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
name: 'guideLine', name: 'guideLine',
}, },
) )
@ -137,7 +147,9 @@ export default function SettingsModal(props) {
name: 'guideDot', name: 'guideDot',
}, },
) )
canvasProps.add(backgroundPolygon) canvasProps.add(backgroundPolygon)
backgroundPolygon.sendToBack()
canvasProps.renderAll() canvasProps.renderAll()
const recoilObj = { const recoilObj = {

View File

@ -0,0 +1,50 @@
'use client'
import { useEffect, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
export default function QEmptyContextMenu(props) {
const { contextRef, canvasProps } = props
// const children = useRecoilValue(modalContent)
const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0 })
useEffect(() => {
if (!contextRef.current) return
const handleContextMenu = (e) => {
e.preventDefault() // contextmenu
setContextMenu({ visible: true, x: e.pageX, y: e.pageY })
canvasProps.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //
}
const handleClick = (e) => {
e.preventDefault()
setContextMenu({ ...contextMenu, visible: false })
}
const handleOutsideClick = (e) => {
e.preventDefault()
if (contextMenu.visible && !ref.current.contains(e.target)) {
setContextMenu({ ...contextMenu, visible: false })
}
}
// Prevent the default context menu from appearing on the canvas
canvasProps.upperCanvasEl.addEventListener('contextmenu', handleContextMenu)
document.addEventListener('click', handleClick)
document.addEventListener('click', handleOutsideClick)
return () => {
// canvasProps.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu)
document.removeEventListener('click', handleClick)
document.removeEventListener('click', handleOutsideClick)
}
}, [contextRef, contextMenu])
const handleMenuClick = (option) => {
alert(`option ${option} clicked`)
setContextMenu({ ...contextMenu, visible: false })
}
return <></>
}

View File

@ -365,10 +365,13 @@ export function useMode() {
canvas?.off('mouse:down') canvas?.off('mouse:down')
switch (mode) { switch (mode) {
case 'drawLine': case 'drawLine':
canvas?.on('mouse:down', mouseEvent.drawLineMode) canvas?.on('mouse:down', mouseEvent.drawLineModeLeftClick)
window.document.removeEventListener('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)
break break
case 'textbox': case 'textbox':
canvas?.on('mouse:down', mouseEvent.textboxMode) canvas?.on('mouse:down', mouseEvent.textboxMode)
@ -655,7 +658,7 @@ export function useMode() {
} }
const mouseEvent = { const mouseEvent = {
drawLineMode: (options) => { drawLineModeLeftClick: (options) => {
const pointer = canvas?.getPointer(options.e) const pointer = canvas?.getPointer(options.e)
const line = new QLine( const line = new QLine(
@ -672,6 +675,21 @@ export function useMode() {
canvas?.add(line) canvas?.add(line)
canvas?.renderAll() canvas?.renderAll()
}, },
drawLineModeRightClick: (options) => {
const line = new fabric.Line(
[0, options.offsetY, canvas.width, options.offsetY], // y축에 1자 선을 그립니다.
{
stroke: 'black',
strokeWidth: 2,
viewLengthText: true,
selectable: false,
fontSize: fontSize,
},
)
canvas?.add(line)
canvas?.renderAll()
},
editMode: (options) => { editMode: (options) => {
let pointer = canvas?.getPointer(options.e) let pointer = canvas?.getPointer(options.e)
@ -802,9 +820,8 @@ export function useMode() {
changeMode(canvas, Mode.EDIT) changeMode(canvas, Mode.EDIT)
}) })
}, },
drawRectMode: () => { drawRectMode: (o) => {
let rect, isDown, origX, origY let rect, isDown, origX, origY
canvas.on('mouse:down', function (o) {
isDown = true isDown = true
const pointer = canvas.getPointer(o.e) const pointer = canvas.getPointer(o.e)
origX = pointer.x origX = pointer.x
@ -822,11 +839,10 @@ export function useMode() {
transparentCorners: false, transparentCorners: false,
}) })
canvas.add(rect) canvas.add(rect)
})
canvas.on('mouse:move', function (o) { canvas.on('mouse:move', function (e) {
if (!isDown) return if (!isDown) return
const pointer = canvas.getPointer(o.e) const pointer = canvas.getPointer(e.e)
if (origX > pointer.x) { if (origX > pointer.x) {
rect.set({ left: Math.abs(pointer.x) }) rect.set({ left: Math.abs(pointer.x) })
} }
@ -837,6 +853,13 @@ export function useMode() {
rect.set({ width: Math.abs(origX - pointer.x) }) rect.set({ width: Math.abs(origX - pointer.x) })
rect.set({ height: Math.abs(origY - pointer.y) }) rect.set({ height: Math.abs(origY - pointer.y) })
}) })
canvas.on('mouse:up', function (o) {
isDown = false
canvas.off('mouse:move')
canvas.off('mouse:up')
setMode(Mode.DEFAULT)
})
}, },
// 흡착점 추가 // 흡착점 추가
adsorptionPoint(o) { adsorptionPoint(o) {