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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형
오랜만에 코로나쪽을 공부해 보겠습니다.
얼마전에 기능이 추가 된 화면전환 효과 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에 대해서 알아보겠습니다.

반응형