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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

HTML5 CSS Animation 효과

2011. 12. 15. 22:21 | Posted by 솔웅


반응형
제가 이 글을 회사에서도 올리고 집에서도 올리고 해서 파일 이름이 헛갈리네요.

오늘도 예전처럼 간단한 html 을 준비해 두시구요. (이름은 여러분들이 정하세요.)
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title> Dougy's HTML5 </title>
    <link rel="stylesheet" href="main06.css">
</head>
<body>
    <div id="box">
        <p id="text"> Text Test. </p>
    </div>
</body>
</html>

main06.css를 아래와 같이 준비하세요.
body{
    text-align:center;
}
#box{
    display:block;
    width:500px;
    margin:50px auto;
    padding:15px;
    text-align:center;
    border:7px solid blue;
    background:yellow;
    outline:7px solid red;
    -webkit-transform:scale(-1,1)
}
#text{
    font:bold 30px Century Gothic;
    text-shadow:rgb(110,110,110) 3px 3px 5px;
}

이제 css를 이용한 animation 효과를 다뤄보겠습니다.
css 파일에 아래 내용을 추가해 보세요.
#box:hover{
    -webkit-transform:rotate(45deg);
}

이렇게 하면 보여드릴 수는 없지만 저 박스에 마우스를 갖다 대면 45도로 박스가 기웁니다.
제 경우에 이 기능은 크롬 브라우저에서만 작동합니다. 아마 다른 브라우저들도 최신버전에서는 작동될지 모르겠습니다.
코드를 보면 box에 마우스를 올리면 45도 돌리라고 돼 있죠? 이렇게 만 하면 마우스가 box에서 벗어나면 다시 제자리로 자동으로 돌아오네요.

이것만해도 약간의 애니메이션 기능이 됐는데요. 좀 더 그럴듯한 효과가 있습니다.
#box 안에 (#box:hover가 아니라) 아래 코드를 넣으세요.
    -webkit-transition:-webkit-transform 2s;

이렇게 하면 45도로 기울이는 동작을 2초에 걸쳐서 하게 됩니다. 그러니까 아주 부드럽게 움직이게 되죠.
한번 직접 해 보세요. 아주 그럴듯 할 겁니다.

하기 전에 css파일을 아래와 같이 만들어 주세요.
body{
    text-align:center;
}
#box{
    display:block;

}
#text{
    font:bold 30px Century Gothic;
    text-shadow:rgb(110,110,110) 3px 3px 5px;
}
#box:hover{
   
}

그리고 #box 안에 아래 코드를 추가하세요.
    margin:150px auto;
    color:#ffffff;
    -webkit-border-radius:10px;
    opacity:0.6;
    background:red;
    width:120px;
    height:75px;

이러면 브라우저에 위와 같은 박스가 뜰 거예요.
여기서 부터 그럴 싸한 애니메이션을 시작할 께요.

그럼 #box 안에 이어서 아래 코드를 넣어 보세요.
    -webkit-transition:-webkit-transform 2s, opacity 2s, background 2s, width 2s, height 2s;

아까 다뤘던거도 있고 그렇지 않은 것도 있죠?
이 의미는 transform이 일어날 때 2초동안 일을 처리하고 투명도,배경,너비,높이 변화도 모두 2초동안 일을 진행하라는 의미입니다.

이제 hover에 위 조건들을 변화시키라는 명령만 하면 됩니다.

이제 #box:hover 안에 아래와 같이 코드를 넣으세요.
    -webkit-transform:rotate(360deg);
    opacity:1;
    background:#1ec7e6;
    width:450px;
    height:110px;

그리고 실행을 해 보세요.
애니메이션 기능이라 캡쳐화면을 넣기 어려운데요.
직접 한번 돌려보세요. 애니메이션 기능에 아주 만족하실 거예요.
2초동안 투명도, 배경색, 너비, 높이가 부드럽게 회전하면서 변할겁니다. (마우스를 올리면요.)
플래시로 한 것 같은 효과 아니예요? 자바스크립트로 한 것도 아니고 그냥 CSS로만으로도 이런 기능이 가능하다고 하니 대단하네요.

전체소스코드는 위에 있습니다.
다음엔 자바스크립트 쪽을 공부해 볼께요.

HTML5로 모바일 게임을 만드는 그날까지 쭉~~~~~



반응형


반응형
Corona SDK로 게임을 만들 때 어떻게 Level별 Lock 기능을 걸고 푸는지에 대해 샘플을 보면서 공부 해 보겠습니다.

오늘 소스는 개발자 peach pellen 이 만들고 공유한 소스코드입니다.
http://peachpellen.com/ 로 가면 많은 정보들도 있구요. 우리의 peach가 열심히 만들어서 공유하고 있는 다른 정보들도 접할 수 있습니다.
가서 댓글로 고마움을 표시하는 것도 좋은 일 인것 같습니다.

원본 파일은 아래에 올리겠습니다.


우선 main.lua를 보겠습니다. (지면을 줄이기 위해서 필요없는 주석은 지울께요.)
display.setStatusBar (display.HiddenStatusBar)
local director = require ("director")
local mainGroup = display.newGroup()
local function main()
    mainGroup:insert(director.directorView)
    director:changeScene("menu")
    return true
end
main()
첫째줄은 늘 그래왔듯이 iPhone의 status bar를 없애는 라인이구요.
두번째 라인은 director.lua 클래스를 require한 라인입니다.
이 director클래스는 일반 개발자가 만든 화면 전환용 클래스죠?
얼마전 코로나에서 화면전환용 api인 storyboard api를 제공하기 시작했으니 그 api를 사용해도 될 겁니다.
이 소스는 그 api가 나오기 이전에 만들어진 것이니 그대로 director 클래스를 사용하겠습니다.
director 클래스에 대해서는 이전에 살펴 본 적이 있으니 따로 설명하지는 않겠습니다.
세번째 줄은 mainGroup이라는 그룹을 만든것이고 그 다음줄에 main() 함수를 만들었습니다.
이 함수 안에서 mainGroup에 directorView를 insert합니다.
그 다음에 changeScene으로 menu.lua 파일로 스크린을 옮깁니다.
화면전환 효과는 아무것도 사용하지 않았네요.
마지막 줄은 이 main함수를 call 해 주는 겁니다.

이젠 그럼 menu.lua를 볼까요?

module(..., package.seeall)
-- BELOW is Director code
function new()
    local localGroup = display.newGroup()
-- ABOVE is Director code

require "saveit"

-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
local function resumeStart()
            local path = system.pathForFile( "ourdata.txt", system.DocumentsDirectory )               
                local file = io.open( path, "r" )

                if file then
                    print("Loading our data...")
                    local contents = file:read( "*a" )
                    -- Loads our data
                   
                    local prevState = explode(", ", contents)

                        _G.onelock = prevState[1]
                        _G.twolock = prevState[2]

                    io.close( file )

                else
                    _G.onelock = 1
                    _G.twolock = 0
                end
            end
            -- Separates the variables into a table
 
local function onSystemEvent( event )
        if( event.type == "applicationExit" ) then             
                local path = system.pathForFile( "ourdata.txt", system.DocumentsDirectory )               
                local file = io.open( path, "w+b" )
                -- Creates the file where we save our data
               
                file:write( _G.onelock ..", ".. _G.twolock)         
                io.close( file )
            end
        end
        -- Saves our data

--BELOW THIS LINE IS ANSCA'S SAMPLE CODE (I don't mess with perfection)
-- explode helper function zomgdata
function explode(div,str)
  if (div=='') then return false end
  local pos,arr = 0,{}
  -- for each divider found
  for st,sp in function() return string.find(str,div,pos,true) end do
    table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider
    pos = sp + 1 -- Jump past current divider
  end
  table.insert(arr,string.sub(str,pos)) -- Attach chars right of last divider
  return arr
end
 
local function init()
        -- start and resume from previous state, if any
        resumeStart()  
        
        Runtime:addEventListener( "system", onSystemEvent )    
end
 
 
--start the program
init()
--ABOVE THIS LINE IS ANSCA'S SAMPLE CODE (You don't need to change it, so don't!)

----------------------------------------------------------------------
--                                SCENE SETUP                            --
----------------------------------------------------------------------
local background = display.newImage ("background.png")
localGroup:insert(background)
-- Sets the background

local leveloneicon = display.newImage ("level1icon.png")
leveloneicon.x = 50
leveloneicon.y = 40
localGroup:insert(leveloneicon)
-- Sets the icon for level one

local function gotoone (event)
director:changeScene("level1")
end
leveloneicon:addEventListener("tap", gotoone)
-- Go to level one when icon is tapped

local function gototwo (event)
director:changeScene("level2")
end
-- Function to go to level two

local function seticontwo (event)
if _G.twolock-0 == 0 then
local leveltwoicon = display.newImage ("level2locked.png")
leveltwoicon.x = 130
leveltwoicon.y = 40
localGroup:insert(leveltwoicon)
elseif _G.twolock-0 == 1 then
local leveltwoicon = display.newImage ("level2icon.png")
leveltwoicon.x = 130
leveltwoicon.y = 40
localGroup:insert(leveltwoicon)
leveltwoicon:addEventListener("tap", gototwo)
end
end
seticontwo()

----------------------------------------------------------------------
----------------------------------------------------------------------
-- BELOW is Director code
    -- MUST return a display.newGroup()
    return localGroup
end
-- ABOVE is Director code

모듈로 사용되기 위해 필요한 부분이 맨 처음 줄이구요.
그 다음은 Director클래스를 사용하기 위해 new()함수 안에 모든 코드를넣고 localGroup이라는 그룹을 만든 겁니다.
다음엔 saveit.lua파일을 require했습니다.
짧으니까 잠깐 saveit.lua 파일을 볼께요.
module(..., package.seeall)
function save( event )          
                local path = system.pathForFile( "ourdata.txt", system.DocumentsDirectory )               
                local file = io.open( path, "w+b" )
                -- Creates the file where we save our data if needed
                file:write( _G.onelock ..", ".. _G.twolock)         
                io.close( file )
                -- Saves our data
end
첫줄은 마찬가지로 모듈로 사용되기 위해 필요한 라인이구요. 그 다음에 save(event) 함수를 구현했습니다.
event가 인수로 있는 것으로 봐서 어떤 리스너에서 불러오지 않나 생각되네요.
함수 내용은 ourdata.txt를 쓰기 가능으로 열고 그 파일 안에 _Gonelock,_Gtwolock을 씁니다. 그리고 저장하면서 닫습니다.

이 기능이 menu.lua 어느곳에선가 불려져서 사용 될 겁니다.
다시 menu.lua로 넘어올께요.

첫번째로 resumeStart()함수를 보겠습니다.
이 함수에서는 ourdata.txt라는 파일을 엽니다.
만약 이 파일이 있으면 "Loading our data..." 라는 문장을 터미널에 print합니다.
그리고 파일 안의 내용을 읽어오구요.  explode 함수를 사용해서 쉼표 , 를 기준으로 파일 안의 내용을 나눕니다.
_G.onelock 에 첫번째, _G.twolock 에 두번째 내용을 저장합니다.
그리고 파일을 닫습니다. (이 때 저장됩니다.)
만약 파일이 없다면 (이 앱이 처음으로 실행 되는 경우가 됩니다.)
_G.onelock 에 1을 _G.twolock에 0을 넣습니다.

두번째로 onSystemEvent(event)함수를 알아볼까요?
이 함수는 event를 인수로 받기 때문에 어떤 리스너에서 Call하는 걸 겁니다.
밑에 보니까 앱이 최초로 실행 될 때인 Runtime 리스너에서 call하네요.
 Runtime:addEventListener( "system", onSystemEvent )
이 함수 내용을 보면 event.type 이 applicationExit일 경우 그러니까 앱이 종료 될 때 if 문 안에 있는 내용들이 실행 됩니다.
그 내용은 ourdata.txt를 쓰기 가능으로 열고 그 안에 _G.onelock,_G.twolock을 저장하고 파일을 닫습니다.
이 내용은 saveit.lua의 내용과 똑 같네요. 이렇게 중복된 코딩은 그렇제 좋은 방법은 아니죠. 저 같으면 이 내용도 saveit.lua 파일 안에 있는 함수를 call 해서 사용할 것 같습니다.
어쨌든 이 소스코드 분석을 하자면 그렇고.. 압축파일을 열어보시면 그 아래 peach가 직접 주석을 달아서 설명한 부분이 있으니까 한번 읽어 보세요.

그 다음엔 explode(div,str) 함수가 있습니다.
그 내용은 div 가 아무 내용이 없으면 false를 return 하구요.
아니면 pos와 arr을 0과 {} (테이블)로 선언합니다.
그리고 for문을 돌려 arr 테이블에 나누는 기준에 따라 string을 나눠서 저장합니다.
마지막엔 이 arr 테이블을 return합니다.

다음 함수는 init()함수인데요. resumeStart()함수와 런타임 리스너로 onSystemEvent를 call합니다.

그 밑에선 init()함수를 call 하고 있네요.

여기까지만 보면 최초로 init()이 불려지고 그 다음에 resumeStart() 그리고 onSystemEvent 함수가 불려지겠네요.

그 다음은 화면 셋업 부분입니다.
백그라운드 이미지를 표시하고 level1icon 이미지를 표시합니다. 그리고 두 이미지 모두 localGroup에 insert합니다.

그 다음은 gotoone(event)함수인데요. 이건 바로 아래 leveloneicon의 tap리스너에서 call 됩니다. 그 내용은 level1.lua화면으로 넘어 가는겁니다.

다음은 gototwo(event)함수로 내용은 level2.lua 화면으로 넘어가는 건데요. 이 함수는 seticontwo(event) 함수 내에서 call 됩니다.

즉 gotoone 함수는 무조건 실행되고 gototwo함수는 seticontwo 함수에서 일정 조건에 부합되면 실행이 되겠네요.

그러면 seticontwo(event)함수를 살펴보겠습니다.
만약에 _G.twolock-0이 0이면 leveltwoicon이 level2locked.png로 설정이 되구요.
이 변수를 그룹에 insert합니다.
여기서 참고로 왜 -0을 했냐 하면요. 혹시 그 이전에 _G.twolock 변수가 string으로 처리 됐을 경우 == 0 같은 숫자 비교하는 부분이 에러가 날 수 있습니다.
그래서-0 을 해 주면 자동으로 int형으로 바꿔주기 때문에 따로 -0을 하지 않았나 생각되네요.
저도 그런 경험이 있거든요.
그리고 만약에 _G.twolock-0이 1이면 leveltwoicon은 level2icon.png가 되고 이 이미지를 tap할 경우 gototwo 함수가 실행 됩니다.

다음줄은 이 seticontwo()함수를 호출 한 겁니다.

그 다음줄은 director 클래스를 사용하려면 반드시 있어야 하는 부분인데요. localGroup을 return하는 겁니다.

이제 주요 내용은 다 본 겁니다.

level1.lua를 한번 볼까요?
module(..., package.seeall)

function new()
    local localGroup = display.newGroup()

----------------------------------------------------------------------
--                                SCENE SETUP                            --
----------------------------------------------------------------------
local background = display.newImage ("background.png")
localGroup:insert(background)
-- Sets the background

local unlockbutton = display.newImage ("unlock2.png")
unlockbutton.x = 160
unlockbutton.y = 140
localGroup:insert(unlockbutton)
-- Image of unlock button

local lockbutton = display.newImage ("lock2.png")
lockbutton.x = 160
lockbutton.y = 240
localGroup:insert(lockbutton)
-- Image of lock button

----------------------------------------------------------------------
--                            FUNCTIONALITY                            --
----------------------------------------------------------------------

local function onewin (event)
print "Level 2 is now unlocked! :)"
_G.twolock = 1
saveit.save()
director:changeScene("menu")
end
unlockbutton:addEventListener("tap", onewin)

local function onefail (event)
print "Level 2 is now locked! :("
_G.twolock = 0
saveit.save()
director:changeScene("menu")
end
lockbutton:addEventListener("tap", onefail)

----------------------------------------------------------------------
----------------------------------------------------------------------
-- Below is the standard stuff, commented in MENU.LUA
    -- MUST return a display.newGroup()
    return localGroup
end

마찬가지로 첫줄은 모듈로 쓰이기 위해서 필요한 라인이구요. 그 다음 두 줄은 dorector.lua클래스를 사용할 때 반드시 있어야 되는 부분이구요.

다음은 화면 셋업하는 부분입니다.
백그라운드, unlockbutton, lockbutton 세개 이미지를 셋업합니다.

그 다음은 함수들인데요.
onewin(event)함수는 unlockbutton을 tap했을 때 불려지는 함수입니다.
그 내용은 터미널에 "Level 2 is now unlocked! :)" 를 프린트 해 주고 saveit.lua파일에 있는 save()함수를 실행시킵니다. 그리고 menu.lua로 돌아가구요.

두번째 함수는 onefail(event)인데요. 이건 lockbutton 이미지를 tap하면 call되는 함수입니다.
내용은 "Level 2 is now locked! :(" 를 터미널에 프린트 해 주고 _G.twolock을 0으로 해 줍니다. 그 다음 save.save() 함수를 call하고 menu.lua 내용을 화면에 뿌려 줍니다.

다음은 마찬가지로 director.lua 클래스를 사용할 때 있어야 하는 규칙으로 localGroup을 return하구요.

마지막으로 level2.lua를 보시죠.
module(..., package.seeall)
-- Main function - MUST return a display.newGroup()
function new()
    local localGroup = display.newGroup()
----------------------------------------------------------------------
--                                SCENE SETUP                            --
----------------------------------------------------------------------
local background = display.newImage ("background2.png")
localGroup:insert(background)
    return localGroup
end

여기는 특별한 부분 없이 그냥 background 이미지를 출력하는 부분만 있습니다.

이제 게임 중 Level별로 Lock하고 Lock을 해제하고 하는 부분들을 이해하시겠죠?


Lock이 풀리면 맨 마지막에 우리의 Peach 사진을 볼 수가 있네요.
전 얘가 남자인지 여자인지 확실히 모르겠어요. 20대 초반에 시드니에 살고 있다고 하던데..
http://peachpellen.com/about/
하여간 얘가 운영하는 홈페이지가 아래에 있습니다.
http://techority.com/
저하고는 관계가 없지만 얘가 share한 소스코드로 제가 공부를 많이 했고 또 여러분에게도 소개해 드리고 해서 이렇게 소개 드립니다.

이 세상을 경쟁으로 생각하기 보다는 이렇게 서로서로 돕자는 마음으로 하면 더 좋을 것 같아서.. 홈페이지 들어가주고 내용 봐주고 필요하면 이용해 주고 힘 주는 댓글 남겨주고 하는게 우리들이 도움 받은거 은혜 갚는거 같애서... ^^

하여간 여러분들도 즐팅 하세요....
반응형

HTML5 CSS Text shadow, translate 효과 등등

2011. 12. 14. 23:38 | Posted by 솔웅


반응형

지난 시간 사용했던 소스를 그대로 사용하겠습니다.
일단 7th.html 파일을 만들어서 아래 코드를 넣으세요.
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <title> Dougy's HTML5 </title>
    <link rel="stylesheet" href="main04.css">
</head>
<body>
    <div id="box">
        <p id="text"> Text Test. </p>
    </div>
</body>
</html>

그리고 main04.css 파일을 아래와 같이 만드세요.
body{
    text-align:center;
}
#box{
    display:block;
    width:500px;
    margin:50px auto;
    padding:15px;
    text-align:center;
    border:1px solid blue;
    background:orange;
    -webkit-border-radius:25px;
    -webkit-box-shadow:rgb(110,110,110) 10px 10px 10px;
}
#text{
    font:bold 30px Century Gothic;
    text-shadow:rgb(110,110,110) 3px 3px 5px;
}


어제하고 조금 다를거예요. 아래 부분이 추가 됐거든요.
text-shadow:rgb(110,110,110) 3px 3px 5px;

어제는 box에 그림자 효과를 준 것인데 오늘은 텍스트에 그림자 효과를 줬습니다.

이제부터 할 일은 박스에 그라디언트를 줄 겁니다.
    background:orange; 이 부분을 아래처럼 바꿔보세요.
background:-webkit-radial-gradient(center,circle,red 0%,orange 50%);

이 코드는 가운데서부터 원 모양으로 빨강->오렌지까지 그라디언트 효과를 주라는 의미입니다.
red 0%는 빨강색이 시작하자마자 그라디언트가 시작된다는 거구요 오렌지 50%는 50%는 그리디언트가 아니라 완전히 오렌지색이 표시 되도록 하라는 의미입니다.
background:-webkit-linear-gradient(top,black,white)
위 코드도 한번 시도해 보세요. (직접 확인해 보세요. 설명은 생략할께요.)

박스나 텍스트 색을 만들 때 rgb를 사용했습니다. 여기에 투명도까지 조절하고 싶으시면 rgba 를 사용하시면 됩니다.
    -webkit-box-shadow:rgba(110,110,110,.6) 10px 10px 10px;
이 코드를 사용하면 박스의 그림자가 60% 투명해 져서 좀 더 연하게 나올 겁니다.

이제 조금 다른 효과를 볼께요.
우선 html과 css 파일을 새로운걸로 바꾸겠습니다.
html은 8th.html로 해 주시고 7th.html에서 css를 main05.css로 바꿔주세요.
body{
    text-align:center;
}
#box{
    display:block;
    width:500px;
    margin:50px auto;
    padding:15px;
    text-align:center;
    border:7px solid blue;
    background:yellow;
    outline:7px solid red;
}
#text{
    font:bold 30px Century Gothic;
    text-shadow:rgb(110,110,110) 3px 3px 5px;
}


새로운 코드는 outline 입니다. 보시면 border랑 똑 같은데 제목이 outline 으로 합니다.

그러면 border 바깥쪽으로 outline이 그려집니다.


다음은 transform 에 대해 알아 보겠는데요.

-webkit-transform:scale(1.5)

-webkit-transform:scale(1,3)

-webkit-transform:scale(-1.1)

이 3개를 하나하나씩 한번 대입해 보세요.

첫번재는 전체 box 크기가 커질것이고 두번째는 아래위 로만 3배 커질 겁니다. 그리고 3번째는 박스가 오른쪽 왼쪽이 바뀌어질 겁니다. 거울에 비치듯이요. 그러면 글자도 그렇게 나오겠죠?

직접 한번 확인해 보세요.

그리고 아래 코드를 한번 넣어 보세요.

-webkit-transform:skew(30deg);

박스가 옆으로 눕네요. 우리의 bucky (thenewboston.com)는 이 기능은 하등의 쓸모가 없다고 쓰지 말라고 하네요.


다음은 translate에 대해서 알아보겠습니다.

-webkit-transform:translate(150px, 300px); 의 의미는 x방향으로 150픽셀 y방향으로 300 픽셀 움직이라는 의미입니다.

그러면 아래처럼 한번 해 보세요.

-webkit-transform:translate(100px,100px)rotate(30deg) scale(.8);

이 의미는 뭘까요?

x방향으로 100픽셀, y 방향으로 100픽셀 움직이고 30도 회전시키고 크기는 80%로 줄이라는 의미입니다.



위 조건이 모두 적용된 화면입니다.

CSS에서 이런 기능까지 적용이 된다면 간단한 애니매이션 기능도 구현할 수 있지 않겠어요?

웬만한 플래쉬 효과는 줄 수 있을 것 같습니다.


다음 글에서는 애니메이션 효과를 한번 공부해 보도록 할께요.

아주 훌륭한 기능이 여러분들을 기다리고 있습니다. ^^

반응형