다음을 통해 공유


캔버스 그래픽에 애니메이션 효과를 주는 방법(HTML)

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

캔버스 요소는 애니메이션, 그래픽, 게임 등의 그래픽 생성을 위해 JavaScript를 사용할 수 있는 HTML 문서 상의 그리기 가능한 영역입니다. 이 항목은 캔버스 요소를 사용하여 기본 그리기에 애니메이션 효과를 주는 데 필요한 단계에 대해 설명하는 것으로 시작합니다.

사전 요구 사항

이 항목에서는 다음을 가정합니다.

  • JavaScript용 Windows 라이브러리 템플릿을 사용하는 JavaScript로 작성한 기본 Windows 스토어 앱을 만들 수 있습니다.
  • HTML 및 JavaScript에 대해 기본적으로 이해하고 있습니다.

JavaScript로 작성된 첫 번째 Windows 스토어 앱을 만드는 방법에 대한 자세한 내용은 JavaScript를 사용하는 첫 번째 Windows 스토어 앱 만들기를 참조하세요. WinJS 템플릿 사용에 대한 지침은 WinJS 도구 키트를 얻고 사용하는 방법을 참조하세요.

지침

단계 1: 애니메이션 시간 지정

requestAnimationFrame 메서드에서 다음에 다시 표시하기 위해 애니메이션을 업데이트해야 할 때마다 호출할 함수(콜백)를 지정하여 애니메이션을 시작합니다.

requestAnimationFrame(animationFunction);

requestAnimationFrame은 페이지 표시 유형 및 디스플레이의 새로 고침 빈도를 고려하여 애니메이션에 할당할 초당 프레임 수를 결정합니다(즉, animationFunction 호출).

JavaScript 예제에서는 더 큰 원을 따라 나선형으로 움직이는 살아 있는 원을 그리게 됩니다.

requestAnimationFrame(draw);

다음은 해당 애니메이션입니다. 결과를 달라질 수 있으며 하드웨어가 빠를수록 원의 간격이 더 가까워집니다.

캔버스 애니메이션에 의해 그려진 나선 원의 예

단계 2: 이미지 그리기

  1. 캔버스 지우기

    각 프레임을 그리기 전에 캔버스를 지워야 합니다.

    캔버스나 이미지의 일부를 지우는 다양한 방법이 있습니다. 예를 들어 globalCompositOperation 속성을 사용하여 특정 영역을 지우거나 clip 메서드를 사용하여 경로를 자릅니다. 캔버스를 지우는 가장 간단한 방법은 clearRect 메서드를 사용하는 것입니다.

    다음 예제에서는 clearRect 메서드를 사용하여 전체 캔버스를 지우지만 이미지를 그리는 효과를 보기 쉽도록 clearRect 메서드를 주석 처리합니다. 이 코드 줄의 주석 처리를 제거하면 큰 원형 궤도로 회전하는 작은 원이 표시되며 각 프레임을 그리기 전에 흔적이 지워집니다.

    // The clearRect method clears the entire canvas.
    context.clearRect(0, 0, 160, 160);
    
  2. 캔버스 상태 저장

    이미지를 그릴 때 스타일이나 변환 등의 일부 설정을 변경할 수 있습니다. 이미지를 다시 그릴 때마다 원본 설정을 사용하려는 경우 save 메서드를 사용할 수 있습니다.

    saverestore 메서드는 스택에 캔버스 상태를 저장하고 검색하는 데 사용됩니다. 캔버스 상태는 적용된 모든 스타일과 변환으로 구성됩니다. save 메서드를 호출할 때마다 현재 캔버스 상태가 스택에 저장됩니다. restore 메서드는 스택에서 최근에 저장된 상태를 반환합니다.

    다음 예제에서는 일부 변환을 설정하기 전에 save 메서드를 사용하여 애니메이션 원을 그리고 이동합니다.

    // Save the canvas state.
    context.save();
    
  3. 이미지 그리기

    캔버스에 이미지를 그리는 동안 translate 및 rotate 메서드의 두 가지 변환을 사용하여 이미지를 변경할 수 있습니다.

    translate 메서드는 캔버스와 원점을 캔버스 그리드의 다른 지점으로 이동하는 데 사용됩니다.

    translate(x, y)
    

    이 메서드는 두 가지 인수를 사용합니다. x는 캔버스가 왼쪽 또는 오른쪽으로 이동하는 양이고 y는 위쪽 또는 아래쪽으로 이동하는 양입니다.

    캔버스를 원래 상태로 되돌리기 위해 역 변환을 수행하는 것보다 restore 메서드를 호출하는 것이 더 쉽기 때문에 변환을 하기 전에 캔버스 상태를 저장하는 것이 좋습니다. translate 메서드를 사용하면 수동으로 좌표를 조정하지 않고도 이미지를 캔버스의 아무 곳에나 배치할 수 있습니다.

    rotate 메서드는 현재 원점을 중심으로 캔버스를 회전하는 데 사용됩니다. 이 메서드는 캔버스를 회전하는 각도(라디안)인 하나의 매개 변수만 사용합니다.

    rotate(angle)
    

    회전은 시계 방향으로 이동하며 회전 중심점은 항상 캔버스 원점(왼쪽 위)입니다. 중심점을 이동하려면 translate 메서드를 사용하여 캔버스를 이동해야 합니다.

    다음 예제에서는 translaterotate 메서드를 교대로 몇 번 호출합니다. translate 메서드를 처음 호출할 때는 애니메이션이 캔버스 가운데에 배치됩니다.

    그런 다음 rotatetranslate 메서드 호출을 두 번 수행합니다. rotatetranslate 메서드를 처음 호출할 때는 캔버스 주위에 큰 루프를 이루며 그려지는 작은 원이 생성됩니다. 두 번째 호출할 때는 훨씬 작은 궤도로 그려지는 작은 원이 생성됩니다.

    캔버스 크기는 160픽셀 높이와 160픽셀 너비로 설정되므로 전체 애니메이션이 캔버스 가운데에 배치되도록 translate 메서드의 x 및 y 좌표가 80과 같도록 설정합니다.

    // centers the image on the canvas             
    context.translate(80, 80);
    

    date 개체로 rotate 메서드의 매개 변수를 계산하여 rotate 메서드를 처음 호출합니다. 이 매개 변수는 캔버스를 회전하는 각도입니다.

    var time = new Date();
    context.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
    

    getSeconds 계산에 사용된 값은 60이고 getMilliseconds 계산에 사용된 값은 60,000입니다.

    translate 메서드가 x 좌표를 이동하며, 이 경우 캔버스 주위를 큰 루프로 회전하는 원이 이동됩니다.

    // Translate determines the size of the circle's orbit.
    context.translate(50, 0);
    

    이것은 첫 번째 rotatetranslate 메서드의 효과입니다.

    루프가 없는 큰 원

    다음 두 개의 rotatetranslate 메서드 호출은 루프가 있는 더 작은 궤도의 원을 만듭니다.

    // Rotate causes the circle to move in a small orbit.
    context.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
    
    // Translate determines the size of the orbit.
    context.translate(0, 5);
    

    두 번째 rotate 호출의 각도를 계산할 때 getSeconds 계산에 사용된 값은 6이고 getMilliseconds 계산에 사용된 값은 6,000입니다.

    첫 번째 rotatetranslate 메서드를 주석 처리할 경우 두 번째 rotatetranslate 메서드가 그리는 모양은 다음과 같습니다.

    루프가 있는 원

    모든 위치 조정을 설정하면 캔버스에 원이 그려집니다.

    // This draws the repositioned circle
    context.beginPath();
    context.arc(5, 5, 4, 0, Math.PI*2, true); 
    context.stroke();
    
  4. 캔버스 상태 복원

    앞의 b 단계에서 캔버스 상태를 저장했으므로 이제 다음 프레임을 그리기 위해 캔버스 상태를 원래대로 설정합니다.

    // Restores the canvas to the previous state
    context.restore();
    

완성된 예제

애니메이션 효과를 준 그래픽

이 JavaScript 예제에서는 더 큰 원을 따라 나선형으로 움직이는 살아 있는 원을 그립니다.

window.onload = init;
  
// As an optimization, make "context" a global variable that is only set once.
var context;
  
function init(){
  context = document.getElementById('canvas').getContext('2d');    
  window.requestAnimationFrame(draw);
} // init

function draw() {
  // Save the canvas state.
  context.save();         
  
  // context.clearRect(0, 0, 160, 160);

  // centers the image on the canvas             
  context.translate(80, 80); 
  
  // Rotate moves the spiraling circle around the canvas in a large orbit.
  var time = new Date();
  context.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
  
  // Translate determines the location of the small circle.
  context.translate(50, 0);  
  
  // Rotate causes the circle to spiral as it circles around the canvas.
  context.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
  
  // determines the size of the loop
  context.translate(0, 5);  
  
  // This draws the circle
  context.beginPath();
  context.arc(5, 5, 4, 0, Math.PI*2, true); 
  context.stroke();
  
  // Restores the canvas to the previous state
  context.restore();
  window.requestAnimationFrame(draw);
}  // draw

이것은 캔버스 요소 주위에 검정색 경계를 만드는 CSS의 예입니다.

/* style the canvas element with a black border. */
canvas { border: 1px solid black; }

이 HTML 파일은 캔버스 요소를 만들고 외부 JavaScript 및 CSS 파일을 사용합니다.

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="myJavascript.js"></script>
        <link Rel="stylesheet" Href="myStyle.css" Type="text/css">
    </head>
    <body>
        <canvas id="canvas" width="160" height="160" />
    </body>
</html>

관련 항목

빠른 시작: 캔버스에 그리기