(CSS) (Styled-components) 아이콘 클릭시 제자리 회전 시키기

개발차 DevCHA·2022년 9월 6일
2

드롭다운 메뉴에서 아이콘을 클릭하면 제자리에서 부드럽게 회전하는 애니메이션을 구현해보려고 한다.
완성된 모습은 아래와 같다.

여러가지 방법이 있겠지만 나는 CSS 구현시 Styled-components를 이용하고 있으므로 keyframes를 import해서 사용했다.

import styled, { keyframes } from "styled-components";

클릭하면 0도에서 180도로, 다시 클릭하면 180도에서 0도로 돌아와야 한다.
즉 애니메이션 두 개를 만든다.

(완성하고 나서 animation-direction 속성으로 reverse를 주면 반대 방향으로 변경할 수 있다는 걸 알게 됐다. 다음 번엔 이걸로 해봐야겠음)

const AniUp = keyframes`
  0% {
    transform:rotate(0deg);
  }
  100%{
    transform:rotate(180deg);
  }
`;

const AniDown = keyframes`
  0% {
    transform:rotate(180deg);
  }
  100%{
    transform:rotate(0deg);
  }
`;

(0%는 시작 지점, 100%는 끝 지점을 뜻함. 중간에 50%같은거 넣어도 됨)

그 다음 span 태그를 만들어서 애니메이션을 넣어 주었다.
(여기서는 span을 썼지만 div든 p든 아무거나 써도 상관없음)

const Animation1 = styled.span`
  animation: ${AniDown} 0.35s linear forwards;
`;

const Animation2 = styled.span`
  animation: ${AniUp} 0.35s linear forwards;
`;

이제 애니메이션을 만들었으니 아이콘이 위치한 헤더로 간다.

H O W E V E R ..........

지난번 드롭다운 메뉴를 만들 때 useState를 이용해서 true, false로 메뉴가 보일지 안보일지 결정했었다. 그런데 애니메이션을 넣으니 클릭을 하지 않고 새로고침만 했을 때도 애니메이션이 실행되는 문제가 발생했다. (=초기값이 false이기 때문에 드롭다운 아이콘이 위로 돌아가는 애니메이션 실행됨)

이 문제를 해결하기 위해 true, false 외에 null 값을 초기값으로 두었다.

최종 코드

const [view, setView] = useState(null);

...중략...
		<HeaderUl
            onClick={() => {
              setView((prev) => {
                return !prev ? true : false;
              });
            }}
          >
            반가워요, nickName 님!{" "}
            {view === null && (
              <div>
                <KeyboardArrowDownIcon viewBox="0 -7 24 24" />
              </div>
            )}
            {view && (
              <>
                <Animation1>
                  <div>
                    <KeyboardArrowUpIcon viewBox="0 -5 24 24" />
                  </div>
                </Animation1>
                <Dropdown />
              </>
            )}
            {view === false && (
              <Animation2>
                <div>
                  <KeyboardArrowUpIcon viewBox="0 -5 24 24" />
                </div>
              </Animation2>
            )}
          </HeaderUl>

간단 해설

  1. UL('안녕하세요 nickName 님 (icon)')을 클릭하면 view의 이전 상태값을 prev으로 받아서 falsy한 값일 경우 true로, true일 경우 false로 반환한다.

falsy 값: false, null, undefined, 0, ""(빈 문자열), NaN

  1. view가 null일 경우 정지해 있는 KeyboardArrowDownIcon을 보여준다.

  2. view가 true일 경우 Animation1을 실행하고 Dropdown 컴포넌트를 보여준다.

  3. view가 false일 경우 Animation2를 실행한다.


사족

viewBox="0 -7 24 24" 는 아이콘(svg) 위치와 크기 설정값.

아이콘을 div로 감싸준 이유는 중앙을 잡아줘야 제자리에서 돌기 때문

0개의 댓글