개발 기술/개발 이야기

[JS] 애니메이션을 만드는 2가지 방법(setInterval, requestAnimationFrame)

by GicoMomg 2022. 8. 6.

🤔 이번 시간에는 js에서 애니메이션을 만드는 2가지 방법(setInterval, requestAnimationFrame(rAF))에 대해 알아보았다!


애니메이션을 만드는 2가지 방법

1) setInterval 사용하기

(1) setInterval이란?

  • setInterval()은 일정한 시간동안 func을 반복적으로 실행하는 함수이다.
setInterval(func, delay)

  • setInterval()을 사용하면, 초당 n번 반복하는 애니메이션을 만들 수 있다.
  • 만약 setInterval()을 멈추고 싶다면 clearInterval()setInterval() 의 리턴값을 인자로 넘겨주면 된다.
const timer = setInterval(func, delay);

clearInterval(timer);   // this!

(2) 예시

  • 아래 예시는 시작 버튼을 누르면 바가 길어지는 애니메이션을 setInterval()로 구현한 모습이다.

See the Pen setInterval example by KumJungMin (@kumjungmin) on CodePen.



  • 코드를 설명하면 아래와 같다.
  • 먼저 필요한 dom(bar)를 가져오고, width, intervalId를 선언한다.
const bar = document.querySelector('.bar');  // bar dom 가져오기

let width = 10;   // 너비 변수
let intervalId;   // setInterval의 고유 id

  • 그 다음, bar의 너비가 최대 200까지 길어지는 애니메이션 함수를 생성한다.
// bar의 너비가 최대 200까지 길어지는 애니메이션
function animation() {
  bar.style.width = `${width}px`;
  width += 10;
  if (width > 200) clearInterval(intervalId);
}

  • setInterval 실행 함수를 생성해준다.
  • setInterval의 리턴값을 intervalId에 담아주는데, 이 변수는 clearInterval에 사용한다.
// setInterval 실행 함수
function render() {
  intervalId = setInterval(animation, 1000/60);
}

  • 테스트 시작 버튼을 클릭했을 때 width를 10으로 초기화시킨 후 render함수를 실행시킨다.
function onClick() {
  width = 10;
  render();
}



2) requestAnimationFrame(rAF) 사용하기

(1) rAF란?

  • rAF는 브라우저에서 수행하고 싶은 애니메이션을 등록하여, 브라우저에서 리패인드가 발생하기 전에 해당 애니메이션을 실행시킨다.
  • 인자로는 callback(애니메이션 실행 함수), 하나만 넘겨주면 된다.
window.requestAnimationFrame(callback);

  • callback은 1초에 60회 실행(60FPS)되나, W3C 권장사항에 따라 프레임 수가 디스플레이 주사율(1초에 몇 개의 장면을 화면에 표시할 수 있는지 나타내는 수치)로 설정된다.
  • 최신 브라우저에선 성능&배터리 수명을 위해 백그라운드탭, hidden iframe에서는 rAF의 실행을 중단시킨다.

📌 그럼, rAF실행을 어떻게 중단시킬 수 있나요?

  • rAFsetInerval처럼 고유한 id값을 리턴해준다.
  • 해당 id값을 window.cancelAnimationFrame에 인자로 넘겨주면 해당 애니메이션 실행을 중단시킬 수 있다.
const id = window.requestAnimationFrame(callback);

window.cancelAnimationFrame(id);  // this!

(2) 예시

  • 아래 예시는 시작 버튼을 누르면 바가 길어지는 애니메이션을 rAF로 구현한 모습이다.

See the Pen requestAnimationFrame example by KumJungMin (@kumjungmin) on CodePen.



  • 코드를 설명하면 아래와 같다.
  • 애니메이션을 적용한 bar를 가져오고 width변수를 선언한다.
const bar = document.querySelector('.bar');
let width = 10;

  • bar의 너비가 최대 200까지 늘어나는 애니메이션 함수를 생성해준다.
function render() {
  bar.style.width = `${width}px`;
  width += 10;  
  const id = requestAnimationFrame(render);     // callback 재호출
  if (width > 200) cancelAnimationFrame(id);    // rAF리턴값으로 애니메이션 중단시킴
}

  • 테스트 시작 버튼을 클릭했을 때 width를 10으로 초기화시킨 후 render함수를 실행시킨다.
function onClick() {
  width = 10;
  render();
}



3) setInterval vs rAF의 차이

(1) 초당 호출 횟수

  • setIntetval은 인자(delay)를 넘겨 초당 호출 횟수를 지정할 수 있다.
  • 하지만 rAF는 브라우저의 리소스 & 컴퓨터의 CPU성능을 고려하여 초당 실행횟수가 결정된다.(기본 60FPS)
60FPS = 초당 60프레임 = 프레임당 16ms

(2) 실행 방식

  • setInterval로 애니메이션을 만들 때는, funcdelay만 설정해주면 된다.
setInterval(func, delay);

  • rAF의 경우, rAFcallback내부에서 rAF를 재호출해줘야 애니메이션 실행이 가능하다.
requestAnimationFrame(render);

function render() {
  ...
  requestAnimationFrame(render);  // 재호출
}

(3) 실행 중단 방식

  • setInterval은 고유한 id값을 리턴하므로, clearInterval에 해당 id값을 넘겨주면 중단 가능하다.
const id = setInterval(func, delay);

clearInterval(id);  // 중단!

  • rAF도 고유한 id값을 리턴하는데, 이 id값을 cancelAnimationFrame에 넘겨주면 중단 가능하다.
const id = window.requestAnimationFrame(callback);

window.cancelAnimationFrame(id);  // this!

(4) 실행 예시 보기

  • setInterval를 초당 60프레임으로 설정하였다.
  • 만약 rAF의 실행결과가 setInterval가 다르다면, rAF가 사용자 브라우저 & 컴퓨터 성능에 따라 다른 속도로 실행되기 때문이다.

See the Pen setInterval vs requestAnimationFrame by KumJungMin (@kumjungmin) on CodePen.

반응형

댓글