프론트엔드/컴포넌트

모달창 드래그앤 드롭

syleemomo 2024. 6. 18. 10:41
728x90
import React, { useRef, useState, forwardRef } from 'react'
import './App.css'

const Modal = forwardRef(({ open, setOpen, handleDown, handleMove, handleUp, left, top }, ref) => {
    return <div ref={ref} className='Modal' style={{display: open ? 'block' : 'none', position: 'absolute', left, top, width: 300, height: 300, backgroundColor: 'orange'}}
        onMouseDown={handleDown}
        onMouseMove={handleMove}
        onMouseLeave={handleUp}
        onMouseUp={handleUp}
    >
        모달<span style={{backgroundColor: 'green', cursor: 'pointer'}} onClick={() => setOpen(false)}>x</span>
        </div>
})
function App(){
    const [open, setOpen] = useState(false)
    const [clicked, setClicked] = useState(false)
    const [posX, setPosX] = useState(0)
    const [left, setLeft] = useState(0)
    const [posY, setPosY] = useState(0)
    const [top, setTop] = useState(0)
    const container = useRef(null)

    const handleDown = (e) => {
        
        if(open){
            console.log(container.current)
            setClicked(true)
            setPosX(e.pageX - container.current.offsetLeft)
            setPosY(e.pageY - container.current.offsetTop)
        }
    }
    const handleMove = (e) => {
        if(!open) return
        if(!clicked) return  
        console.log("드래그중...")
        e.preventDefault()
        const x = e.pageX - container.current.offsetLeft
        const walkX = x - posX
        const y = e.pageY - container.current.offsetTop
        const walkY = y - posY
        console.log("이동거리 : ", x)
        setLeft(left => left + walkX)
        setTop(top => top + walkY)
    }
    const handleUp = () => {
        setClicked(false)
    }
    return (
        <div className='App'>
            <button onClick={() => setOpen(true)}>열기</button>
            <Modal 
            open={open} 
            setOpen={setOpen} 
            handleDown={handleDown}
            handleMove={handleMove}
            handleUp={handleUp}
            left={left}
            top={top}
            ref={container}
            />
        </div>
    )
}
export default App

 

728x90