반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

앱 화면 Screen Capture하기

2011. 12. 29. 04:26 | Posted by 솔웅


반응형
오랜만에 Corona SDK Tip을 공부합니다.

예전 텍스트, 이미지, 모양 표시하기... 2 에서 이런게 있다는 설명만 하고 넘어갔는데요.
오늘 예제와 함께 자세히 다뤄 볼께요.

display.setStatusBar( display.HiddenStatusBar )
 
-- Fill the screen with a green rectangle
local rect = display.newRect(0, 0, display.contentWidth, display.contentHeight)
rect:setFillColor(0, 255, 0)
 
-- Draw a circle on the screen
local circle = display.newCircle(155, 100, 36)
circle:setFillColor(255, 0, 0)
 
-- Capture the screen
local screenCap = display.captureScreen( true )
 
-- Remove the objects from the screen
rect:removeSelf()
circle:removeSelf()
 
-- Scale the screen capture, now on the screen, to half it's size
screenCap:scale(.5,.5)
 
-- Alert the user to look in the library (device)
-- or on the desktop (simulator) for the screen capture
local alert = native.showAlert( "Success", "Screen Capture Saved to Library", { "OK" } )
이 앱을 실행하면 위 화면이 실행되고 아래 화면이 캡쳐 됩니다.

왜 그런지 소스를 보실까요?
첫째줄은 아이폰에서 status 바를 없앱니다.
그 다음엔 커다란 녹색 사각형을 그리고 그 다음에 빨간 원을 그립니다.
녹색 사각형은 화면에 꽉 차게 그려집니다.
그 다음 display.captureScreen(true)를 해서 스크린을 캡쳐합니다.
(true)를 했으니까 이 파일은 디바이스 안에 이미지 파일로 저장됩니다.
그리고 사각형과 원을 screen에서 없앱니다.
그리고 아까 캡쳐한 것을 반 크기로 줄여서 화면에 표시합니다.
맨 마지막엔 제대로 스크린 캡쳐가 됐다는 Alert 메세지를 뿌립니다.

즉 이 앱은 꽉찬 녹색 사각형과 큰 원을 캡쳐한 후 두 사각형과 원을 지우고 절반크기로 다시 화면에 보여주는 앱입니다.

여기서 사각형과 원을 removeSelf()한 부분을 주석처리한 다음에 실행해 보세요.

그럼 이렇게 나올 겁니다.
보시다시피 캡쳐 전 도형들이 사라지지 않고 나와서 전체가 녹색 사각형이고 빨간 원도 좀 큽니다. 그리고 그 위에 캡쳐한 이미지를 절반크기로 올려 놓은 화면입니다.

간단하지만 때에 따라서는 아주 유용하겠죠?
display.captureScreen( false ) 하면 디바이스에는 저장되지 않습니다.
이것을 true로 할 경우
아이폰 같은 경우는 Photo Albums에 자동으로 저장이 되구요.
안드로이드는 build.settings에 아래와 같이 퍼미션을 주어야 합니다.
settings =
{
   androidPermissions =
   {
       "android.permission.WRITE_EXTERNAL_STORAGE"
   },
}
그리고 시뮬레이터는 컴퓨터 바탕화면에 캡쳐된 화면을 저장합니다.
(윈도우에서는 MyPictures\Corona Simulator" 디렉토리에 저장이 될 겁니다.)
저장된 파일은 png형식이고 이름은 Picture#.png이렇게 나갑니다.
10000개까지 가능합니다.


이 화면처럼 버튼을 누르면 화면을 캡쳐하도록 만들어 볼까요?
display.setStatusBar(display.HiddenStatusBar)
local background = display.newImage('background.png')
local captureButton = display.newImage('captureButton.png')

captureButton:setReferencePoint(display.CenterReferencePoint)
captureButton.x = display.contentWidth * 0.5
captureButton.y = display.contentHeight * 0.5

function captureButton:tap(e)
    local screenshot = display.captureScreen(true)
    -- Show Image in Photo Library
    media.show(media.PhotoLibrary)
end
captureButton:addEventListener("tap", captureButton)

이 소스처럼 button이미지에 리스너를 달아서 tap할 경우 display.captureScreen(true)를 하도록 하면 됩니다.
간단하죠?

샘플 파일은 아래에 있습니다.





반응형

코로나 관련 신간 소개

2011. 12. 28. 00:02 | Posted by 솔웅


반응형
요즘 들어 코로나 관련 책들이 하나 둘 나오기 시작하는 것 같습니다.

얼마전에 일본에서 책이 나왔다는 소식도 들었는데요.
지난주에 미국에서도 책이 나왔습니다.

오프라인 서점에 나왔는지 모르겠습니다.
저는 이 책의 첫장 Hello World 만 있는 PDF를 받았거든요.

아래에 공유해 드릴께요.


******** o ******* o ******* o ******* o ******* o ******* o *******

그리고 출판업계 관련 있으신분들 관심 가져 주셨으면 좋겠습니다.
제가 Corona SDK 관련 책을 내려고 준비 중에 있습니다.
CoronaSDK 의 CEO한테도 메일 했고 관심 있다는 답장도 받았습니다.

기존 책을 번역하는 것으로 할지 아니면 별도로 만들지는 지금 고민중인데요.

아직 책을 내 본 경험이 없어서 출판사 쪽에서 관심 있으시면 같이 일 진행 하면 좋겠습니다.

Corona SDK 는 쉽게 모바일 게임을 만들 수 있는 툴로 최근 급 성장하고 있는 개발 Language입니다.

혹시 이 글 보시는 분 들 중에 도움 주실 수 있으신 분들 연락 부탁드립니다.
(댓글로 써 주셔도 되구요. solkit2011@yahoo.com 으로 이메일 주셔도 되요.)

그럼........
반응형

HTML5 Web Storage -01-

2011. 12. 27. 04:44 | Posted by 솔웅


반응형
HTML5 에서 데이터를 저장했다가 사용하도록 하는 방법이 여러가지가 있습니다.
외부 서버에 접속해서 DB에 있는 데이터를 가져와서 처리하는게 아니라 그냥 Client side에서 데이터를 관리할 수 있도록 제공하는 기능을 말합니다.
이전에는 (정확히는 지금까지 지만..) 쿠키와 세션을 많이 사용했습니다.
이 방법은 client 쪽에 쿠키라는 작은 정보를 넣고 이 쿠키에 접근해서 그 정보를 사용하는 겁니다. 이 경우 쿠키에 접근할 때마다 서버와의 communication이 일어나는데요 Web Storage는 그런 서버와의 커뮤니케이션이 일어나지 않아서 서버의 부담을 줄일 수 있습니다.
Web Storage는 Key와 Value 의 구조로 돼 있습니다.
이 Web Storage는 싸이트 단위로 관리되는 Local Storage와 Browsing Context로 관리되는 Session Storage가 있습니다. 둘 다 똑 같은데요. 그냥 세션 스토리지는 기간의 제한이 있다는 것만 다릅니다.
local Storage는 한 싸이트에 대해 다른 창(탭)을 띄워도 정보가 계속 유지 되는 거구요. Session Storage는 한 창에서만 정보가 유지 되는 겁니다.

뭐 골치아픈 이론은 넘어가고 곧바로 페이지 만드는 것 부터 할께요.

오늘 만들 화면은 왼쪽에 Key 입력하는 textbox와 value 입력하는 text area 그리고 정보를 저장하기 위한 save 버튼을 만들겠습니다.
그리고 오른쪽에는 save 버튼을 누르면 key 와 value 가 표시 되도록 할 거구요.

일단 HTML 로 기본 틀을 잡아 보죠.
 <!doctype html>
<html lang="en">
<head>
    <title> Dougy's HTML5 Web Storage API</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href="webstoragedoug01.css">
    <script src="webstoragedoug02.js"></script>
</head>
<body>
    <section id="leftbox">
    <form>
        <p>(key) One: <input type="text" id="one"></p>
        <p>(value) Two <textarea id="two"></textarea></p>
        <p><input type="button" id="button" value="Save"</p>
    </form>   
    </section>
    <section id="rightbox">
        Nothing Yet Now!
    </section>
</body>
</html>

<input type="text"> 태그와 <textarea> 태그는 기본 html 문법입니다. 따로 설명은 안 할께요. 혹시 이거 모르시는 분은 html 공부부터 시작하시는게 좋을 겁니다.
leftbox,rightbox 라는 id를 갖는 두개의 section을 만들었습니다.
leftbox에는 input, textarea,button 태그들이 있구요. rightbox에는 그냥 글자만 있습니다.

여기까지 하면 이런 화면이 나옵니다.
이제 webstoragedoug01.css 를 작성해서 화면을 꾸며 보겠습니다.
#leftbox{
    float:left;
    padding:20px;
    border:3px solid red;
}
#rightbox{
    float:left;
    width:250px;
    margin-left:20px;
    padding:20px;
    border:3px solid blue;
}
float를 주어서 왼쪽에서 오른쪽으로 section 을 배치하도록 했습니다.

이제 왼쪽 오른쪽 box들이 제대로 표시되고 있습니다.
그럼 이제 동적인 효과를 위해서 JavaScript를 작성하겠습니다.
function doFirst(){
    var button = document.getElementById("button");
    button.addEventListener("click",saveData,false);
}
function saveData(){
    var one = document.getElementById("one").value;
    var two = document.getElementById("two").value;
    sessionStorage.setItem(one,two);
    display(one);
}
function display(one){
    var rightbox = document.getElementById("rightbox");
    var two = sessionStorage.getItem(one);
    rightbox.innerHTML = "Name : " + one + "<br/> Value : " + two;
}
window.addEventListener("load",doFirst,false);
분석해 볼까요?
1. 우선 맨 밑에 리스너부터 실행이 될 겁니다.
페이지가 load 될 때 doFirst 함수가 Call 됩니다.
2. doFirst() 함수에는 button이라는 지역변소에 html 내의 id가 button인 요소를 대입합니다.
그리고 이 버튼에 리스너를 다는데요. click 이벤트가 발생하면 saveData()함수를 실행합니다. 그러니까 화면에서 save버튼을 누르면 saveData()가 call 되서 실행 될 겁니다.
3. saveData()에는 one,two 두 지역 변수를 만들어서 각각 html 내에 id가 one,two 인 애들의 value 를 이 변수에 집어 넣습니다. 둘 다 input box와 textarea 안에 있는 글자들(values)이 대입 될 겁니다.
그 다음에 바로 오늘 배울 세션 스토리지가 나오네요.
4. sessionStorage.setItem(one,two)의 의미는 one을 key값으로 하고 two를 value 값으로 하는 세션스토리지를 만든다는 의미입니다. one이 key 값이라고 하는 것은 값이 중복되지 않는다는 말입니다. unique 한 key인거죠.
이러면 간단하게 세션스토리지에 원하는 값들을 저장하는 겁니다.
그리고 나서 display함수를 call 하는데요. parameter 로 one 즉 key 값을 던져 줍니다.
5. display() 함수에서는 one을 인자로 받아서 사용할 겁니다.
우선 rightbox라는 지역변수를 만들어서 거기에 html에서 id가 rightbox인 요소를 대입합니다.
6. 다음이 오늘 배우는 세션스토리지 관련한 내용인데요.
saveData()함수에서 set 한 세션스토리지를 불러와서 사용하는 방법입니다.
sessionStorage.getItem(one); 하면 key값이 one인 value를 불러오는 겁니다. 이 값을 two 에 대입합니다.
그리고 나서 HTML 코드를 만들어서 Name에 one을 Value에 two 를 표시하도록 합니다.


이러면 왼쪽에 글을 입력하고 save를 누르면 오른쪽에 그 내용이 표시 됩니다.
그런데 세션스토리지는 해당 정보를 브라우저에 저장해 둔다고 했습니다.
제가 animal2, Cat 치기 전에 animal1, Dog를 쳤었거든요.
근데 그 정보를 볼 수가 없네요.

이 코드는 세션스토리지를 충분히 잘 활용하기 위한 코드는 못 됩니다. 제대로 활용하기 위해서 자바스크립트를 많이 바꾸겠습니다.
function doFirst(){
    var button = document.getElementById("button");
    button.addEventListener("click",saveData,false);
    display();
}
function saveData(){
    var one = document.getElementById("one").value;
    var two = document.getElementById("two").value;
    sessionStorage.setItem(one,two);
    display();
    document.getElementById('one').value="";
    document.getElementById('two').value="";
}
function display(){
    var rightbox = document.getElementById("rightbox");
    rightbox.innerHTML = "";
    for(var x=0; x<sessionStorage.length;x++){
        var a = sessionStorage.key(x);
        var b = sessionStorage.getItem(a);
        rightbox.innerHTML += a+" - "+b+"<br/>";
    }
}
window.addEventListener("load",doFirst,false);

display()함수가 많이 바뀌었죠?
먼저 보면 일단 one이라는 인수를 받지 않습니다.
rightbox는 이전이랑 똑 같구요. 다음줄에서 rightbox를 빈 공간으로 만들어 버립니다.
그 다음에 session Storage에 저장 되 있는 내용들을 표시할 건데요.
for문을 sessionStorage에 저장돼 있는 갯수만큼 돌립니다.
sessionStorage.length가 세션스토리지에 저장된 데이터의 수 입니다.
a에 key값을 넣고 b에 이 키값에 대한 value 값을 집어 넣은 다음 HTML 코드를 넣어 표시합니다.
이러면 해당 창에서 이전에 넣었던 데이터들도 모두 표시 될 겁니다.
심지어는 Naver 나 Google로 가서 다른 싸이트 막 써핑하다가 다시 돌아와도 계속 그 값을 남아있을 겁니다.
이렇게 다른 싸이트 나갔다가 돌아오는 경우를 대비해서 doFirst()함수 마지막에 display(); 함수 Call 하는 부분을 추가합니다.
그리고 Html에서 값을 넣고 save버튼을 누르면 그 값이 오른쪽에 표시되고 input box나 Text Area는 새로운 값을 입력 받기 위해 빈칸으로 만들어 주면 좋겠죠?
그래서 saveData() 함수에 display();  하고 난 후 one,two 의 value 를 빈칸으로 합니다.


자 이제 세션 스토리지에 나와 있는 내용들이 다 나옵니다.
제가 우리나라 역대 10명의 대통령과 그 말로를 Key, Value로 짝 지었습니다.
이제 naver나 내 블로그나 다른 싸이트를 돌아 다니다가 와도 저 정보는 그대로 있을 겁니다.
하지만 다른 탭을 열거나 다른 브라우저를 띄워서 접속하면 이 정보는 남아있지 않습니다. 이게 바로 세션스토리지 입니다.
만약에 이 데이터들을 로컬 스토리지로 set 하고 사용했다면 새로운 탭으로 열어도 이 정보는 계속 남아 있을 겁니다.
세션스토리지에서 특정 데이터를 지울 수도 있습니다.
그럴 경우는 sessionStorage.removeItem("name");을 하시면 됩니다.
그리고 모든 데이터를 지우려면 sessionStorage.clear(); 하시면 되구요.

재미삼아 우리나라 역대 대통령을 가지고 예를 들었는데요.
총 10명의 역대 대통령이 있군요 우리나라에.(현 대통령까지 포함해서)
외국으로 도망간 대통령에 쿠테타로 쫒겨난 두명의 대통령, 총 맞아 죽은 대통령, 퇴임 후 대통령에서 졸지에 반란 수괴로 법원 판결을 받은 두명의 대통령, 퇴임후 살아있는 대통령, 퇴임후 노환으로 별세한 대통령, 그리고 퇴임 후 자살한 대통령까지...
내용들은 별로 재미있지 않네요. 현 대통령께선 퇴임 후 어떻게 될까요?

제가 컴퓨터 프로그래밍 일을 한지 10년이 넘었는데요. 전공이 정치학이었거든요. 좀 정치에 관심이 많아요.
프로그래머는 열심히 프로그래밍 하고, 학생은 열심히 공부하고, 근로자는 열심히 일 하고 국민은 열심히 정치해야 합니다. :)

그럼 다음 글에서 뵐께요.

P.S. 제가 역대 대통령을 1대부터 현재까지 쭉 순서대로 입력을 했는데 출력 되는건 순서가 막 뒤죽 박죽 되서 나오네요.
이게 순서대로 입력되고 순서대로 출력되지 않나봐요. 세션스토리지가요. 버그인가?
세션스토리지 정보를 좀 더 찾아봐도 정렬과 관련한 API는 없는 것 같구요.
혹시 세션스토리지 내 데이터 정렬에 대해 아시는 분 계시면 조언 부탁드립니다.
반응형

HTML5 드래그 앤 드롭 하기 Drag and Drop

2011. 12. 26. 03:23 | Posted by 솔웅


반응형
PC에서는 화면에 폴더 두개를 띄워 놓고 파일을 옮기면 파일이 복사되거나 옮겨 집니다.
브라우저에서는 이와 비슷하게 이미지나 텍스트 같은 객체 object 들을 드래그해서 다른 지점으로 옮기도록 할 수 있습니다. HTML을 이용해서 말이죠.

오늘은 이 브라우저 상에서 객체를 드래그 앤 드롭 하는 방법에 대해 알아보겠습니다.

브라우저에 왼쪽에 드롭하라고 알려주는 박스 하나 그리고 오른쪽에는 이미지가 있는 박스 하나를 만들겠습니다.
그래서 이 이미지를 왼쪽에 드래그 앤 드롭 하면 옮겨져서 왼쪽 박스에 display 되게 만들겠습니다.

이렇게 만들기 위해서는 일단 HTML로 2개의 박스 틀을 만들고 CSS로 왼쪽 오른쪽 정렬 및 다른 꾸며주는 효과를 주어야 할 것 같네요.
그리고 Drag and Drop 효과는 자바스크립트로 주어야 합니다.

그럼 HTML부터 작성해 볼까요?

 <!doctype html>
<html lang="en">
<head>
    <title> Dougy's HTML5 HTML5 Drag N Drop</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href="dragdoug01.css">
    <script src="dragdoug02.js"></script>
</head>
<body>
    <section id="leftbox">
        Drag an image in me!
    </section>
    <section id="rightbox">
        <img id="deco" src="drag.jpg" width="200">
    </section>
</body>
</html>
자 이렇게 두개의 나란한 박스로 사용될 두개의 section을 만들었습니다.
이 section 들을 박스로 만들고 왼쪽 오른쪽 배치하고 색을 입히고 하는 것들은 dragdoug01.css에서 할겁니다.
일단 html만 완료된 상태로 브라우저에 출력하면 아래와 같습니다.

그림이 우아하죠? 크리스마스 이브때 맨하튼 5번가에 갔었어요. 거기에 매년 연말이 되면 가게들 window decoration이 아주 멋진데요. 이 사진은 Berg Dorf goodman store의 Decoration 입니다.

일단 HTML은 완료 됐구요. 다음 CSS를 만들겠습니다.
#leftbox{
    float:left;
    width:250px;
    height:300px;
    margin:5px;
    border:3px solid blue;
}

#rightbox{
    float:left;
    width:250px;
    height:300px;
    margin:5px;
    border:3px solid red;
}
 id가 leftbox인 section 먼저 작업하면 float:left로 했으니까 이 section 이 왼쪽에 위치하게 되고 그 다음 오는 요소는 오른쪽에 배치될 겁니다. 그리고 너비,높이, 마진, 보더 등을 정하구요. rightbox도 마찬가지로 했습니다.

자 이제 원하는 모양대로 왼쪽, 오른쪽 박스가 만들어졌고 왼쪽에는 글자가 오른쪽에는 이미지가 있습니다.
지금 오른쪽에 있는 이미지를 왼쪽으로 드래그 앤 드롭 해 보세요.
제 브라우저에서는 드래그 할 때 이미지가 따라 오지만 마우스 표시가 금지표시(Ø)처럼 나오네요. 여러분은 좀 다르게 나올 수 있습니다. 이건 브라우저에서 기본적으로 설정된 기능입니다.
이제 우리는 이 브라우저에서 기본적으로 설정된 기능을 실행하지 않고 우리가 직접 만든 기능이 실행 되도록 프로그래밍을 할 겁니다.

이제 자바스크립트 코드를 아래와 같이 만드세요.
 function doFirst(){
    mypic = document.getElementById('deco');
    mypic.addEventListener("dragstart",startDrag,false);
    leftbox = document.getElementById('leftbox');
    leftbox.addEventListener("dragenter",function(e){e.preventDefault();},false);
    leftbox.addEventListener("dragover",function(e){e.preventDefault();},false);
    leftbox.addEventListener("drop",dropped,false);
 }
 function startDrag(e){
    var code = '<img id="deco" src="drag.jpg" width="200">';
    e.dataTransfer.setData('Text',code);
 }
 function dropped(e){
    e.preventDefault();
    leftbox.innerHTML = e.dataTransfer.getData('Text');
 }
 window.addEventListener("load",doFirst,false);
맨 마지막에 있는 이벤트리스너는 브라우저에 해당 페이지가 처음 로드될때 doFirst함수를 실행하라는 말입니다.
그럼 doFirst를 분석해 볼까요?
mypic이라는 변수에 id가 deco라는 객체를 담습니다. html 파일을 보시면 아시겠지만 이건 이미지입니다. 이 mypic에 리스너를 다는데 이벤트는 dragstart입니다.
그러니까 mypic을 드래그 시작할 때 startDrag함수를 실행하라는 겁니다.
다음 leftbox 변수에 id가 leftbox인 요소를 대입합니다.
이 leftbox에는 dragenter와 dragover 이벤트에 브라우저에서 기본적으로 제공되는 기능을 막습니다.
e.preventDefault(); 이것인데요.
이 리스너에서는 함수를 호출하는 것이므로 따로 함수로 만들어서 그 함수를 호출해도 되구요. 위에서처럼 아예 함수를 그 안에 집어 넣어도 됩니다.
다은엔 leftbox의 drop 이벤트에 dropped 함수를 호출하는 리스너를 넣습니다.

이제 이미지를 드래그 할 때 호출되는 startDrag를 볼까요?
code라는 지역변수에 html에서 만들었던 img 태그를 모두 넣습니다.
그리고 이 code Text라는 Key 값으로 setting 합니다.
 setData메소드는요.
setData(type, data)

- key/value 쌍으로 MIME 타입과 데이터 저장(여러 세트 저장 가능)

- Draggabledragstart 이벤트에서 Draggable의 정보를 저장하기 위해 사용

- 브라우저의 기본 드래그 요소나 외부 애플리케이션의 드래그 요소는 자동으로 여러 세트의 MIME 타입이 지정됨

getData(type)

- 지정한 MIME 타입의 데이터 반환

- droppabledrop 이벤트에서 draggable의 정보를 꺼내기 위해 사용

이렇습니다.
그리고 leftbox에 이미지가 drop 됐을 때 호출 되는 dropped 함수를 보겠습니다.
브라우저에서 제공되는 drop 이벤트에 대한 기본 기능을 먼저 막았구요.
그리고 leftbox에 geData로 아까 setData로 저장했던 html 코드를 넣습니다.
그러면 leftbox에 이미지를 불러오는 html 코드가 붙여지게 됩니다.


이제 브라우저에서 User 가 이미지를 지정된 곳으로 이동 시킬 수 있게 됐습니다.

여기에 좀 더 세세하게 각 이벤트에 리스너를 달아서 여러 동작들을 주면 좀 더 세련되게 꾸밀 수 있을겁니다.
예를 들어 leftbox에 drop하면 이미지가 이동하니까 leftbox에 마우스가 들어오면 이제 drop하면 이미지가 복사될 거라는 것을 알 수 있도록 leftbox의 색을 바꾼다던지. 진짜 파일이 이동하도록 leftbox에 drop 되면 오른쪽 box의 이미지를 지워버린다든지 하는거요.
아래 예제 코드를 넣습니다.
 function doFirst(){
    mypic = document.getElementById('deco');
    mypic.addEventListener("dragstart",startDrag,false);
    mypic.addEventListener("dragend",endDrag,false);
    leftbox = document.getElementById('leftbox');
    leftbox.addEventListener("dragenter",dragenter,false);
    leftbox.addEventListener("dragleave",dragleave,false);
    leftbox.addEventListener("dragover",function(e){e.preventDefault();},false);
    leftbox.addEventListener("drop",dropped,false);
 }
 function startDrag(e){
    var code = '<img id="deco" src="drag.jpg" width="200">';
    e.dataTransfer.setData('Text',code);
 }
 function dropped(e){
    e.preventDefault();
    leftbox.innerHTML = e.dataTransfer.getData('Text');
 }
  function endDrag(e){
    pic = e.target;
    pic.style.visibility='hidden';
 }
 function dragenter(e){
    e.preventDefault();
    leftbox.style.background="SkyBlue";
    leftbox.style.border="3px solid red";
 }
  function dragleave(e){
    e.preventDefault();
    leftbox.style.background="White";
    leftbox.style.border="3px solid blue";
 }

 window.addEventListener("load",doFirst,false);
 
자바스크립트의 여러 drag 이벤트를 사용해서 단계별로 기능들을 제공했습니다.
이벤트들은 dragstart,dragend,dragenter,dragleave,dragover,drop 등입니다.
mypic에는 dragstart 이벤트에는 html 이미지 태그를 setData로 저장을 해두고,
dragend 이벤트에서는 이미지를 안 보이도록 합니다.
그러면 이미지가 leftbox로 옮겨지만 rightbox 안의 이미지는 없어지게 됩니다.

leftbox에는 dragenter 이벤트에 배경색과 border 색을 바꾸고 dragleave 이벤트에서는 다시 배경과 border 색을 원상태대로 돌려 놓습니다.
이렇게 하면 이미지가 leftbox 안에 들어오면 복사가 가능하다는 의미로 배경색과 border 색이 변하고 drop 해서 복사가 끝나면 다시 원 상태대로 돌아올 겁니다.
사실 이 코드대로 하면 이미지 뿐만 아니라 그냥 마우스를 아무데서나 드래그해서 leftbox에 넣으면 색이 변합니다.

아래 오늘 소스코드를 올려 놓을 께요.



직접 해 보시고 여러분이 생각하신대로 프로그램을 좀 더 발전 시켜보세요.
이 코드를 응용해서 아주 다양한 기능을 만들 수 있을 겁니다.

예를 들어 쇼핑몰 홈페이지에서 쇼핑카트에 담는것을 그냥 드래그 앤 드롭으로 할 수도 있구요.

쇼핑몰 얘기가 나온김에 HTML5에서는 브라우저 내에서 mySQL 같은 Database 기능과 유사한 기능을 사용할 수 있도록 해 줍니다.

다음엔 이 브라우저 내 DB 기능에 대해서 공부해 볼께요.


반응형

HTML5 Canvas 이용하기 - 04 - Image/Animation

2011. 12. 24. 23:23 | Posted by 솔웅


반응형
HTML 5로 이미지를 다루는 법을 배워보겠습니다.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
   
    var pic = new Image();
    pic.src="nytimes.jpg";
   
    canvas.drawImage(pic, 0, 0);
 }
 window.addEventListener("load",doFirst,false);

곧바로 자바스크립트부터 들어가죠.
처음에 Image를 다룰 변수를 만들어 줍니다. 여기서는 pic이라는 지역변수(var)를 만들었습니다.
그 다음엔 이 변수에 원하는 이미지를 담습니다. 저는 nytimes.jpg라는 이미지를 사용할겁니다. (이 글 쓰면서 뉴욕타임즈 들어가 보니까 이 이미지가 있더라구요.)
이제 캔바스에다 그리면 됩니다. drawImage를 사용해서 pic을 x=0,y=0의 위치에 그립니다.

이렇게 하면 HTML5로 canvas에 image 를 넣을 수 있습니다.

그러면 아래 세 줄을 추가해 보세요.
    canvas.drawImage(pic, 100, 50,150,80);
    canvas.drawImage(pic, 400, 30, 69, 97, 300, 100, 103, 145);
    canvas.clearRect(500, 100, 10, 40);

좀 어지러워 졌죠?
첫 번째 줄은 이미지를 100,,50인 위치에 너비 150 높이 80으로 그리라는 의미입니다.
그리고 두번째는 400,30인 위치에서 너비 69 높이 97 만큼 복사해서 300,100 위치에 너비 103 높이 145 만큼 그리라는 겁니다.
그리니까 이미지 일 부분을 Copy and Paste 까지 할 수 있네요.
마지막은 우리가 전에 배웠던 clearRect 입니다. 해당 부분 만큼을 지워버리는 거죠.

제대로 설명 된 걸 한번 볼께요.




이제 좀 다이나믹한 걸 함 보겠습니다.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');

     window.addEventListener("mousemove",dougy,false);
 }
 
 function dougy(e) {
    canvas.clearRect(0,0,600,400);
    var xPos = e.clientX;
    var yPos = e.clientY;
    canvas.fillRect(xPos,yPos,50,50);
 }
 
 window.addEventListener("load",doFirst,false);

doFirst 안에 리스너를 하나 달았습니다. 지금까지 맨 밑에 있는 리스너만 썼었는데요. 이건 load 할 때 시행 되는 겁니다. doFirst 안에 있는 것은 마우스가 움직일 때 계속 불려 지는 겁니다.
마우스가 움직이는 동안 계속 dougy라는 함수를 호출 합니다.
dougy 함수를 보면 e를 인수로 받습니다. 이 e는 리스너로부터 전달되는 정보들 입니다.
처음에는 canvas를 싹 지웁니다.
다음에 보면 e.clientX 라는게 있는데 이건 마우스를 클릭했을 때 그 x 위치 입니다.
그러니까 e.clientY는 마우스의 y 위치 이겠죠. 이 정보들이 바로 아까 본 e 에 다 들어 있는 겁니다.
이 마우스 위치인 x,y 를 각각 xPos, yPos 변수에 대입 시킵니다.
그리고 사각형을 그리는데요. 그 그리는 위치가 바로 마우스의 위치인 xPos,yPos 입니다.
그러니까 마우스가 움직이는 동안 캔버스를 지우고 마우스 위치에 사각형을 그리는 작업을 계속 하는 겁니다.
1초에 몇백번 하는지 몇천번 하는지 모르겠지만 하여간 계속 그 작업을 합니다.
그러면 사각형이 마우스를 움직는대로 따라 움직이게 됩니다.

제법 그럴듯한 애니메이션 효과가 납니다.
이 사각형을 우주선 이미지로 바꾸면 마우스가 움직이는 대로 우주선이 움직일 수도 있습니다.
이제 HTML5로 게임 제작하기에 한발짝 더 다가선 것 같습니다.
자 한가지 여기서 dougy 함수 안에 canvas를 지우는 부분을 없애 보세요. // 로 주석을 다셔도 됩니다.

그리고 나서 마우스를 움직이면 캔버스를 지우지 않기 때문에 이전에 그린 사각형이 그대로 남겠죠? 그러면 위에 보시는 바와 같이 선을 그을 수가 있습니다.
포토샵의 브러시 툴 갖지 않나요?

지금까지 HTML5의 Canvas에 대해 알아봤습니다.
다음엔 HTML5의 새로운 Concept 에 대해 공부하겠습니다.
반응형

HTML5 Canvas 이용하기 - 03 -

2011. 12. 24. 04:05 | Posted by 솔웅


반응형
HTML5 canvas에 대해서 계속 공부하고 있습니다.

오늘은 일단 아래 코드를 공부할께요.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
   
    canvas.font="bold 22px Tahoma";
    canvas.textAlign="start;
    canvas.fillText("start",10,30);
   
    canvas.translate(100,150);
    canvas.fillText("after translate",0,0);
   
    canvas.rotate(1);
    canvas.fillText("after rotate",0,0);
   
    canvas.scale(1.5,4);
    canvas.fillText("after rotate",0,20);
 }
 window.addEventListener("load",doFirst,false);

처음에 font를 정해주고 정렬방식을 start 로 해 줍니다.
(보통 left,center,right 인데 여긴 start, middle, end 인가 봅니다. 왜 그런진 모르겠어요. 만든사람 마음이니까......)
그리고 start라는 글자를 쓰게 되요.
다음줄은 보니까 translate 이 있네요. 이건 x 좌표로 100포인트 y좌표로 150포인트 옮기라는 겁니다.
다음에 after translate 이라는 글자를 쓰는데 x,y는 0,0 입니다. 이 0,0은 canvas의 0,0이 아니라 translate 했던 100,150 을 기준으로 한 0,0 입니다.
그러니까 translate 하지 않고 100,150 한것이랑 똑같죠.
그래서 이 after translate 는 100,150 지점에 쓰여질 겁니다.
이 translate 명령어는 start 글자에는 적용되지 않습니다. translate 명령이 내려진 이후의 애들한테만 적용됩니다.

다음엔 뭐가 있죠? rotate 이 있네요.
이건 회전 시키라는 명령어인데요. 괄호 안에 있는 1은 Radian 단위 입니다. 반지름과 같은 길이의 호를  연결한 원의 중심 각도인데요. 나중에 게임 만들 때 아주 많이 쓰이게 되는 개념입니다. 모르시면 따로 공부해 두시는게 좋을거예요.
하여간 1Radian 만큼 회전시키라고 한 다음에 있는 것이 after rotate 이라는 글자입니다.
이 글자는 일단 translate 명령이 내려진 다음에 있으니까 좌표가 0,0으로 돼 있지만 실제 출력되는 위치는 100,150 지점이 됩니다.
그리고 rotate 하라고 했으니까 1Ratian 만큼 회전할 테구요.
다음은 scale 입니다. 좌우로 1.5배 위아래로 4배 키우라는 겁니다.
그리고 after Scale이라는 글자가 찍힐 텐데..
당연히 이 글자는 translate, rotate, scale 영향을 다 받게 됩니다.


이제 앞으로 캔바스에 그려지는 모든 것들은 다 이렇게 translate,rotate,scale 이 적용될 텐데요.
만약 이게 다 적용되지 않도록 하고 싶으면 어떻게 할까요?
save와 restore를 이용하면 됩니다.
자바스크립트를 아래와 같이 바꿔보세요.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
   
    canvas.font="bold 22px Tahoma";
    canvas.textAlign="start";
    canvas.fillText("start",10,30);
   
    canvas.save();
   
    canvas.translate(100,150);
    canvas.fillText("after translate",0,0);
   
    canvas.rotate(1);
    canvas.fillText("after rotate",0,0);
   
    canvas.scale(1.5,4);
    canvas.fillText("after Scale",0,20);
   
    canvas.restore();
   
    canvas.fillText("after restoring", 110,30);
 }
 window.addEventListener("load",doFirst,false);

보시면 처음 폰트와 정렬이 선언된 다음에 save() 를 해 놓습니다.
그리고 그 이후에 translate,rotate,scale 이런 기능들을 적용하구요.
다시 이 기능들을 적용하지 않기 위해 restore()를 해 줬습니다.
after restoring 은 제대로 110,30 위치에 쓰여질 겁니다.


오늘은 간단한 몇가지 기능들에 대해 공부했습니다.
반응형


반응형
오랜만에 코로나쪽을 공부해 보겠습니다.
얼마전에 기능이 추가 된 화면전환 효과 Story Board 샘플 소스를 분석해 볼께요.

Story Board API는 예전에 살펴 본 바 있습니다.

이 샘플 예제는 Corona SDK/interface 안에 storyboard 라는 폴더에 있습니다.

우선 main.lua 소스 파일 입니다.

display.setStatusBar( display.HiddenStatusBar )
-- require controller module
local storyboard = require "storyboard"
local widget = require "widget"
-- load first scene
storyboard.gotoScene( "scene1", "fade", 400 )
-- Display objects added below will not respond to storyboard transitions
-- table to setup tabBar buttons
local tabButtons = {
    { label="First", up="icon1.png", down="icon1-down.png", width = 32, height = 32, selected=true },
    { label="Second", up="icon2.png", down="icon2-down.png", width = 32, height = 32 },
}
-- create the actual tabBar widget
local tabBar = widget.newTabBar{
    top = display.contentHeight - 50,    -- 50 is default height for tabBar widget
    buttons = tabButtons
}
main.lua에서는 딱 두 부분으로 나뉘어 져 있습니다.
첫번째는 Story Board 를 이용한 부분이고 두번째는 Tab Button을 이용한 부분입니다.
이 두 기능을 이용하기 위해 storyboard와 widget 을 require 했습니다.
그리고 storyboard 부분은 gotoScene 을 이용해서 화면 전환 한 것 밖에는 없습니다.
scene1.lua 로 가는데 0.4초동안 fade 효과를 이용해서 화면 전환을 합니다.
화면 전환 효과는 fade를 포함해서 모두 20개의 효과가 있습니다.
내용은 여기를 클릭하시면 보실 수 있습니다.
두번째는 탭바를 생성하는 건데요. 일단 tabButtons 테이블 안에 탭버튼 두개의 정보들을 담아 놓습니다. 그리고 widget.newTabBar로 Tabbar를 만드는데요. 중요한건 이 탭 바는 화면전환해도 계속 남아 있는 다는 겁니다.

Story Board API 에서는 scene 의 life cycle 메소드가 4개 있습니다.
createScene,enterScene,exitScene,destroyScene
그리고 이 메소드 안에서 생성한 object 들만 화면전환시 적용이 됩니다.
director.lua 클래스는 localGroup을 생성해서 그 그룹에 insert 한 객체들만 적용이 됐었습니다.
이번에 코로나에서 제공한 화면전환 API는 이보다 더 세밀한 화면 전환 단계를 이용할 수 있게 만들었습니다.
이 4개 메소드가 적용된 예는 Scene1 설명할 때 나올겁니다.

일단 여기서 만드는 tabbar 는 화면전환시 적용되지 않고 처음부터 끝까지 계속 남아있을 겁니다.
(그리고 tab bar 관련된 글을 한번도 안 다뤄봤는데요. 이 기능은 나중에 자세히 다뤄볼께요.)


-- storyboard.gotoScene( "scene1", "fade", 400 )
이렇게 scene1.lua로 넘어가는 부분을 주석 걸어놓고 실행하면 위 화면이 나옵니다.

이게 온전히 main.lua만을 실행했을 때 나오는 화면입니다.
그 다음에 scene1.lua를 보겠습니다.

local storyboard = require( "storyboard" )
local scene = storyboard.newScene()

---------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------

local image, text1, text2, text3, memTimer

-- Touch event listener for background image
local function onSceneTouch( self, event )
    if event.phase == "began" then
        storyboard.gotoScene( "scene2", "slideLeft", 800  )
        return true
    end
end

-- Called when the scene's view does not exist:
function scene:createScene( event )
    local screenGroup = self.view
   
    image = display.newImage( "bg.jpg" )
    screenGroup:insert( image )
   
    image.touch = onSceneTouch
   
    text1 = display.newText( "Scene 1", 0, 0, native.systemFontBold, 24 )
    text1:setTextColor( 255 )
    text1:setReferencePoint( display.CenterReferencePoint )
    text1.x, text1.y = display.contentWidth * 0.5, 50
    screenGroup:insert( text1 )
   
    text2 = display.newText( "MemUsage: ", 0, 0, native.systemFont, 16 )
    text2:setTextColor( 255 )
    text2:setReferencePoint( display.CenterReferencePoint )
    text2.x, text2.y = display.contentWidth * 0.5, display.contentHeight * 0.5
    screenGroup:insert( text2 )
   
    text3 = display.newText( "Touch to continue.", 0, 0, native.systemFontBold, 18 )
    text3:setTextColor( 255 ); text3.isVisible = false
    text3:setReferencePoint( display.CenterReferencePoint )
    text3.x, text3.y = display.contentWidth * 0.5, display.contentHeight - 100
    screenGroup:insert( text3 )
   
    print( "\n1: createScene event")
end

-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
   
    print( "1: enterScene event" )
   
    -- remove previous scene's view
    storyboard.purgeScene( "scene4" )
   
    -- Update Lua memory text display
    local showMem = function()
        image:addEventListener( "touch", image )
        text3.isVisible = true
        text2.text = text2.text .. collectgarbage("count")/1000 .. "MB"
        text2.x = display.contentWidth * 0.5
    end
    memTimer = timer.performWithDelay( 1000, showMem, 1 )
end

-- Called when scene is about to move offscreen:
function scene:exitScene( event )
   
    print( "1: exitScene event" )
   
    -- remove touch listener for image
    image:removeEventListener( "touch", image )
   
    -- cancel timer
    timer.cancel( memTimer ); memTimer = nil;
   
    -- reset label text
    text2.text = "MemUsage: "
end


-- Called prior to the removal of scene's "view" (display group)
function scene:destroyScene( event )
   
    print( "((destroying scene 1's view))" )
end

---------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------

-- "createScene" event is dispatched if scene's view does not exist
scene:addEventListener( "createScene", scene )

-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )

-- "exitScene" event is dispatched before next scene's transition begins
scene:addEventListener( "exitScene", scene )

-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )

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

return scene

이 scene1.lua 는 onSceneTouch 함수와 StoryBoard 에 소속된 4개 함수로 구성된 간단한 구조입니다

이 함수 호출은 Storyboard 4인방은 scene:addEventListener 를 사용해서 호출이 되고 onSceneTouch 는 배경이미지에 리스너를 달아서 화면을 터치하면 scene2로 이동하게끔 하는 겁니다.

4인방 메소드에서는 self.view를 이용해서 객체들을 그룹화 하면서 화면에 보여줄 수 있도록 합니다.

처음 createScene 에서는 배경이미지와 텍스트 등 기본 display 요소들을 정의하고 표시합니다.

enterScene 에서는  0.1초 후에 실행되는 타이머를 달아서 showMem 함수를 실행하도록 했습니다.
이 함수는 배경이미지를 터치하면 scene2.lua로 가도록 하는 onSceneTouch 함수를 Call 하는 리스너를 달았고 현재 메모리를 모여주는 로직이 있습니다.
그 이전에 storyboard.purgeScene( "scene4" ) 이 있는데요. purgeScene 은 해당 scene(여기서는 scene4) 에 있는 객체들을 모두 unload 합니다. purge말고 remove를 사용하면 unload 될 뿐만 아니라 메모리에서도 사라집니다.
이 기능은 메모리를 절약하거나 할 때 사용하는 건데 scene1에서 scene2로 넘어 갈때 터미널에 뭐가 찍히는지 보면 잘 알 수 있습니다.

보시다시피 scene1이 시작되면 scene4 의 destroy 가 호출 되서 그 안의 내용이 실행 됩니다.
scene1에서 scene2로 넘어갈 때 destroyScene 함수가 호출되는게 아니라 해당 scene이 unload 될 때 destroyScene 이 호출 됩니다.
그리고 purgeScene 하게 되면 해당 scene 의 destroyScene 이 호출 됩니다.
removeScene 하게 되면 purgeScene 한 후 메모리에서 없애므로 자연히 destroyScene 이 호출 됩니다.

exitScene 은 다음 화면으로 넘어갈 때 실행 되는데 여기서는 모든 리스너를 remove 하고 timer 도 cancel 합니다.

여기까지 하면 실행되는 화면이 아래와 같습니다.


나머지 scene2,scene3,scene4 도 이 scene1과 구조가 동일 합니다.

그런데 여기서 드는 한가지 의문점은 Tab Bar 는 화면 전환에 상관 없이 계속 있는데요.

특정 화면에서 이 TabBar 를 안 보이게 하거나 없애거나 아니면 어떻게 콘트롤을 할 수 있을까요?

그렇게 하려면 main.lua 에서 tabBar 를 local 이 아니라 glabal 변수로 선언하면 됩니다. 그냥 local 이란 글자만 지우세요.

그리고 scene3.lua 맨 밑에 (return scene 바로 윗줄에) tabBar.isVisible = false; 를 넣어보시고. scene4.lua에는 tabBar.isVisible = true 를 넣어보세요.

그러면 이렇게 scene3에는 탭바가 없어지고 scene4에는 나타나게 됩니다.
이런식으로 tabbar를 제어하시면 됩니다.


반응형


반응형
HTML5의 canvas 를 이용해서 브라우저에 무엇인가 그리는 법을 배우고 있습니다.
지난시간에는 첫시간으로 사각형 그리기에 대해 알아봤습니다.

일단 그리기는 처음에 선 그리기부터 배우는게 맞지 않나 싶네요. 어린 애들도 처음에 선따라 그리기 하잖아요?

선을 그려 보겠습니다.
javascript 내용을 아래와 같이 바꿔 보세요.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
   
    canvas.beginPath();
    canvas.moveTo(50,50);
    canvas.lineTo(70,250);
    canvas.lineTo(300,200);
    canvas.closePath();
    canvas.stroke();
 }
 window.addEventListener("load",doFirst,false);

처음에 선을 그리겠다고 의사표현을 합니다. 그것이 beginPath(); 이고 나중에 선 그리는게 끝났다고 얘기해 줍니다. 그게 closePath() 입니다.
그 안에서 선을 그리면 되는데요.
처음에 시작할 부분은 moveTo()에서 정해 줍니다. 그 다음에 lineTo로 첫지점에서 다음지점까지 (여기서 지점은 좌표를 말합니다.) 선을 그어줍니다. 이 lineTo가 계속 되면 좀 더 많은 선이 그어 지겠죠.
이렇게 선을 그었으면 이걸 canvas에 표시하라고 얘기해 줘야 합니다. 이것이 stroke() 입니다. 컴퓨터는 이렇게 하나하나 일일이 얘기를 해줘야 알아듣습니다. 애기보다 더 해요. 점 하나만 틀려도 못알아듣고 스펠 하나만 잘못되도 시키는대로 안하고..

자 이렇게 선을 그었습니다.
한가지 더 팁을 드리면 canvas.strokeStyle = "red"; 를 추가하면 선 색을 빨간색으로 할 수 있습니다.
영어 공부도 할 겸 영어로 정리해 볼까요?
moveTo(x,y)     move to starting point with coordinate x and y.
lineTo(x,y)     Draw a line to this point from starting point. Again x and y being the coordinate.
strokeStyle     CSS color of the line
stroke     A method to actually make javascript draw a line
beginPath     Before you start drawing a new line with different color, you will have to call "beginPath".

HTML5에는 글자도 타입할 수 있습니다.
그리고 그 글자에 그림자 효과 같은걸 줄 수도 있구요.
배워보겠습니다.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
     
     canvas.shadowOffsetX=4;
     canvas.shadowOffsetY=4;
     canvas.shadowBlur=6;
     canvas.shadowColor='rgba(0,0,255,.5)';

     canvas.font="bold 36px Tahoma";
     canvas.textAlign="end";
     canvas.fillText("Douglas's HTML5 Study",450,100);
 }
 window.addEventListener("load",doFirst,false);

우선 그림자 효과부터 만들어야 합니다. (나중에 만들어도 되지만 하옇든간 글자 뿌려주는 부분보다는 위에 있어야 합니다.)
그림자 효과를 오른쪽으로 4픽셀 아래로 4픽셀인 곳에 주고 번지는 효과는 6 정도로 줍니다. 그리고 색은 rgb(red,green,blue) 중 모두 0으로 하고 blue만 255로 했으니까 파란색이 되구요 그리고 마지막  a(alpha, 투명도)는 .5 로 50% 줍니다.

그 다음은 글자(Text와 관련된 건데요.) 볼드로 36픽셀크기인 글자고 폰트는 Tahoma 폰트 입니다. 그리고 정렬은 end에다 하고 테두리선이 있는 글자가 아니라 안에 색이 채워진 글자로 괄호 안에 있는 글자를 뿌립니다. 그리고 그 다음 숫자들은 글자 위치인 x,y 좌표구요.


Text 와 관련된 요소들부터 정리할 께요.
fillText(text,x,y) : Print the text with solid color within. Text color is determined by fillStyle().
strokeText(text,x,y)     Print the text with only color the outline of the text. Text color is set by strokeStyle().
strokeStyle     CSS color for text that call strokeText
fillStyle     CSS color for text that call fillText
font     CSS font style such as "bold, 10px, san-serif"
textBaseline     This is a little bit tricky to explain. We will need another demo. The value for this propery can be "top", "hanging", "middle", "alphabetic", "ideographic" and "bottom". Default value is "alphabetic".

아래와 같이 코드를 작성해 보세요.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
     
     canvas.shadowOffsetX=4;
     canvas.shadowOffsetY=4;
     canvas.shadowBlur=6;
     canvas.shadowColor='rgba(0,0,255,.5)';

     canvas.font="bold 36px Tahoma";
     canvas.textAlign="start";
     canvas.fillText("Douglas's HTML5 Study",10,100);
     
     canvas.textBaseline = "top";
     canvas.fillText('Top', 10, 200);
     
     canvas.textBaseline = "bottom";
     canvas.fillText('Bottom', 90, 200);
     
     canvas.textBaseline = "middle";
     canvas.fillText('Middle', 200, 200);
     
     canvas.textBaseline = "alphabetic";
     canvas.fillText('Alphabetic', 300, 200);
     
     canvas.textBaseline = "hanging";
     canvas.fillText('Hanging', 400, 200);
 }
 window.addEventListener("load",doFirst,false);

baseLine과 관련된 샘플입니다.

아래는 shadow와 관련된 내용 정리한 겁니다.
shadowOffsetX : Horizontal distance (x-axis) between the shadow and the shape in pixel.
shadowOffsetY : Vertical distance (y-axis) between the shadow and the shape in pixel.
shadowBlur : How blur you want your shadow to be.
shadowColor : Obviously, this is to set the color of your shadow

위 4개 속성은 이미 예제에서 다 사용했습니다.

다음글에도 이어서 계속 canvas에 대해 다루겠습니다.
반응형

HTML5 Canvas 이용하기 - 01 -

2011. 12. 21. 20:59 | Posted by 솔웅


반응형
HTML5 에서는 브라우저에 도형을 그리거나 이것을 움직이거나 하는 일들을 할 수 있습니다.
제가 느끼기엔 자바에 있는 Swing 이랑 비슷한 개념인것 같습니다.
이름에서 알수 있듯이 그림 그릴때 사용하는 캔버스처럼 브라우저에 캔버스를 놓고 그 캔버스 위에 그림을 그리는 겁니다.
HTML5에서는 이 Canvas라는 판만 깔아 놓고 실제 그림 그리는 작업은 JavaScript 에서 합니다.
이제 HTML5의 Canvas를 이용해 보겠습니다.
먼저 HTML 파일을 만들어 주세요. (저는 canvas01.html로 했습니다.)
 <!doctype html>
<html lang="en">
<head>
    <title> Dougy's HTML5 HTML5 Canvas</title>
    <meta charset="utf-8"/>
    <script src="canvasdoug01.js"></script>
</head>
<body>
    <section id="main">
        <canvas id="canvas" width="600" height="400" style="border:solid 1px #000000">
            If you can see this. No good. get google chrome browser to see html5 canvas.
        </canvas>
    </section>
</body>
</html>
이 코드가 HTML5로 브라우저에 판을 깔아 놓은 예제 입니다.
canvas 태그 사이에 있는 문장은 브라우저가 HTML5를 지원하지 않는 경우 나오게 됩니다. 만약에 지원하게 된다면 나오지 않습니다.
canvas 는 <canvas></canvas> 로 선언되고 width와 height를 지정할 수 있습니다.
그리고 위 코드에서는 id를 canvas로 주었습니다.
style은 태그내에서 CSS 효과를 주는 건데요. 브라우저로 볼 때 테두리를 만들어서 볼 캔버스 크기를 알아볼 수 있도록 하기 위해서 그냥 넣었어요.
안 그러면 그냥 하얗게만 보이거든요.

브라우저에 캔버스가 저만큼 만들어 졌어요.
이제 저 캔버스 안에 자바스크립트를 가지고 그림을 그리거나 간단한 애니메이션을 만들거나 할 건데요.
자바스크립트 이름은 canvasdoug01.js 로 했습니다.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
    canvas.strokeRect(10,10,100,200);
    canvas.fillRect(150,50,100,200);
 }
 window.addEventListener("load",doFirst,false);

함수 doFirst()를 만들었구요. 그 안에 그림 그리라는 명령들을 넣었습니다.
이 doFirst()는 load 될 때 불려지도록 했구요. 맨 아래 리스너에 대한 설명은 이전 글에서 했기 때문에 생략할께요.
우선 x 라는 지역변수를 만들고 거기에 html 안에 id가 canvas 인 태그를 대입했습니다. 이제 이 x 가지고 html 안에 있는 id가 canvas 인 태그를 맘대로 요리할 수 있게 됐습니다.
다음은 canvas 라는 global 변수를 만들고 그 안에 x에 담을 내용은 2d 라고 알려 줬습니다.
아직 2d 밖에 지원이 안 되는데 나중에 기술이 발달되면 3d,4d 도 사용할 수 있게 되겠네요.
자바스크립트에서는 지역변수를 선언할 때 var를 사용합니다. 이 지역변수 전역변수(global variable)에 대한거는 CoronaSDK 관련 글에서 자세히 그것도 반복하면서 언급했던걸로 기억하는데요.
일단 지역변수는 그 함수 안에서 밖에 사용못합니다. 하지만 전역변수는 함수 밖에서도 사용할 수 있지요.
프로그램을 많이 만들다보면 지역변수,전역변수를 어떻게 유용하게 사용할 지 몸으로 익히시게 될 겁니다.
그 다음에 있는 코드들이 캔버스에 그림을 그리는 코드들입니다.
처음엔 외곽선이 있는 사각형이구요. 괄호 안에 있는 내용들은 x,y 좌표와 width와 height 입니다.
두번째는 색이 안에 채워진 사각형입니다.

이런식으로 HTML5에서는 html 파일에서 canvas를 만들어 놓고 javascript에서 그 canvas 안에 그림을 그리게 됩니다.
다음은 지우는 방법에 대해 공부합니다.
doFirst 함수 안에 아래 두 줄을 넣어 주세요.
    canvas.clearRect(70,30,130,50);
    canvas.clearRect(160,100,30,60);
clearRect 는 지우라는 명령입니다. canvas에 뭐가 그려져 있던 이 사각형안에 내용은 모두 지우라는 겁니다.


이제 색을 좀 넣어볼까요?
doFirst를 아래와 같이 수정해 보세요.
 function doFirst(){
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
    canvas.fillStyle="blue";
    canvas.strokeStyle="red";
    canvas.strokeRect(10,10,100,200);
    canvas.fillRect(150,50,100,200);
    canvas.clearRect(70,30,130,50);
    canvas.clearRect(160,100,30,60);
 }
fillStyle 하고 strokeStyle 에 색을 주었습니다. 그러면 fillRect에는 파란색이 그리고 strokeRect에는 빨간 테두리선이 적용될 겁니다.


색을 주었으니 이제 그라데이션 효과 주는 법도 배워볼까요?
    var x = document.getElementById('canvas');
    canvas = x.getContext('2d');
    var g = canvas.createLinearGradient(0,0,100,200);
    g.addColorStop(.0,"blue");
    g.addColorStop(1,"red");
    canvas.fillStyle=g;
    canvas.fillRect(0,0,100,200);
    canvas.strokeStyle="red";
    canvas.strokeRect(10,10,100,200);
    canvas.fillRect(150,50,100,200);
    canvas.clearRect(70,30,130,50);
    canvas.clearRect(160,100,30,60);

지역변수 g에 그라데이션을 대입했습니다.
그리고 파란색에서 시작해서 빨간색으로 끝나구요.
이 g를 fillStyle에 적용했습니다. 이렇게 되면 모든 fill 스타일엔 다 적용될 겁니다.

보시면 새로만든 사각형에 그라데이션 효과가 잘 적용 됐죠? 뿐만아니라 아까 만들었던 fillRect 에도 살짝 적용된걸 보실 수 있습니다.

오늘은 여기까지 하고 다음에 계속해서 HTML5의 canvas에 대해서 알아보겠습니다.

반응형


반응형
지난 글에서 HTML5 Video 태그를 이용해 브라우저에서 동영상을 상영하는 것을 공부해 봤습니다.
그리고 CSS로 꾸미는 방법하고 내가 원하는 스킨 만드는 법하고요.
자바스크립트를 이용해서 play/pause 하는 법까지 진행했습니다.
여기까지 하면 브라우저를 통해서 동영상을 보고 멈추고 하는 기본적인 기능은 다 됐습니다.
이제 동영상이 진행됨에 따라 Progress Bar 가 그 진행상태를 나타내주고 또 마우스로 진행바를 클릭하면 그 위치로 동영상이 옮겨져서 플레이 하도록 하는 기능을 배우겠습니다.
 function playOrPause() {
    if(!myMovie.paused && !myMovie.ended){
        myMovie.pause();
        playButton.innerHTML='Play';
        window.clearInterval(updateBar);
    }else{
        myMovie.play();
        playButton.innerHTML='Pause';
        updateBar=setInterval(update,500);
    }
 }
지난 시간에 만든 playOrPause 함수인데요 if 안에 window.clearInterval(updateBar) 가 추가 됐고 else 문 안에 updateBar=setInterval(update,500) 이 들어 있습니다.
먼저 else문에 있는 내용을 보면요.
updateBar 변수에 setInterval을 해 줍니다. 그 내용은 0.5초마다 update 함수를 실행하라는 내용입니다.
그리고 if 문에서는 (만약에 동영상이 play 중이면) 이 0.5초마다 update 함수를 call 하는 것을 중지하도록 하고 있습니다.

그럼 이제 update()함수를 만들어 볼까요?
이 update 함수에서는 동영상이 플레이 중이면 그 진행상황을 progress bar에 표시해 줄 겁니다. 그리고 동영상이 끝나면 진행바가 다시 처음으로 세팅되도록 하고 Button 글씨를 play로 바꿔 줄 거구요. 그리고 동영상이 끝나면 더이상 진행바를 업데이트 할 필요가 없으니까 setInterval 한 것도 clear 시킬겁니다.

이것을 자바스크립트가 알아듣는 언어로 번역하면 아래와 같습니다.
 function update(){
    if(!myMovie.ended){
        var size=parseInt(myMovie.currentTime*barSize/myMovie.duration);
        progressBar.style.width=size+'px'
    }else{
        progressBar.style.width='0px'
        playButton.innerHTML='Play';
        window.clearInterval(updateBar);
    }
 }
if 문은 myMovie가 ended가 아니면.. 즉 플레이 중이면(pause 중이어도 해당 됩니다.) 실행하라는 겁니다.
그 내용은 지역변수(var) size에 myMovie 의 전체 길이 중 지금 현재 위치를 구해서 barSize(600) 에 맞게 그 비율 대로 표시 할 수 있는 숫자를 구합니다.
(동영상의 전체 시간-길이- 는 브라우저가 이미 가지고 있습니다.)
지난번에 css파일 안에서 progressBar 의 width를 1px로 해 놨는데요.(사실은 이걸 이제 0px)으로 해야 합니다. 이 길이를 size 만큼으로 변경 시킬 겁니다.
자바스크립트에서 css 내의 값을 바꾸는 방법은 변수.style을 사용하면 됩니다.
위에서와 같이 progressBar.style의 width= size로 하는 겁니다. 그리고 css에서는 px라는 단위를 사용해야 되기 때문에 +'px'을 해 줍니다.
이제 0.5초마다 이 update 함수가 불려지면서 progressBar의 길이를 점점 바꿀 겁니다.

이제 동영상이 진행되는것에 맞춰 progress bar 가 진행 되고 Pause를 누르면 동영상과 함께 진행바도 멈춤니다.
그런데 아직 노란선을 누르면 동영상이 그 위치로 가서 플레이 되고 진행바도 그 위치에서 이어서 진행되도록 하는 기능은 없습니다.
이것은 clickedBar라는 함수에서 구현 할 겁니다. 잊으셨는지 모르겠는데 doFirst() 함수에서 이미 bar.addEventListener('click',clickedBar,false); 를 선언해 뒀습니다.
bar(id가 defaultBar) 즉 노란선을 클릭하면 clickedBar 함수를 call 하는 리스너 입니다.
그러니 이젠 이 함수를 구현하기만하면 됩니다
이 함수에서는 마우스로 클릭된 지점을 구해서 그만큼 barSize를 정하고 동영상을 그 지점부터 시작하도록 해야 합니다.
 function clickedBar(e) {
    if(!myMovie.paused && !myMovie.ended){
        var mouseX = e.pageX-bar.offsetLeft;
        var newtime = mouseX*myMovie.duration/barSize;
        myMovie.currentTime = newtime;
        progressBar.style.width=mouseX+'px'
    }
 }
여기서 e 는 해당 이벤트 입니다. 리스너를 click에 걸었으니까 e 는 그 click에 대한 정보를 담고 있습니다.
클릭한 지점은 x,y 좌표로 표현할 수 있습니다.
e.pageX는 클릭한 지점의 X좌표 입니다.
그 다음 offSetLeft 는 객체의 위치 중 width와 관련된 property 입니다.
자세한 사항은 여기를 참조하세요.
이 x 값을 지역변수 mouseX에 담습니다.
다음 지역변수 newtime에 동영상 전체 길이에 비례한 barSize내의 값을 담습니다.
그리고 다음 줄에서는 동영상의 현재 위치를 newtime으로 바꾸고요.
마지막 줄에서는 progressBar의 길이를 mouseX 필셀로 업데이트 합니다.

이제 progressBar 에 대한 기능 구현까지 모두 완료 했습니다.
html과 css 파일은 지난 글에 업로드한 파일 그대로구요.
자바스크립트 파일만 업로드 할께요.

여러분은 html 파일 안에 있는 동영상 이름만 여러분이 가지고 있는 것으로 바꾸시면 됩니다.

HTML5 로 나만의 동영상 플레이어 스킨 만들기는 completed 됐구요.
다음엔 아마 HTML5 의 Canvas 에 대해 공부할 겁니다.

반응형