컨텐츠 바로가기

HTML5 Canvas image rotate (HTML 이미지 회전)

http://Luia.egloos.com/2003287

HTML5 Canvas에서는 Context.rotate() 함수를 사용해서 이미지를 회전 시킬 수 있다.
그런데 조심해야 할 것이 있다!
그냥 Context.rotate()를 할 경우, 모든 이미지가 회전하는 불상사가 발생한다.

-----------------------------------------------------------------------------------------------

이미지 회전에 관련된 Context 함수는 5가지 정도가 있다.
-save() : 최근 Context를 저장한다.
-translate(x, y) : 이미지를 생성할 생성 좌표와 회전할 기준점을 설정한다.
-rotate(radian) : 회전 시킨다.
-drawImage(img, x, y) : 이미지를 x, y 좌표에 그려준다.
-restore() : 해당 텍스트를 반환한다.


여기서 집중해야 할 것은
translate가 이미지의 생성 좌표만 바꿔주는 것이 아니라 회전할 기준점까지 설정한다는 것을 고려해야한다.

rotate같은 경우에는 라디안을 사용하기 때문에 라디안을 각도로 변환시켜주는 RadToDeg 함수를 만들어서 사용하는 것이 편하다. 예를 들어서 아래와 같이 만들면 편하다.

function RadToDeg(angle){
return angle * Math.PI/180;
}

-----------------------------------------------------------------------------------------------

순서를 따져보면 대충 아래와 같이 된다.

1. save()
2. translate(x, y)
3. rotate(RadtoDeg(angle))
4. translate(-x, -y)
5. drawImage(img, x, y)
6. restore()

4번을 보면 translate를 한 번 더 쓴 것을 볼 수 있다.
이는 생성 기준 좌표를 (0, 0)으로 바꾸기 위한 작업이다.
translate 후 rotate를 하면 이미지가 이미 회전한 상태가 되기 때문에, 생성점과 기준점을 바꾸어 주어도 괜찮기 때문!

4번인 translate를 쓰지 않을 경우에는 아래와 drawImage의 좌표가 (-x, -y)이런 식으로 변환되야 한다.
편하게 계산 하기 위해서는 4번을 쓰는 것이 훨씬 좋다!

-----------------------------------------------------------------------------------------------
예제 코드이다.
편의상 만든 것이니 원하는 대로 바꿔서 사용할 수 있었음 좋겠다.

--HTML--
<body>
<canvas id="GameCanvas" width="800" height="600" style="position: absolute; top:25px; left:25px;">
</canvas>
</body>

--JavaScript--

var GAME_FPS =60;
var angle =0;

//이미지의 크기가 10x10일 경우
var img =new Image();
img.src ="images/GAME_weapon1.png";

window.addEventListener("load", framework, false);

function Render(){
var theCanvas =document.getElementById("GameCanvas");
var Context =theCanvas.getContext("2d");

Context.save();
Context.translate(5, 5); //이미지의 생성점과 회전 기준점을 설정
Context.rotate(RadToDag(angle)); //기준점을 기준으로 회전
Context.translate(-5, -5); //원점으로 생성점과 기준점을 바꾼다.
Context.drawImage(img, 0, 0); //기준점이 0,0이기 때문에 0,0으로 생성됨
Context.restore(); //컨텍스트 반환

angle++;

//이미지의 크기가 10x10이라고 할 때, 원점을 기준으로 이미지의 중앙은 (5, 5)이다.
//생성점과 기준점을 (5, 5)를 삼아놓고 이미지를 먼저 회전시킨다. 
//그리고 나서 생성점과 기준점을 되돌린다!
//이미 (5,5)를 기준으로 이미지가 회전 되었고, 
      //이미지가 (0,0)에서 출력 되었으니 중앙을 기준으로 회전된 것 처럼 보이게 된다.
}

function framework(){
setInterval (render, 1000/GAME_FPS);
}

function RadToDag(angle){
return angle * Math.PI/180;
}

덧글|신고