마우스 contextmenu 구현
This commit is contained in:
parent
7460409802
commit
7e68be16a1
@ -1,6 +1,6 @@
|
|||||||
NEXT_PUBLIC_TEST="테스트변수입니다. development"
|
NEXT_PUBLIC_TEST="테스트변수입니다. development"
|
||||||
|
|
||||||
NEXT_PUBLIC_API_SERVER_PATH="http://localhost:8080"
|
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
|
||||||
|
|
||||||
DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true"
|
DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true"
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useCanvas } from '@/hooks/useCanvas'
|
import { useCanvas } from '@/hooks/useCanvas'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState, useRef } from 'react'
|
||||||
import { Mode, useMode } from '@/hooks/useMode'
|
import { Mode, useMode } from '@/hooks/useMode'
|
||||||
import { Button } from '@nextui-org/react'
|
import { Button } from '@nextui-org/react'
|
||||||
import RangeSlider from './ui/RangeSlider'
|
import RangeSlider from './ui/RangeSlider'
|
||||||
@ -19,10 +19,13 @@ import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
|||||||
import { calculateIntersection } from '@/util/canvas-util'
|
import { calculateIntersection } from '@/util/canvas-util'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import ThumbnailList from './ui/ThumbnailLIst'
|
import ThumbnailList from './ui/ThumbnailLIst'
|
||||||
|
import CanvasWithContextMenu from '@/util/context-util'
|
||||||
|
|
||||||
export default function Roof2() {
|
export default function Roof2() {
|
||||||
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
|
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
|
||||||
|
|
||||||
|
const canvasRef = useRef(null)
|
||||||
|
|
||||||
//canvas 기본 사이즈
|
//canvas 기본 사이즈
|
||||||
const [canvasSize, setCanvasSize] = useRecoilState(canvasSizeState)
|
const [canvasSize, setCanvasSize] = useRecoilState(canvasSizeState)
|
||||||
|
|
||||||
@ -699,7 +702,8 @@ export default function Roof2() {
|
|||||||
)}
|
)}
|
||||||
<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 id="canvas" style={{ border: '1px solid black' }} />
|
<canvas ref={canvasRef} id="canvas" style={{ border: '1px solid black' }} />
|
||||||
|
{canvas !== undefined && <CanvasWithContextMenu ref={canvasRef} canvasProps={canvas} />}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -64,15 +64,11 @@ export function useCanvas(id) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
initialize()
|
initialize()
|
||||||
canvas?.on('object:added', onChange)
|
removeEventOnCanvas()
|
||||||
canvas?.on('object:added', addEventOnObject)
|
addEventOnCanvas()
|
||||||
|
|
||||||
canvas?.on('object:modified', onChange)
|
|
||||||
canvas?.on('object:removed', onChange)
|
|
||||||
canvas?.on('mouse:move', drawMouseLines)
|
|
||||||
canvas?.on('mouse:out', removeMouseLines)
|
|
||||||
}
|
}
|
||||||
}, [canvas])
|
}, [canvas])
|
||||||
|
|
||||||
const addEventOnCanvas = () => {
|
const addEventOnCanvas = () => {
|
||||||
canvas?.on('object:added', onChange)
|
canvas?.on('object:added', onChange)
|
||||||
canvas?.on('object:modified', onChange)
|
canvas?.on('object:modified', onChange)
|
||||||
|
|||||||
@ -277,7 +277,7 @@ export function useMode() {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case 'default':
|
case 'default':
|
||||||
canvas?.off('mouse:down')
|
// canvas?.off('mouse:down')
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,7 +510,7 @@ export function useMode() {
|
|||||||
setMode(mode)
|
setMode(mode)
|
||||||
// mode변경 시 이전 이벤트 제거
|
// mode변경 시 이전 이벤트 제거
|
||||||
setCanvas(canvas)
|
setCanvas(canvas)
|
||||||
canvas?.off('mouse:down')
|
// canvas?.off('mouse:down')
|
||||||
|
|
||||||
addEvent(mode)
|
addEvent(mode)
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/util/context-util.js
Normal file
65
src/util/context-util.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import React, { useState, useEffect, forwardRef, useContext } from 'react'
|
||||||
|
|
||||||
|
const CanvasWithContextMenu = forwardRef(({ canvasProps }, ref) => {
|
||||||
|
const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0 })
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ref.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)
|
||||||
|
}
|
||||||
|
}, [ref, contextMenu])
|
||||||
|
|
||||||
|
const handleMenuClick = (option) => {
|
||||||
|
alert(`option ${option} clicked`)
|
||||||
|
setContextMenu({ ...contextMenu, visible: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{contextMenu.visible && (
|
||||||
|
<div style={{ position: 'absolute', top: contextMenu.y, left: contextMenu.x, zIndex: 2000 }}>
|
||||||
|
<ul style={{ listStyle: 'none', margin: 0, padding: '5px' }}>
|
||||||
|
<li style={{ padding: '8px 12px', cursor: 'pointer' }} onClick={() => handleMenuClick(1)}>
|
||||||
|
Option 1
|
||||||
|
</li>
|
||||||
|
<li style={{ padding: '8px 12px', cursor: 'pointer' }} onClick={() => handleMenuClick(2)}>
|
||||||
|
Option 2
|
||||||
|
</li>
|
||||||
|
<li style={{ padding: '8px 12px', cursor: 'pointer' }} onClick={() => handleMenuClick(3)}>
|
||||||
|
Option 3
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default CanvasWithContextMenu
|
||||||
Loading…
x
Reference in New Issue
Block a user