window API , requestAnimationFrame 살펴보기

Devback·2022년 3월 27일
0
post-thumbnail
post-custom-banner

"프레임워크 없는 프론트엔드"라는 책을 읽다가 requestAnimation라는 메소드를 만나보게 되었다. 이번에 처음 본건 아닌데 이참에 정리해보면 좋을거 같다.

문법

window.requestAnitmation(callback);
callback 함수는 반드시 자기 자신을 가르켜야 한다.

특징

  • setInterval과 달리 백그라운드에서 실행이 중단되는 장점이 있다.
  • 콜백의 수는 보통 1초에 60회이다.

window.requestAnimationFrame() 메소드는 브라우저에게 수행하기 원하는 애니메이션을 알리고 리페인트가 진행되기 전 해당 애니메이션을 업데이트하는 함수를 호출하게 한다. 즉, 리페인트 이전에 실행할 콜백을 인자로 받는다. 그런데 애니메이션의 경우, 리페인트 과정이 끝나지도 않았는데 다음 좌표로 이동하라고 애니메이션을 수행하는 경우, 애니메이션이 의도한 대로 부드럽게 움직이지 않게 된다. requestAnimationFrame은 이러한 문제를 해결해준다.

MDN 예제

const element = document.getElementById('some-element-you-want-to-animate');
let start, previousTimeStamp;
let done = false

function step(timestamp) {
  if (start === undefined) {
    start = timestamp;
    }
  const elapsed = timestamp - start;

  if (previousTimeStamp !== timestamp) {
    // Math.min() is used here to make sure the element stops at exactly 200px
    const count = Math.min(0.1 * elapsed, 200);
    element.style.transform = 'translateX(' + count + 'px)';
    if (count === 200) done = true;
  }

  if (elapsed < 2000) { // Stop the animation after 2 seconds
    previousTimeStamp = timestamp
    !done && window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);

다른 간단한 박스 이동 예제

<body>
    <div>
      <div id="container" style="width: 500px; border: 1px solid">
        <div
          id="animate-box"
          style="width: 50px; height: 50px; background: wheat"
        ></div>
      </div>
    </div>
    <script>
      const element = document.getElementById("animate-box");
      const parentElement = document.getElementById("container");

      function move(timestamp) {
        const elementLocate = element.getBoundingClientRect();
        const containerLocate = parentElement.getBoundingClientRect();

        element.style.transform = "translateX(" + elementLocate.left + "px)";

        if (
          elementLocate.left <
          containerLocate.width - elementLocate.width - 10
        ) {
          requestAnimationFrame(move);
        }
      }

      requestAnimationFrame(move);
    </script>
  </body>

Note

MDN에 따르면 엣지 버전이 17 미만과 Internet Explorer는 페인트 사이클 전에 requestAnimationFrame을 확실하게 실행할 수 없다고 한다.

참고:
https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
https://blog.coderifleman.com/2016/12/02/how-to-test-request-animation-frame/

profile
나랑 같이 개발할 사람🖐
post-custom-banner

0개의 댓글