이미지의 크기를 조절하고 드래그하는 기능을 구현하기 위해서 react-rnd 라이브러리를 사용했다.
https://www.npmjs.com/package/react-rnd
구현해야 했던 기능으로는
1. 이미지 드래그 (+ 드래그 바운더리 지정)
2. 이미지 크기 조절 (+ 최소 크기 지정)
이 두 가지 여서 react-rnd를 사용하게 되었다.
구글링을 했는데 생각보다 자료가 많이 없어서 당황했지만.. 위의 문서를 보고 구현할 수 있었다.
⭐️ 설치
npm i -S react-rnd
⭐️ 사용방법
<Rnd
default={{
x: initialPo.x,
y: initialPo.y,
width: 100,
height: 100,
}}
minWidth={50}
minHeight={50}
bounds="#limit"
resizeHandleStyles={handleStyles}
lockAspectRatio={true}
>
<img
src={image}
/>
</Rnd>
- default: 초기 위치(x, y)와 초기 크기(width, height)를 설정한다.
- minWidth, minHeight: 최소 크기를 설정한다.
- bounds: 이미지 이동 경로를 제한한다. id=limit인 div를 가져와서 제한해주었다.
- lockAspectRatio: true로 설정해주면 이미지 크기 조절 시, 초기 이미지의 비율을 유지한다.
- resizeHandleStyles: 이미지 크기 조절을 편하게 하기 위한 가이드를 스타일링한다.
const handleStyles =
selected == index
? {
bottomLeft: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
left: "0px",
bottom: "0px",
},
bottomRight: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
right: "0px",
bottom: "0px",
},
topLeft: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
left: "0px",
top: "0px",
},
topRight: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
right: "0px",
top: "0px",
},
}
: {};
위와 같이 작성한 후에 resizeHandleStyles에 넣어주었다.
왼쪽 위, 왼쪽 아래, 오른쪽 위, 오른쪽 위만 다음과 같이 스타일링 해주었다.
사진이 한 장이 아니라 여러 장이 존재하기 때문에
선택된 사진에만 나타나도록 하기 위해 selected === index 일때만 나타나도록 설정해주었다.
하나만 선택되는걸 볼 수 있다!
⭐️ 스크롤 시, 요소는 스크롤되지 않는 오류 발생
여기까지 수월하게 진행돼서 쉽다고 생각했었다.
다 잘되는데 화면을 스크롤하면 요소들이 같이 스크롤되지 않고 제자리에 있는 오류가 생겼다🙀
공식문서를 다시 잘 읽어보니
nearest node with position relative or absolute라고 나와있었다.
내가 지정해줬던 id=limit인 div 태그에 따로 position을 지정해주지 않은 것 같아서
div 태그에 position: "relative"를 추가해주니 오류가 해결되었다.
잘 동작하는걸 확인할 수 있다.
⭐️ 전체코드
import React, { useEffect, useRef, useState } from "react";
import { Rnd } from "react-rnd";
const Image = ({ image, initialPo, selected, changeSelected, index }) => {
const handleClick = () => {
changeSelected(index);
};
const handleStyles =
selected == index
? {
bottomLeft: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
left: "0px",
bottom: "0px",
},
bottomRight: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
right: "0px",
bottom: "0px",
},
topLeft: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
left: "0px",
top: "0px",
},
topRight: {
width: "10px",
height: "10px",
border: "0.5px solid #777777",
right: "0px",
top: "0px",
},
}
: {};
return (
<Rnd
default={{
x: initialPo.x,
y: initialPo.y,
width: 100,
height: 100,
}}
minWidth={50}
minHeight={50}
bounds="#limit"
resizeHandleStyles={handleStyles}
lockAspectRatio={true}
>
<img
src={image}
onClick={() => {
handleClick(index);
}}
onTouchStart={() => {
handleClick(index);
}}
/>
</Rnd>
] );
};
export default Image;
'React' 카테고리의 다른 글
[React]useState 비동기(+동기처리 방법) (5) | 2024.05.21 |
---|---|
[React]axios multiple request(request 여러 개 요청하기) (6) | 2024.04.30 |
[React]onFocus, onBlur (0) | 2024.04.17 |
[React]React 프로젝트 폰트 변경하기(눈누) (0) | 2024.03.30 |
[React] 상태관리 라이브러리 Recoil (0) | 2024.03.29 |