HTML5/Image Rotation

HTML5 Image Rotation example

Soul-Learner 2012. 4. 20. 00:32

미사일 이미지를 회전하여 방향을 설정한 다음 발사하는 예

테스트 환경: HTML5, Eclipse, Google Chrome, Javascript

사용된 미사일 이미지

Vector2D.js

마우스를 미사일 이미지 아래로 이동하면 미사일의 방향을 설정할 수 있고 클릭하면 미사일이 발사된다.

HTML5 Canvas를 지원하지 않는 브라우저입니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>HTML5 이미지 회전</title>

<style type="text/css">
#MyCanvas {  }
</style>
<script type="text/javascript" src="Vector2D.js"></script>
<script type="text/javascript">

var ctx = null; 
var canvas = null;
var imgUrl = "https://t1.daumcdn.net/cfile/tistory/141E79414F8D8D4321";
var missileObj = null;
var directionVec = null;
var headPt = new Vector2D(0,0);
var tailPt = new Vector2D(0,0);
var directionRAD = 0;
var timer = 0;
var fired = false;

function Missile(ctx, x,y,speed,imgObj) { 

	this.ctx = ctx;
	this.x = x;
	this.y = y;
	this.speed = speed;
	this.imgObj = imgObj;
	this.heading = 0;

	Missile.prototype.setHeading = function(heading) {
		this.heading = heading;
	}
	Missile.prototype.update = function(){
		this.x += this.speed.x;
		this.y += this.speed.y;
	}
	Missile.prototype.draw = function() {
		ctx.save();
		ctx.translate(this.x,this.y);
		ctx.rotate(this.heading);
		ctx.translate(-this.x,-this.y);
		this.ctx.drawImage(this.imgObj,this.x-this.imgObj.width/2,this.y-this.imgObj.height/2);
		ctx.restore();
	}
}

window.onload=function() {
	canvas = document.getElementById("MyCanvas");
	ctx = canvas.getContext('2d');
	canvas.addEventListener("mousemove", onMouseMove);
	canvas.addEventListener("mousedown", onMouseDown);
	var img = new Image();
	img.onload=function(){
		missileObj = missileObj = new Missile(ctx,canvas.width/2, canvas.height/2, new Vector2D(0,0),img);
		missileObj.draw();
	}
	img.src = imgUrl;
}

function reset() {
    if(timer!=0) clearInterval(timer);
	missileObj.x = canvas.width/2;
	missileObj.y = canvas.height/2;
	clearCanvas();
	missileObj.setHeading(0);
    missileObj.speed.x = 0;
	missileObj.speed.y = 0;
	missileObj.draw();
	fired = false;
}

function onMouseMove(e) {
	var x = e.pageX-this.offsetLeft;
	var y = e.pageY-this.offsetTop;
	tailPt.x = x;
	tailPt.y = y;

	if(y>=missileObj.y) {
		clearCanvas();
		drawLine(x,y);
		findHeading();
		missileObj.setHeading(directionRAD+Math.PI);
		missileObj.draw();
	}
}

function onMouseDown(e){
	missileObj.speed.x = Math.cos(directionRAD)*5;
	missileObj.speed.y = Math.sin(directionRAD)*5;
	fired = true;
    if(timer!=0) clearInterval(timer);
	timer = setInterval("fire()", 10);
}

function fire() {
	clearCanvas();
	missileObj.update();
	missileObj.draw();
}

function drawLine(x,y) {
	if(fired) return; 
	ctx.beginPath();
	ctx.strokeStyle = "red";
	ctx.lineWidth = 2;
	ctx.moveTo(missileObj.x, missileObj.y);
	ctx.lineTo(x,y);
	ctx.stroke();
}

function clearCanvas() {
	ctx.clearRect(0,0,canvas.width,canvas.height);
}

function findHeading() { 
	// 클릭된 점과 수평선과의 내적을 계산한다. 추후에 내적을 이용한 cos값을 구할 때
	// 사용할 목적으로 산출한 값
	headPt.x = missileObj.x;
	headPt.y = missileObj.y;

	var directionVec = headPt.sub(tailPt);
	var dot = directionVec.x*1 + directionVec.y*0;

	var len = directionVec.length();
	var cosVal = dot/len;
	var rad = Math.acos(cosVal);

	if(directionVec.y<0) {//위쪽을 가리키고 있는 경우에는 각도를 보정해야 한다.
		rad = Math.PI - rad + Math.PI;
	}
	directionRAD = rad;
}

</script>
</head>
<body>
<canvas id="MyCanvas" width="400" height="300" style="border:1px dotted black;">
HTML5 Canvas를 지원하지 않는 브라우저입니다.
</canvas>
<br/>
<input type="button" value="재설정" onClick="clearInterval(timer); reset();"/>
</body>
</html>