๊ฐœ๋ฐœ ๐Ÿพ/ReactJS

react draggable ๊ฐ„๋‹จ ์ƒ˜ํ”Œ

JOTOKKI 2021. 6. 22. 16:05
728x90
react-draggable : https://www.npmjs.com/package/react-draggable
 

react-draggable

React draggable component

www.npmjs.com

 

๊ฐ์ฒด๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๋“œ๋ž˜๊ทธํ•˜๋Š” ๋ชจ์…˜์„ ์ฐพ๋‹ค๊ฐ€ ์ง์ ‘ ๊ตฌํ˜„๋„ ํ•ด๋ณด์•˜์ง€๋งŒ ๋ Œ๋”ํ•˜๋Š” ๊ณผ์ •์—์„œ buffer๊ฐ€ ์ƒ๊ธฐ๋Š”๊ฒƒ ๊ฐ™์•„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐพ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. 

์•„์ฃผ ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•œ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž…๋‹ˆ๋‹ค. 

 

1. ์„ค์น˜

npm install react-draggable

 

2. ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ์ ์šฉ

import Draggable from "react-draggable"; 

export default function App() {
  const [position, setPosition] = useState({ x: 0, y: 0 }); // box์˜ ํฌ์ง€์…˜ ๊ฐ’
  // ์—…๋ฐ์ดํŠธ ๋˜๋Š” ๊ฐ’์„ set ํ•ด์คŒ
  const trackPos = (data) => {
	setPosition({ x: data.x, y: data.y }); 
  };
  return (
  <div className="App">
    <Draggable onDrag={(e, data) => trackPos(data)} >
      <div className="box" >
        <div>BOX</div>
        <div>x: {position.x.toFixed(0)}, y: {position.y.toFixed(0)}</div>
      </div>
    </Draggable>
  </div>
  );
}
// css
.box {
  position: absolute;
  cursor: move;
  color: black;
  width: 100px;
  border-radius: 5px;
  padding: 1em;
  margin: auto;
  user-select: none;
  background: lightgrey;
}

Draggable๋กœ ๊ฐ์‹ผ๋’ค ํ•„์š”ํ•œ ์˜ต์…˜๊ณผ ํ•จ์ˆ˜๋ฅผ props์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. 

x, y ์ขŒํ‘œ๋ฅผ toFixed(0) ์œผ๋กœ ์†Œ์ˆ˜์ ์„ ์ œ์™ธํ•œ ๊ฐ’์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. 

์ฐธ๊ณ ๋กœ ๋ฐ˜๋“œ์‹œ css์—์„œ absolute๋ฅผ ์ค˜์•ผ ์ž‘๋™์ด ๋˜๋Š”๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. 

onDrag ์ด์™ธ์— ๋‹ค์–‘ํ•œ ์˜ต์…˜๊ฐ’์ด ์žˆ์Šต๋‹ˆ๋‹ค. ( ์ƒ๋‹จ react-draggable ์‚ฌ์ดํŠธ์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ )

์ ์šฉ์‹œ ๋™์ž‘์ด ์ œ๋Œ€๋กœ ๋˜๋”๋ผ๋„ ์ฝ˜์†”์— ์—๋Ÿฌ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ’ฆ
useRef๋ฅผ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ฒฐ๊ณผ

 

 

3. ๋“œ๋ž˜๊ทธ ์ค‘ ํšจ๊ณผ์ฃผ๊ธฐ

๋“œ๋ž˜๊ทธ์ค‘ onStart์™€ onStop ์˜ต์…˜์„ ํ†ตํ•ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

๋“œ๋ž˜๊ทธ ์ค‘ opacity๋ฅผ ์ฃผ๋Š” ํšจ๊ณผ๋ฅผ ์ ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

{ ... }
const [Opacity, setOpacity] = useState(false);

const handleStart = () => {
  setOpacity(true);
};
const handleEnd = () => {
  setOpacity(false);
};

{...}

<Draggable
  nodeRef={nodeRef}
  onDrag={(e, data) => trackPos(data)}
  onStart={handleStart}
  onStop={handleEnd}
>
  <div
    ref={nodeRef}
    className="box"
    style={{ opacity: Opacity ? "0.6" : "1" }}
  >
    <div>BOX</div>
    <div>
      x: {position.x.toFixed(0)}, y: {position.y.toFixed(0)}
    </div>
  </div>
</Draggable>

์ด๋ ‡๊ฒŒ onStart์„ ํ†ตํ•ด ๋“œ๋ž˜๊ทธ๋ฅผ ํ•˜๋Š” ์‹œ์ ์—์„œ setState๋ฅผ ํ•˜์—ฌ style ๋˜ํ•œ ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด, onStop์„ ํ†ตํ•ด ๋“œ๋ž˜๊ทธ๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ์‹œ์ ์— ๋‹ค์‹œ setState๋ฅผ ํ•˜์—ฌ stlye์„ ๋ณ€๊ฒฝํ•ด ์ค๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

 

๋ฐ˜์‘ํ˜•