[CSS] keyFrames 애니메이션 초기화

Wooki·2023년 6월 27일
0

CSS

목록 보기
8/9

React로 슬라이드 컴포넌트를 제작하던 도중 상태가 변경되면 CSS 애니메이션이 초기화되도록 구현할 필요가 있어서 관련 정보를 찾아봤다.

애니메이션 초기화 원리

애니메이션을 가지는 요소에 animation 값을 "none"으로 부여했다가 null을 부여하는 방법이였다.

const resetAnimation = () => {
  animationElement.current.style.animation = "none"; --- A
  animationElement.current.style.animation = null; --- B
}

하지만 위 코드처럼 작성하게 되면 애니메이션 초기화가 되지 않는다.

브라우저는 페이지가 연속적으로 변경됨으로 인해서 발생하는 자원 낭비를 막기 위해서
변경사항을 누적해뒀다가 A, B코드가 각각 실행될 때마다 화면을 다시 그리지 않고 마지막에 일괄 처리하여 화면을 다시 그리게 된다.

이때 일괄처리하는 과정에서 초기 상태와 달라진게 없다면 브라우저는 해당 요소를 다시 그리지 않는다.

  1. animationElement.current.style.animation = "none"
    -> 브라우저는 해당 요소의 animation을 none으로 설정하지만 리렌더링을 하지는 않는다.
  2. animationElement.current.style.animation = null;
    -> 브라우저는 해당 요소의 animation을 none으로 설정하지만 리렌더링을 하지는 않는다.
  3. 해당 함수가 완료되었으므로 브라우저는 리렌더링을 하기 위해서 값을 확인하지만 결론적으로 변한 값이 없으므로 리렌더링을 발생시키지 않는다!

setTimeout를 사용하는 방법

setTimeout을 이용해서 구현한 방법이다.

const animationElement = useRef(null);
const resetAnimation = () => {
  animationElement.current.style.animation = "none";
  setTimeout(()=>{
    animationElement.current.style.animation = null;
  },500);
}

setTimeout을 이용해서 "none" 설정하는 코드와 null로 설정하는 코드에 시간차를 둬서 브라우저가 다시 그릴 시간을 주는 방법이 있다.

하지만 해당 경우는 내가 구현하고자 하는 컴포넌트랑 잘 맞지 않아서 다른 방법을 찾아보았다.

offsetWidth 를 사용하는 방법

const resetAnimation = () => {
  animationElement.current.style.animation = "none";
  void animationElement.current.offsetWidth; --- 3
  aniamtionElement.current.style.animation = null;
}

두 연산 사이에 void 요소.offsetWidth를 한줄 추가하는 방법이다.

offsetWidth 값을 구하기 위해서 브라우저는 변경사항 일괄 처리를 포기하고 페이지를 다시 그려야만 하기 때문에 두 코드 사이에 강제적인 페이지 렌더링이 발생해서 정상적으로 애니메이션 초기화가 발생한다!

  1. animationElement.current.style.animation = "none"
    -> 브라우저는 해당 요소의 animation을 none으로 설정하지만 리렌더링을 하지는 않는다.
  2. void animationElement.current.offsetWidth;
    -> offsetWidth의 값을 구하기 위해서 브라우저는 이전 변경사항들을 적용하고 리렌더링을 실시한다.
  3. animationElement.current.style.animation = null;
    -> 브라우저는 해당 요소의 animation을 none으로 설정하지만 리렌더링을 하지는 않는다.
  4. 함수가 완료되었으므로 브라우저는 변경사항을 반영하여 화면을 다시 그리게 된다.

참고

Stack Overflow

profile
웹 개발자

0개의 댓글

관련 채용 정보