본문 바로가기
제가 쓴 책/HTML5, CSS3 and JavaScript

10. 변환(Transformation)

by edupicker(체르니) 2013. 8. 7.

10. 변환(Transformation)


여러분은 캔버스(canvas)에 간단한 직선부터 사각형, 곡선 등과 같이 다양한 형태의 그리기 작업을 사용해보았습니다. 이번에는 이러한 그리기 작업에 조금 변화를 줄 수 있는 방법에 대해서 소개할 것인데 바로 변환(Transformation)입니다. 제공하는 메서드를 정리하면 다음과 같으며 순서대로 알아봅니다.


context.scale(x, y)
context.translate(x, y)
context.rotate(angle)
context.transform(a, b, c, d, e, f)
context.setTransform(a, b, c, d, e, f)


10.1 scale(x, y) 메서드를 이용한 배율 조정

scale() 메서드는 입력 파라미터로 받는 x, y 값의 배율에 의해서 그 크기를 크게, 혹은 작게 변화시킬 수 있는 메서드로 x는 너비(width) , 가로 방향을 나타내고 y는 높이(height)인 세로 방향을 조절하는데 사용됩니다.

“basic.html” 파일을 메모장을 열어서 “// canvas에 그릴 선이나 도형 작성부분에 다음과 같이 3개의 직사각형을 그리는 코드를 작성합니다.

      // canvas
에 그릴 선이나 도형 작성
      context.fillStyle = "blue";
      context.fillRect(0,0,100,50);

      context.fillStyle = "red";
      context.scale(0.5,2);
      context.fillRect(50,100,100,50);         

위에서 scale() 메서드에 의해 x 방향에 대해서 0.5, y 방향에 대해서 2배를 하도록 코드를 작성하고 다음 라인에서 fillRect() 메서드를 이용하여 사각형을 그리고 fillStyle 속성에 설정된 대로 빨강색으로 채우도록 합니다.
다른 이름으로 저장을 선택하여 “ScaleEx.html”로 저장한 후 IE9로 열어보면 다음과 같이 나타나게 됩니다.



결과에서 보는 것처럼 원래는 점선으로 표시된 곳에 해당 크기의 빨강색으로 채워진 사각형을 표시해야하는데 scale() 메서드에 의해 뒤에 이어지는 fillRect() 메서드가 “fillRect(25,200, 50, 100)”과 같이 적용되어 처리됩니다.


10.2 translate(x, y) 메서드를 이용한 초점 이동


translate()
메서드는 canvas의 초점을 입력 파라미터인 x 값에 의해서 오른쪽으로 해당 x 값 만큼 이동하고 y 값에 의해 아래 방향으로 y값 만큼 이동하도록 하는 메서드입니다.
이제 예제를 해볼까요? “basic.html” 파일을 메모장을 열어서 <body> 태그 안의 canvas 요소 태그의 너비(width) 400, 높이(height) 300으로 크기를 변경한 후 “//canvas에 그릴 선이나 도형 작성부분에 다음과 같이 3개의 직사각형을 그리는 코드를 작성합니다.


      context.fillStyle = "blue";
      context.fillRect(0, 0, 100, 50); //--


      //
초점 이동 (200, 150)
      context.translate(context.canvas.width/2, context.canvas.height/2);  //--

      context.fillRect(0, 0, 100, 50); //--
   

위와 같이 작성한 후 다른 이름으로 저장을 선택하여 “translateEx.html”로 저장한 후 IE9로 열어보면 다음과 같이 나타나게 됩니다.




위의 결과에서 보는 것처럼 원래 canvas의 시작지점이 (0, 0) 이었던 것이 에서 translate() 메서드를 통해 (200, 150)을 이동된 후 에서 과 동일한 크기의 직사각형을 채우게 됩니다.



10.3 rotate(angle) 메서드를 이용한 회전

rotate()
메서드는 말 그대로 선, 도형 등을 회전시키는데 사용하는 메서드입니다. 입력 파라미터인 angle arc() 메서드에서 설명한 자바스크립트의 Math 객체(Object) PI 속성을 이용하여 그 각을 표시합니다.
예를 들어 45도를 회전시킬 경우 45도의 경우
 이고 이를 Math 객체의 PI를 이용하여 0.25*Math.PI” 형태로 나타낼 수 있습니다. 그래서 결과적으로 45도 회전을 rotate() 메서드를 이용하여 구현할 수 있게 됩니다.
방금 전 사용한 “translateEx.html” 파일을 메모장으로 연 후 “//canvas에 그릴 선이나 도형 작성다음의 코드를 “ } </script>” 전까지 주석(//) 처리한 후 다음과 같이 코드를 작성합니다.


      // canvas에 그릴 선이나 도형 작성
      //
초점 이동 (200, 150)
      context.translate(context.canvas.width/2, context.canvas.height/2);
      context.rotate(Math.PI / 4); //45
도 회전
      context.fillStyle = "blue";
      context.fillRect(0, 0, 50, 100);

위와 같이 작성한 후 다른 이름으로 저장을 선택하여 “rotateEx.html”로 저장한 후 IE9로 열어보면 다음과 같이 나타나게 됩니다.




10.4 transform(a, b, c, d, e, f), setTranform(a, b, c, d, e, f) 메서드

지금까지 본 scale, rotate, translate 같은 Transformation은 생각보다 사용하기가 쉬웠습니다. 이번에 소개하는 transform()이나 뒤에 이어지는 setTransform() 메서드는 조금 어려운 내용입니다. 하지만 여러분이 비스듬한 형태의 도형, 예를 들면 사다리꼴이나 텍스트 반사 같은 보다 그럴듯한 작업이 가능해집니다.
그래서 transform() 메서드는 다음과 같은 변환 행렬(Transformation matrix)을 사용합니다.



위에서 언급된 a, b, c, … 등은 transform() 메서드의 입력 파라미터와 동일하며 각각의 의미를 정리하면 다음과 같습니다.


입력 파라미터

의미

a

수평 방향, x축 방향의 scale

b

수평 방향의 기울기(skew)

c

수직 방향, 수직방향의 기울기(skew)

d

수직 방향, y축 방향의 scale

e

수평방향으로 이동

f

수직방향으로 이동


그리고 이와 같은 변환 행렬을 이용하여 변환이 이루어지는데 이를 수식화하면 다음과 같습니다.



이제 변환 행렬(Transformation matrix)을 이용하여서 앞서 설명한 translate나 평행 사변형 형태의 도형 그리고 반사(Mirror) 효과를 만들어볼까요?



translate 구현하기
만일 canvas의 특정 좌표에서 수평(x), 수직(y)으로 이동하고자 할 경우는 위의 e, f 입력 파라미터 값에 변화를 주면 되면 이에 상응하는 변환 행렬(Transformation matrix)으로 나타내면 다음과 같습니다.


이를 transform() 메서드로 나타내면 transform(1, 0, 0, 1, x, y) 형태로 나타낼 수 있습니다.

“basic.html” 파일을 메모장을 열어서 <body> 태그 안의 canvas 요소 태그의 너비(width) 400, 높이(height) 300으로 크기를 변경한 후 “//canvas에 그릴 선이나 도형 작성부분에 다음과 같이 코드를 작성합니다.


      context.fillStyle="black";
      context.fillRect(0, 0, 100, 50);
      context.transform(1,0,0,1,50,50);
      context.fillStyle="red";
      context.fillRect(0, 0, 100, 50);

위에서 보는 것처럼 transform() 메서드의 x, y축 이동 관련 입력 파라미터들인 e, f 에 각각 50 씩을 설정하여 기본 canvas 좌표인 (0, 0) (50, 50) 이동한 후 fillRect() 메서드를 적용합니다.
위와 같이 작성한 후 다른 이름으로 저장을 선택하여 “transform_translate.html”로 저장한 후 IE9로 열어보면 다음과 같이 나타나게 됩니다.




평행 사변형 형태 만들기
사다리꼴 형태를 만드는 것과 관련된 입력 파라미터는 b, c 입니다. 따라서 다음과 같은 변환 행렬 형태를 취합니다.



이를 transform() 메서드로 나타내면 transform(1, b, c, 1, 0, 0) 형태로 나타낼 수 있습니다.
“basic.html”
파일을 메모장을 열어서 <body> 태그 안의 canvas 요소 태그의 너비(width) 400, 높이(height) 300으로 크기를 변경한 후 “//canvas에 그릴 선이나 도형 작성부분에 다음과 같이 코드를 작성합니다.


      //초점 이동 (100, 100)
      context.translate(100, 100);
      context.transform(1,0,1,1,1,0,0);
      context.fillStyle="red";
      context.fillRect(0, 0, 100, 50);

다른 이름으로 저장을 선택하여 저장한 후 “transform_Skew.html”로 저장하고 IE9를 통해 확인하면 다음과 같이 평형 사변형 형태의 도형을 그립니다.


텍스트 반사(Reflection) 효과 만들기
이제 캔버스(canvas)내의 텍스트에 반사 효과를 주는 방법에 대해서 알아봅니다.




이를 transform() 메서드로 나타내면 transform(1, 0, 0, -1, 0, 0) 형태로 나타낼 수 있습니다.
“basic.html”
파일을 메모장을 열어서 <body> 태그 안의 canvas 요소 태그의 너비(width) 400, 높이(height) 300으로 크기를 변경한 후 “//canvas에 그릴 선이나 도형 작성부분에 다음과 같이 코드를 작성합니다.


      // canvas에 그릴 선이나 도형 작성   
      context.fillStyle="black";
      context.font="20pt Century Gothic";
      context.fillText("
자신의 아이디어를 프로그래밍하세요.", 0,100);
      context.transform(1,0,0,-1,0,0);
      context.fillStyle="red";
      context.fillText("
자신의 아이디어를 프로그래밍하세요.", 0,-100);

다른 이름으로 저장을 선택하여 저장한 후 “transform_reflection.html”로 저장하고 IE9를 통해 확인하면 다음과 같이 텍스트에 대해서 반사된 형태로 출력합니다.




마지막으로 setTransform() 메서드는 transform() 메서드의 기능을 수행하기 전에 변환 행렬을 다음과 같은 단위 행렬(identity matrix) 형태로 재설정하는 작업을 수행합니다.



변환 행렬에 의해 계산된 새로운 값인 ,   x, y와 같아진다는 의미이므로 원래의 상태로 설정하기 위해서는 setTransform() 메서드를 이용하면 되는데 다음과 같이 입력해주면 됩니다.

      context.setTransform(1,0,0,1,0,0);

이제 간단한 예제를 통해 setTransform() 메서드가 어떻게 사용되는지 알아봅니다. “basic.html” 파일을 메모장을 열어서 <body> 태그 안의 canvas 요소 태그의 너비(width) 400, 높이(height) 300으로 크기를 변경한 후 “//canvas에 그릴 선이나 도형 작성부분에 코드를 작성합니다.


      // canvas에 그릴 선이나 도형 작성   
      context.translate(canvas.width/2, canvas.height/2);
      context.fillStyle = "blue";
      context.fillRect(50, 50, canvas.width/4, canvas.height/3);
     
      context.setTransform(1, 0, 0, 1, 0, 0);
      context.fillStyle = "red";
      context.fillRect(0, 0, canvas.width/4, canvas.height/3);

다른 이름으로 저장을 선택하여 저장한 후 “setTransformEx.html”로 저장하고 IE9를 통해 확인하면 다음과 같이 setTransform() 메서드에 의해 원래의 좌표(0,0)으로 이동하여 빨강색의 정사각형을 그리게 됩니다.





- 본 저작물은 본인이 2011년 상반기부터 2012년 여름 즈음까지 도서 출판을 목적으로 약 470 페이지(A4, 폰트 10)으로 작성한 원본 중 Canvas에 대한 부분을 그대로를 공개하는 것으로 본 저작물에 대한 모든 권리는 본인(원철연)에서 있음을 알립니다.
개인적인 학습 목적으로 사용을 허용하며 온오프라인의 베포나 펌상업적인 용도의 사용은 삼가해주시기 바랍니다. 끝으로 학교나 비영리 단체에서의 경우 본 저작물을 비상업적인 용도로 활용하고자 할 경우 연락처를 비밀댓글로 남겨주시면 연락드리겠습니다.