스크립트 기반 애니메이션용 타이밍 컨트롤("requestAnimationFrame")

Internet Explorer 10 및 JavaScript로 작성한 Windows 스토어 앱은 requestAnimationFrame 메서드를 새롭게 지원합니다. 이 메서드는 시스템이 프레임을 그릴 준비가 되었을 때 애니메이션 프레임을 호출하여 애니메이션 웹 페이지를 만들 수 있는 더 유연하고 효율적인 방법을 제공합니다. 이 API 전에 setTimeoutsetInterval을 사용하여 그린 애니메이션은 웹 개발자에게 애니메이션의 그래픽 타이머를 예약할 수 있는 효율적인 방법을 제공하지 않았습니다. 따라서 애니메이션이 과도하게 그려지고, CPU 주기가 낭비되었으며, 추가 전력이 사용되었습니다. 또한 웹 사이트가 보이지 않을 때, 특히 웹 사이트가 배경 탭의 페이지를 사용하거나 브라우저가 최소화된 경우에도 애니메이션이 종종 발생합니다.

애니메이션에서 10밀리초의 aJavaScript 타이머 확인을 사용할 경우 여기 표시된 대로 타이밍 불일치가 발생합니다.

디스플레이 주파수와 JavaScript 타이머 확인 간의 주파수 차이를 보여 주는 다이어그램

맨 위 행은 대부분의 모니터에 표시되는 16.7밀리초 디스플레이 주파수를 나타내고 맨 아래 행은 일반적인 10밀리초 setTimeout을 나타냅니다. 디스플레이 새로 고침 간격 전에 그리기 요청이 한 번 더 발생하기 때문에 매 세 번째 그림은 그릴 수 없습니다(빨간색 화살표로 표시). 이러한 과도한 그리기는 매 세 번째 프레임이 손실되기 때문에 애니메이션이 끊어지는 현상을 가져옵니다. 이러한 타이머 확인 감소는 또한 배터리 수명에도 좋지 않은 영향을 미치고 다른 앱의 성능을 저하시킬 수 있습니다.

W3C(World Wide Web 컨소시엄)의 스크립트 기반 애니메이션의 타이밍 컨트롤(영문) 사양에 정의된 requestAnimationFrame 메서드는 브라우저가 페이지 디스플레이를 업데이트해야 할 때만 앱에 알리도록 할 수 있으므로 프레임 손실 문제를 해결할 수 있습니다. 따라서 앱이 브라우저 그리기 간격에 맞춰 완벽하게 조정되며 적절한 리소스 양만 사용합니다. 둘 다 단일 콜백을 예약하므로 setTimeout에서  requestAnimationFrame으로 전환하는 것은 간단합니다. 애니메이션을 지속하려면 애니메이션 함수가 호출된 후에 requestAnimationFrame을 다시 호출합니다.

requestAnimationFrame 사용

이 새 API를 사용하려면 콜백 함수를 사용하여 requestAnimationFrame을 호출하면 됩니다. 타이밍은 시스템에 의해 처리됩니다. 다음과 같이 현재 setTimeout을 사용하여 애니메이션 타이밍을 조정하는 경우


var handle = setTimeout(renderLoop, PERIOD);

아래에 표시된 대로 setTimeoutrequestAnimationFrame으로 바꿀 수 있습니다.


var handle = requestAnimationFrame(renderLoop);

이는 첫 번째 다시 표시를 처리합니다. 애니메이션을 계속 진행하려면 콜백 함수 내에서 requestAnimationFrame을 다시 호출합니다(여기에서 renderLoop로 표시됨).


<!DOCTYPE html>
<html>
  <head>
    <title>Script-based animation using requestAnimationFrame</title>
    <style type="text/css">
     #animated { 
       position: absolute; top:100px; 
       padding: 50px; background: crimson; color: white; 
       }
    </style>

 
  </head>
  <body>
    <div>Click the box to stop and start it</div>
    <div id="animated">Hello there.</div>
   
    <script type="text/javascript">
      // global variables 
      var elm = document.getElementById("animated");
      var handle = 0;
      var lPos = 0;

      renderLoop();  // call animation frame to start

      function renderLoop() {
          elm.style.left = ((lPos += 3) % 600) + "px";
          handle = window.requestAnimationFrame(renderLoop);
      }

      // click the box to stop the animation 
      document.getElementById("animated").addEventListener("click", function () {
        if (handle) {
          window.cancelAnimationFrame(handle);
          handle = null;
        } else {
          renderLoop();
        }
      }, false);

      </script>

  </body>
</html>


이 예제에서는 먼저 getElementById를 사용하여 <div> 요소를 전역 변수에 저장합니다. renderLoop() 함수가 호출되어 애니메이션을 시작합니다. <div> 요소의 위치가 변경된 후에 requestAnimationFrame이 다시 호출되어 다음 이동을 설정합니다. 이는 브라우저를 닫거나 <div> 요소를 클릭할 때까지 계속됩니다.

addEventListener 메서드는 <div> 요소의 클릭 이벤트를 처리합니다. 요소를 클릭하면 현재 핸들과 함께 cancelAnimationFrame이 호출됩니다.

콜백 함수의 시간

콜백 함수를 사용하여 예를 들어 SVG, Canvas 또는 여기에서 보는 바와 같이 CSS 속성을 비롯하여 거의 모든 것에 애니메이션 효과를 줄 수 있습니다. 이 콜백 함수에는 들어오는 time 매개 변수 한 개가 있고 이 매개 변수는 콜백 함수가 호출된 시간을 나타냅니다. 이는 페이지의 탐색 시작부터 측정된 고해상도 시간인 DOMHighResTimeStamp입니다. DOMHighResTimeStamp는 밀리초로 측정되며 밀리초의 천분의 1까지 정확하게 측정됩니다. 이 시간 값은 1970년 1월 1일 이후 시간을 밀리초로 측정하는 Date.now()와 직접 비교할 수 없습니다. time 매개 변수를 현재 시간과 비교하려면 현재 시간에 대해 window.performance.now를 사용하세요. 시간 값을 DOMTimeStamp에서 DOMHighResTimeStamp로 변경하는 것은 W3C 스크립트 기반 애니메이션의 타이밍 컨트롤(영문) 사양의 최신 편집자 초안에 포함된 최근 변경 사항이므로 일부 공급업체는 시간 값을 여전히 DOMTimeStamp로 구현할 수 있습니다. W3C 사양의 이전 버전에서는 DOMTimeStamp를 사용했으며, 이때는 현재 시간에 Date.now를 사용할 수 있었습니다.

브라우저 지원

위에서 설명한 대로 일부 브라우저 공급업체는 여전히 DOMTimeStamp 매개 변수를 구현했거나 window.performance.now 타이밍 함수를 구현하지 않았을 수 있습니다. W3C 사양이 아직 최종본이 아니기 때문에 다른 브라우저 제조업체는 자체 접두사가 추가된 requestAnimationFramecancelAnimationFrame의 구현을 만들었습니다. 이 예제에서는 여러 브라우저에서 작동하며 <div> 요소를 이동하는 시간을 사용하는 애니메이션 프로그램 버전 하나를 제공합니다.


<!DOCTYPE html>
<html>
<head>
<title>Script-based animation using requestAnimationFrame</title>
<style type="text/css">
div { position: absolute; left: 10px; top:100px; padding: 50px;
  background: crimson; color: white; }
</style>
<script type="text/javascript">
    var requestId = 0;
    var startime = 0;
    var lpos = 0;
    var elm;

    function init() {
        elm = document.getElementById("animated");
    }
    
    function render() {
        elm.style.left = ((lpos += 3) % 600) + "px";
        requestId = window.requestAFrame(render);
    }

    function start() {
        if (window.performance.now) {
            startime = window.performance.now();
        } else {
            startime = Date.now();
        }
        requestId = window.requestAFrame(render);
    }
    function stop() {
        if (requestId)
            window.cancelAFrame(requestId);        
    }


    // handle multiple browsers for requestAnimationFrame()
    window.requestAFrame = (function () {
        return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                // if all else fails, use setTimeout
                function (callback) {
                    return window.setTimeout(callback, 1000 / 60); // shoot for 60 fps
                };
    })();

    // handle multiple browsers for cancelAnimationFrame()
    window.cancelAFrame = (function () {
        return window.cancelAnimationFrame ||
                window.webkitCancelAnimationFrame ||
                window.mozCancelAnimationFrame ||
                window.oCancelAnimationFrame ||
                function (id) {
                    window.clearTimeout(id);
                };
    })();

   
</script>
</head>
<body onload="init();">

<div id="animated">Hello there.</div>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
</body>
</html>


이 예제는 공급업체 접두사가 있는 요소가 추가된 W3C 사양 샘플의 확장 버전입니다. 이 예제에서는 추가적으로 window.performance.now를 테스트하며 지원되지 않으면 Date.now를 사용하여 현재 시간을 가져옵니다.

API 참조

requestAnimationFrame

샘플 및 자습서

requestAnimationFrame을 사용한 효율적인 애니메이션 샘플

Internet Explorer 테스트 드라이브 데모

거품형
requestAnimationFrame API

IEBlog 게시물

W3C 웹 성능: 성능 투자 계속
웹 성능 API가 빠르게 W3C 후보 권고안으로 제안됨
IE10 Release Preview에서 웹 안정성 향상
연간 리뷰: W3C 웹 성능 작업 그룹
HTML5에서 보다 효율적인 PC 하드웨어 사용: 새로운 웹 성능 API, 1부

사양

스크립트 기반 애니메이션용 타이밍 컨트롤

 

 

표시:
© 2014 Microsoft