TIL.10 | CSS 애니메이션

원용현·2023년 1월 3일
0

TIL

목록 보기
10/18

웹 프로젝트를 진행하며 원하는 사이트를 만들고 난 후에 사이트의 이곳저곳을 돌아다녀보면 재미없고, 별로 들어가보고 싶다는 생각이 크게 들지 않는다.

그 이유는 바로 UI 때문이다. 처음 웹페이지를 접속하는 사용자의 입장에서 UI가 제대로 짜여지지 않은 사이트를 들어가면 눈에 확 띄는 무언가도 없고, 재미없다는 생각이 많이 든다.

그래서 UI를 좀 더 사용자의 입장에서 눈에 확 띄게 주의를 집중시킬 수 있는 무언가가 필요하다. 이번 TIL에서는 CSS를 활용한 애니메이션에 대해서 정리하려고 한다.

CSS 애니메이션

웹 사이트를 이곳저곳 돌아다니다보면 스크롤을 내리는 것에 대해서 특정 애니메이션이 실행되어 사이트를 동적으로 만들어주는 효과를 배워볼 것이다. 애니메이션 효과에 대해서는 여러가지가 있겠지만 크게보면 특정 문구나 이미지가 나타나고, 혹은 사라지는 효과가 대표적이다.

이 글에서는 나타나는 효과와 사라지는 효과 둘 모두 정리할 것이며, 추가적으로 슬라이드 효과에 대해서도 정리할 것이다.

애니메이션을 구현하는 방법에는 크게 2가지가 있는데 하나는 자바스크립트를 사용해서 해당 영역의 스타일을 받아와서 스타일을 수정하는 방식이 있고, 하나는 keyframes을 사용해서 CSS 영역에서 애니메이션을 적용하는 방법이 있다. 이 글에서는 keyframes을 사용하는 방법에 대해서 정리할 것이다.

1. Fade-In / Fade-Out

const FadeIn = keyframes`
  from{
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`
const FadeOut = keyframes`
  from{
    opacity: 1;
  }
  to {
    opacity: 0;
  }
`

각각 Fade-In과 Fade-Out을 keyframes를 사용해서 정의한 것이다. Fade-In의 경우 opacity가 0에서 1로 변경되기 때문에 없던 글자나 이미지가 서서히 나타나는 효과를 적용할 수 있다.

Fade-Out의 경우에는 1에서 0으로 변경되므로 있던 글자나 이미지가 서서히 사라지는 애니메이션을 적용할 수 있다.

위의 keyframes를 적용해서 애니메이션을 적용한 코드는 다음과 같다.

const fade = keyframes`
  from{
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`;

const Body = styled.div`
  height: 2000px;
  width: 100%;
`;

const Text = styled.h1`
  font-size: 6em;
  width: 258px;
  font-family: sans-serif;
  position: absolute;
  top: 200px;
  left: 350px;
  opacity: 0;
  animation: fade 2s ease-out forwards;
`;

export default function Home() {
  return (
    <Body>
      <Text>Animation</Text>
    </Body>
  );
}

위와 같이 작성할 경우에 웹 사이트에 접속하자마자 Text 태그의 글자가 Fade-In 되어 서서히 나타나는 모습을 볼 수 있다.

2. Slide-In / Slide-out

const SlideIn = keyframes`
  from{
    left: -100px;
    opacity: 0;
  }
  to {
    left: 350px;
    opacity: 1;
  }
`;

const SlideOut = keyframes`
  from{
    left: 350px;
    opacity: 1;
  }
  to {
    left: -100px;
    opacity: 0;
  }
`;

각각 Slide-In과 Slide-Out을 keyframes를 사용해서 정의한 것이다. keyframes의 from과 to에 각각 left에 대해서 적용하여 -100px에서 350px로 이동하도록 한다. 해당 값은 필요에 따라서 적절하게 변경하면되며 opacity도 0에서 1로 적용하여 fade와 함께 slide도 적용되도록 하였다.

적용방법은 위의 Fade를 적용한 코드에서 animation: fade 2s ease-out forwards; 부분을 animation: Slide-In 2s ease-out forwards; 으로만 바꿔주면 된다.

문제점

애니메이션 자체는 적용이 되어서 훨씬 보기 좋은 사이트를 만들 수 있지만, 문제는 애니메이션을 적용하고 싶은 영역이 접속하자마자 나타나는 영역이 아닌 스크롤을 아래로 내려야만 보이는 영역에 위치하고 있다면 해당 애니메이션을 볼 수 없다는 문제가 생긴다. 애니메이션 작동 조건에 대해서 따로 지정해둔 것이 없기 때문에 웹 사이트에 접속하자마자 바로 애니메이션이 실행되어 사용자가 스크롤을 내리기 전에 애니메이션이 끝난다면 실제 사용자의 입장에서는 동적으로 실행되는 부분을 보지 못하기 때문에 결국에는 정적인 사이트와 같게된다.

해결방법

애니메이션이 실행되는 조건에 대해서 정의를 해주며 해당 내용을 가지고 조건에 따라서 애니메이션이 실행 되도록 코드를 작성한다.

const SlideIn = keyframes`
  from{
    left: -100px;
    opacity: 0;
  }
  to {
    left: 350px;
    opacity: 1;
  }
`;

const SlideOut = keyframes`
  from{
    left: 350px;
    opacity: 1;
  }
  to {
    left: -100px;
    opacity: 0;
  }

const Body = styled.div`
  height: 2000px;
  width: 100%;
`;

const Text = styled.h1`
  font-size: 6em;
  width: 258px;
  font-family: sans-serif;
  position: absolute;
  top: 200px;
  left: 350px;
  opacity: 0;

  ${(props: { y: number }) =>
    props.y > 10
      ? css`
          animation: ${SlideIn} 2s ease-out forwards;
        `
      : css`
          animation: ${SlideOut} 2s ease-out forwards;
        `};
`;

export default function Home() {
  const [y, setY] = useState(0);

  useEffect(() => {
    window.addEventListener("scroll", function () {
      const value = window.scrollY;
      setY(value);
    });
  });

  return (
    <Body>
      <Text y={y}>Animation</Text>
    </Body>
  );
}
  1. 스크롤 Y 값을 저장할 state 변수 선언.
  2. useEffect 안에 스크롤 이벤트 리스너를 선언, window.scrollY를 통해서 현재 스크롤 위치 저장.
  3. 저장된 값을 Text 태그로 props 전달
  4. Text 태그에서 전달받은 y값으로 삼항 연산자를 통해서 애니메이션 조건을 분기.

주의할 점으로 CSS-in-JS를 사용할 때, 원래는 animation: ${SlideIn} 2s ease-out forwards; 과 같이 작성했지만, 여기에 더 붙여서 css`animation: ${SlideIn} 2s ease-out forwards;` 와 같이 앞에 css임을 의미하는 css를 추가하고 뒤의 내용을 백틱으로 감싸서 사용한다.

위와 같이 코드를 작성하면 스크롤하여 y값이 10보다 커지면 'Animation'이라는 글자가 왼쪽에서 오른쪽으로 슬라이딩되며 서서히 나타나고, y값이 10보다 작아지면 반대로 있던 위치에서 왼쪽으로 이동하며 점점 희미해지며 사라진다.

마무리

이 글에서는 CSS 애니메이션 속성과 keyframes을 사용해서 애니메이션을 구현하였다. 이 외에도 태그의 id 등을 통해서 해당 태그의 내용을 받아와서 style을 직접 변경하여 opacity를 수정하는 방법도 있다.

개인적으로는 keyframes를 사용한 방법이 한눈에 봤을 때, 이것은 애니메이션과 관련된 것이라는 생각이 들어서 좀 더 알아보기 쉬운 것 같다.

추가적으로 css를 통한 애니메이션을 지원하는 라이브러리를 지원하는 사이트를 추가하니 이곳에서 원하는 애니메이션을 선택해서 적용하는 것도 한가지 방법이 될 것이다.
링크 : https://animate.style/

0개의 댓글