본문으로 건너뛰기

도형 그리기와 애니메이션

1. 도형 그리기

캔버스 요소 (Canvas Element)

HTML5에서 그리기: HTML5는 웹 페이지에 직접 그림을 그릴 수 있는 요소인 <canvas>를 제공하여 플러그인 없이 자바스크립트와 함께 상당히 정교한 그림을 그릴 수 있습니다.

캔버스 생성: <canvas> 태그를 사용하여 생성되며, HTML 페이지 내에서 사각형 형태의 영역으로 존재합니다. 기본적으로 경계를 가지지 않으며, 단순히 그래픽을 위한 컨테이너입니다.

캔버스 좌표계: 픽셀이 들어 있는 2차원 그리드(격자)로, 좌측 상단의 좌표는 (0, 0)이며, 우측 하단 좌표는 캔버스의 크기에 따라 결정됩니다.

컨텍스트 객체: 캔버스에 그림을 그리는 데 사용되는 자바스크립트 객체로, 캔버스 도화지에 해당하며 물감과 붓에 해당하는 기능을 제공합니다. canvas.getContext("2d")를 통해 2D 렌더링 컨텍스트를 얻을 수 있습니다.

자바스크립트의 위치: 캔버스에 그림을 그리는 자바스크립트 코드는 <body> 요소의 맨 끝에 두어야 하며, 문서 로드가 끝난 후 실행되도록 권장됩니다.

기본 도형 그리기

직선 그리기: moveTo(x,y)로 시작점을 정의하고, lineTo(x,y)로 끝점을 정의한 후, stroke()를 호출하여 선을 그립니다.

사각형 그리기: rect(x,y,w,h)를 사용하여 좌상단 모서리 좌표와 가로/세로 길이를 지정합니다. stroke()는 채우지 않은 사각형을, fill()은 채워진 사각형을 그립니다.

원 그리기: arc(x,y, radius, startAngle, endAngle, antiClockwise)를 사용하여 중심점, 반지름, 시작 및 종료 각도, 방향(반시계 방향 여부)을 지정하여 그립니다.

곡선 그리기: 3차 곡선인 베지어 곡선은 4개의 제어점 안에서 그려집니다.

일반적인 도형 그리기: beginPath()로 시작하고, closePath()로 종료하며, moveTo(), lineTo(), bezierCurveTo(), arc() 등을 호출하여 경로를 생성한 후 stroke() 또는 fill()로 그립니다.

텍스트 그리기: font 속성으로 폰트를 설정하고, fillText(text,x,y)로 채워진 텍스트를, strokeText(text,x,y)로 외곽선만 있는 텍스트를 그립니다.

도형의 속성

선 그리기 속성:

  • context.lineWidth: 선 두께
  • context.strokeStyle: 선 색상
  • context.lineCap: 선 끝점 모양

도형 채우기:

  1. 단일 색상으로 채우기: context.fillStyle 속성을 이용하여 색상을 지정합니다.

  2. 그라디언트로 채우기:

    • createLinearGradient() (선형) 또는 createRadialGradient() (원형)를 생성
    • addColorStop()를 이용하여 2개 이상의 종료 색상을 추가
  3. 패턴으로 채우기:

    • Image 객체를 생성하고 createPattern(image, "repeat")으로 패턴 객체를 생성
    • context.fillStyle로 설정하고 fill() 메서드를 호출하여 도형 내부를 채움
    • repeat 옵션: "repeat", "repeat-x", "repeat-y", "no-repeat"

이미지 그리기: drawImage(image,x,y)를 사용하여 특정 위치에 이미지를 그릴 수 있으며, image 객체의 onload 속성을 이용하는 것이 일반적입니다.

2. 도형의 변환과 애니메이션

도형의 변환

평행 이동 (Translation): translate(tx, ty) 메서드는 캔버스 좌표 공간의 원점을 평행 이동시킵니다. 내부적으로는 행렬을 사용하여 좌표를 변환합니다.

회전 (Rotation): rotate(angle) 메서드는 (x,y)를 기준으로 좌표 공간을 회전시킵니다. 각도는 라디안 단위로 지정합니다.

신축 (Scale): scale(sx, sy) 메서드는 가로(sx)와 세로(sy) 방향으로 도형을 신축합니다. scale(0.5, 0.5)는 크기를 절반으로 줄입니다.

일반 변환: transform(a, b, c, d, e, f) 메서드는 변환 행렬의 값을 직접 지정하여 x' = ax + cy + ey' = bx + dy + f와 같은 일반적인 변환을 수행할 수 있습니다.

애니메이션

적용 방법: CSS3를 이용한 애니메이션과 캔버스 및 자바스크립트를 이용한 애니메이션 두 가지 방법이 있습니다.

작성 순서: 애니메이션은 일반적으로 다음의 절차를 반복하여 구현됩니다:

  1. 캔버스를 지움 (clearRect())
  2. 위치를 업데이트함 (예: x += dx; y += dy;)
  3. (업데이트된) 위치에 그림을 그림

Bouncing Ball 예제

// 캔버스 지우기
clearRect(0, 0, 300, 200);

// 공 그리기
beginPath();
fillStyle = "red";
arc(x, y, 10, 0, 2 * Math.PI);
fill();

// 위치 업데이트
x += dx;
y += dy;

// 경계 체크
if (x <= 0 || x >= 300) dx = -dx;
if (y <= 0 || y >= 200) dy = -dy;

// 애니메이션 반복
setInterval(draw, 10);

공던지기 예제 (물리 엔진 적용)

캔버스 요소 생성: lawn.pngnet.png 이미지를 활용하여 배경을 만듭니다.

공의 움직임: 물리 엔진을 사용하지 않고 직접 계산합니다.

  • ballVx는 초기 속도에서 변하지 않음
  • ballVy는 중력 가속도(1.98)만큼 점점 느려짐
  • ballX = ballX + ballVx;ballY = ballY + ballVy;로 공의 현재 위치를 업데이트

타이머 설정: timer = setInterval(calculate, 100);를 사용하여 주기적으로 calculate() 함수를 호출합니다.

충돌 감지:

  • 공이 목표물(450 <= ballX <= 480, 60 <= ballY <= 210)에 맞으면 점수를 증가시키고 clearInterval(timer)로 애니메이션을 중단
  • 공이 캔버스 경계를 벗어나도 애니메이션을 중단

초기 속도 계산: 공의 초기 속도(ballVx, ballVy)는 사용자가 입력한 속도와 각도에 따라 삼각함수(Math.cos, Math.sin)를 사용하여 계산됩니다. 각도는 라디안으로 변환됩니다 (angle * Math.PI/180).