[CSS] 크기와 위치 변환 애니메이션

ksj0314·2024년 5월 21일

CSS

목록 보기
4/6

문제점 : 리액트의 한 컴포넌트(Com3)의 위치를 부모 요소(Com2)의 위치에서 부모의 부모요소(Com1)의 위치로 변환시키는 애니메이션을 주고싶다.

Com1에는 postion: relative;를 준 상태

// JSX
const open = keyframes`
    100% {
        top: 0;
        left: 0;
    }
`;

const Com3 = styled.div`
    border: 1px solid blue;
    position: absolute;
    animation: ${open} 1s forwards;
`;

position값을 주어도 top, left를 주지않으면 Com3은 Com2의 내부에 위치한다.
애니메이션으로 top, left를 0을 주면 Com1을 기준으로 위치가 변환된다.

하지만 위 코드를 적용하면 애니메이션이 적용되지 않는다.

이유 : top, left를 설정하지 않으면 Com2를 기준으로 위치해있긴 하지만 애니메이션의 시작점을 설정해준것은 아니라서 서서히 이동되지 않는다.

해결방안 : top과 left의 초기값을 설정해준다.

top과 left의 초기값은 Com2을 기준으로 해야한다.
하지만 Com3의 top, left는 Com1을 기준으로 설정된다.
=> Com1을 기준으로 Com2의 top, left를 구하여 Com3로 전달해준다.

우선 자식요소가 부모요소로부터 어느정도 떨어진지 나타내주는 값은 따로 존재하지 않는다.
=> 뷰포트를 기준으로 각각의 위치값을 얻어 연산하여 위치값을 동적으로 구한다.

// JSX
function Com1(props){
    const [position, setPosition] = useState({ top: 0, left: 0 });
    const parentRef = useRef();

    useEffect(() => {
        const parentElement = parentRef.current;
        if (parentElement) {
            const rect = parentElement.getBoundingClientRect();
            setPosition({ top: rect.top, left: rect.left });
        }
    }, []);

	return (
      	<div ref={parentRef}>
    		<Com2 parentPosition={position}/>
        </div>
    );
}
  • useRef()를 이용해 구하려는 요소를 가져온다.
  • useEffect()를 이용해 요소가 렌더링된 후 getBoundingClientRect()통해 위치값을 구한다.

Com2에서도 비슷한 로직을 구현하여 위치값을 얻어 Com1에서 받은 parentPosition값을 빼줘 Com3으로 전달해주어 Com3의 초기 top, left를 구한다.

∴ 애니메이션이 적용되려면 시작점(from)과 끝점(to)의 값을 잘 설정해야한다.

0개의 댓글