지난번 포스트에서 canvas를 제어하는 javascript는 <canvas>태그 이후 정의해야만 했었다.
오늘은 정의위치와 상관없이 짜는 방법을 찾아보겠다.

아울러 이 방법은 javascript를 통한 canvas 캡슐화의 한 방법이기도 하니 알아두면 좋을 것이다.

(javascript에서 함수는 객체, var는 private으로 취급된다는걸 염두하면 당연한 일이다)



우선 지난번 만들었던 index.html과 javascript이다.

Index.html

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title>Nagarry's HTML5</title>

<link type="text/css" rel="stylesheet" href="./css/Nagarry.css">

</head>

<body>

<canvas id="CANVAS_1" width="800" height="480">

Sorry, Your browser doesn't support HTML5 Canvas.

</canvas>

<script src="./script/Nagarry.js"></script>

</body>

</html>


Nagarry.js

var can1 = document.getElementById("CANVAS_1");

var context1 = can1.getContext("2d");

context1.fillStyle = "#ff0000";

context1.fillRect(50, 50, 360, 240);


canvas이후에 javascript가 위치한다.

javascript에서 canvas를 사용하므로, canvas가 정의된 이후에 javascript를 써야했던 것이다.


이걸 이렇게 고쳐보겠다.

우선 javascript 정의를 <canvas>훨씬 전인 <head>내부에 위치시켰고,

Index.html

<!DOCTYPE html>

<html lang="ko">

<head>

<meta charset="UTF-8">

<title>Nagarry's HTML5</title>

<link type="text/css" rel="stylesheet" href="./css/Nagarry.css">

<script src="./script/Nagarry.js"></script>

</head>

<body>

<canvas id="CANVAS_1" width="800" height="480">

Sorry, Your browser doesn't support HTML5 Canvas.

</canvas>

</body>

</html>



javascript도 이렇게 바꾸겠다.

Nagarry.js

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


function eventWindowLoaded()

{

var can1 = document.getElementById("CANVAS_1");

var context1 = can1.getContext("2d");

context1.fillStyle = "#ff0000";

context1.fillRect(50, 50, 360, 240);

}


index.html은 javascript정의 순서만 바뀌었는데,

javascript는 뭔가 바뀌었다.

바로 이녀석이 핵심이다.

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


여기서 window란 윈도xp나 윈도7같은 OS가 아니고, DOM(Document Object Model)객체의 최상위 객체다.

window가 최상위 객체다보니 사실은 window.document.getElementById("CANVAS_1");이라도 해도 무방하나,

window는 보통 생략하고, 위 소스와 같이 document.getElementById("CANVAS_1");라고만한다.

이것을 window.addEventListener("load", eventWindowLoaded, false);에 적용시켜보면,

addEventListener("load", eventWindowLoaded, false);이라고 작성해도 무방하다는 말이다.

실제로 브라우저들은 아무문제없이 이를 처리한다.




<window는 DOM최상위 객체- http://www.w3.org/TR/DOM-Level-3-Events/>



결국 DOM최상의 레벨인 만큼 window는 html페이지 전체를 의미하고,

결국 html페이지를 의미하는 window으로부터 addEventListener()라는 것을 호출했다.


addEventListener()는 이벤트큐에 함수를 추가하는 기능을 하고 3개의 인자를 가진다.

첫째인자는 이벤트인데, window의 이벤트는 이미 다 정의되어 있기에 여기선 html페이지가 모두 로딩되면

호출되는 "load"를 사용했다.

(참고 : http://www.w3.org/TR/DOM-Level-3-Events/)

두번째 인자는 함수명이다. 이벤트가 발생하면 호출되는 함수인데, 여기선 html페이지가 load되면 eventWindowLoaded()라는 함수를 호출하게 된다.

셋째 인자는 useCapture이다. DOM하위로 이벤트를 보낸건지 말건지 결정한다.

여기선 false이므로 더이상 하위로 보내지않는다.


셋째인자인 useCapture와 상관없이 프로그램을 짜려면

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

부분을 다르게 바꿀 수 있다. window.[on이벤트]라는 방식이다.


이렇게 말이다.

window.onload = function()

{

eventWindowLoaded();

}

이건 다시 한줄로 이렇게 표한할 수도 있다.

window.onload = eventWindowLoaded();


아지만 나는 .NET프로그램을 짜던 내 습관과 가장 유사한 이 방식이 가장 내 맘에 든다.

window.addEventListener("load", eventWindowLoaded, false);// 이게 잘 맘에 듬

(물론 형태에 따라 저장후 호출되는 함수이냐 즉시실행함수이냐 등의 차이는 있으나, 아직은 무시하자)


다시 말하면 결국 이 코드는...

Nagarry.js

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


function eventWindowLoaded()

{

var can1 = document.getElementById("CANVAS_1");

var context1 = can1.getContext("2d");

context1.fillStyle = "#ff0000";

context1.fillRect(50, 50, 360, 240);

}


html페이지가 모두 로딩되면,

eventWindowLoaded()라는 함수를 호출하게 되고,

그 함수안에서 canvas와 context를 사용하게 되는 것이다.


이렇게 canvas변수를 이벤트 함수안에 넣어 캡슐화하면, 혹시나 모를 다른 변수나 함수와의 충돌을 피할 수 있다.

Google AdSense

'끄적끄적 > HTML5' 카테고리의 다른 글

HTML5 Canvas 이미지 처리  (1) 2014.03.07
HTML5 Canvas 이미지/스프라이트  (2) 2014.03.06
HTML5 개발툴 끝판왕(?) - Liveweave  (2) 2014.03.02
[HTML5] Javascript로 canvas제어하기  (0) 2014.03.01
HTML5 시작하기  (0) 2014.03.01

+ Recent posts