Tag Archives: 액션스크립트

lazylog_minsangk_preview.png

[minsangk.com] 리뉴얼 Season2 완료-

사용자 삽입 이미지

기념으로 스냅샷 한방-



이번 컨셉은 ‘하늘과 바람과 별과 시와 코드와 기타-’ 입니다.
제가 너무도 좋아하는 윤동주님의 유고시집 이름에서 살짝 손을 댔습니다. 하늘에 계신 ‘나의 시인’ 윤동주님, 비록 하늘을 우러러 한 점 부끄럼 없이 살 자신은 없습니다만, 끊임없이 치열하게 살아보겠습니다. 시대처럼 올 아침을 최후까지 기다려 보겠습니다. (그러니 시집 이름 갖다쓴건 용서를 바랍니다. ㅋ)

Tiskin 님의 Adagio 스킨을 변형하여 제작 중이던 adagio_minsangk 스킨으로 수정하려다가 너무도 좋은 스킨을 발견하여 부득이 새로 작업을 들어갔습니다. 이번 리뉴얼의 원본 스킨은 Qwer999 님이 만드신 LazyLog Smoke Version 1.1 입니다. LazyLog 스킨은 세 가지 색상 중 어느 하나 고르기가 너무도 고민일 만큼 멋진 스킨이었는데요, LazyLog_Night 의 색상이 너무너무 마음에 들어 끝까지 고민하다, 결국 원래 하고자 했던 컨셉에 맞추어 Smoke 버젼을 수정하기로 결정했습니다.


수정사항은,

 - 배경 이미지를 연한 녹색 톤으로 (친구들이 고려청자 컨셉이냐고 물었던 그 색, 다시 나왔군요. 제가 좀 좋아하는 색;) Colorize 했습니다. 통 이미지로 되어 있어 작업이 무진장 편리했습니다.

 - 전체적인 폰트를 ‘맑은 고딕’으로 수정했습니다. XP 기본 글꼴부터 VS, 플래시, 플렉스, 드림위버, RadRails, 메모장, Eclipse 모두를 맑은 고딕으로 사용할 만큼 ClearType 적용된 맑은 고딕을 좋아라 합니다. ClearType 설정이 되어 있지 않은 컴퓨터에서는 의도하지 않은 레이아웃이 나올 수 있습니다.

 - 메인 타이틀 로고를 플래시로 수정했습니다. 이전 adagio_minsangk 에서 쓰던 눈송이 (먼지송이로 착각되지만;) 애니메이션은 과감히 버리고 새로 두드렸네요. 따스하고 부드러운 느낌의 날개 애니메이션을 만들고 싶었는데 만들면 만들 수록 거미나 문어 느낌이 나서 여러번 좌절했습니다ㅠ 기회가 된다면 거미씨와 문어씨 애니메이션을 만들어 올려보겠습니다 -_- 어쨌거나 날개 느낌을 살짝 줄이고, Rotation 을 후하게 쓰니 묘하게 마음에 드는 움직임이 나왔네요. 지속적으로 수정이 될 가능성도 있지만 당분간은 올려 놓겠습니다.

 - 개별 포스트 타이틀 (Article Title) 을 플래시로 수정했습니다. 파도 애니메이션은 오늘 처음 시도 해 봤는데, 적용할 수 있는 부분이 많을 듯 하네요. 단순하면서도 멋진 결과가 참 많이 나옵니다. 여기서는 마스크와 Shape Tween 을 활용해 간단히 만들어 봤습니다. (이런 예제가 없더군요; 기회가 된다면 이것도 포스팅 해보겠습니다) 제목값 전달은 flashVars 를 이용했습니다. 나름 원시적-_-인 방법이지만, 이 경우는 가장 효율적인 방법이었지요. 텍스트큐브(, 물론 그 이전에 태터툴즈)와 플래시를 결합하는 여러가지 방법을 고민한 포스트가 있었는데, 당시 그 포스트에선 참 여러가지 복잡한 방법들을 썼었지요. 하지만 요런 간단한 접목엔 굳이 XML 파싱해서 쓰는 불편함을 감수할 필요가 전혀 없습니다.

 ! 플래시 제작은 금방 했으나 Embed 에 훨씬 많은 시간이 걸렸습니다. 스킨 수정할 때는 반드시 텍스트큐브 설정에서 ‘스킨 캐쉬’를 끄고 테스트하세요. 그렇지 않으면 임시 인터넷 파일들을 이잡듯이 뒤져가며 테스팅해야 합니다. (실제로 반나절을 그렇게 했습니다 -_-)

- 그 외 가벼운 몇가지 수정이 있었습니다만, 너무 소소한 것들이고 나름 비밀스런 링크들도 있는지라(ㅋ) 찾아보는 재미를 드리겠습니다. (과연 누가 찾아볼지는 의문, 찾으면 롯데월드 1일 자유이용권- 을 들고 모든 놀이기구를 탈 수 있는 용기를 북돋아 드리겠습니다)


트럭으로 쌓여있는-_- 기능적 업데이트는 차차 해 볼 생각입니다. PHP 로 부벼댈까 했는데 왠지 시간 낭비가 되지 않을까 하는 걱정이 들었거든요. 요즘 배우고 있는 루비온레일스 숙련도 차근차근히 올려 하나하나 테스트 해 보겠습니다.


예정사항은-

 - 카테고리 단위로 애니메이션이 작동하는, creative 한 UI 의 블로그 커버 메뉴
 - 대학생 (특히 공대생) 전용 블로그 스케쥴러
 - 경호와 함께 미적대며-_- 제작 중인 백문백답 위젯
 - 백스페이스 키가 안 먹는 오타 문답
 - 블로그와 동기화 되어 작동하는 포토 갤러리
 - 다양한 재미가 있는 프로필 페이지
 - 세븐데이즈(http://7days.metaschool.org) 의 블로그판 ‘나 자신과의 약속’ 위젯.

등이 있지만, 일단 블로그 스케쥴러가 가장 우선순위가 높습니다. 개강 전에 기본 틀이라도 만들어 써먹어야 할 텐데요. 시간 내에 될지는 잘 모르겠습니다 -.-.-


아무튼 이번 리뉴얼.
이전 리뉴얼에 비해 별다른 잔 기술들이 그다지 많이 들어가지는 않았지만, 느낌상으로 참 마음에 듭니다.
원 제작자인 Qwer999 님께 다시 한번 감사드리고 싶네요.

어쨌거나,
오랜만에 쓰는 경어체 포스팅이로군요 ㅋ

[minsangK.com] 플래시 액션스크립트 XML 로드 (블로그 타이틀 02)


플래시가 서버와 데이터를 주고 받는 방법은 이전 포스트 에서 밝혔다시피 여러가지가 있지만, 여기서 사용된 방법은 플래시 액션스크립트 2.0 의 XML 객체의 load 함수를 이용하는 것이다. 방법자체는 크게 어렵지 않다.
우선 플래시에 정보를 전달해주는 녀석은 이거다.
http://minsangk.com/xmlTest/titleComment.php?mode=xmlOnce

이 녀석은 GET Method 를 통해 전달된 mode 의 값에 따라 구분 작동하는데,

모드 지정을 안 할 경우 입력된 DB 의 데이터를 XML 로 뿌려준다 (모드 미지정)
XML 로 최신 노드 하나만을 뿌려주거나 (xmlOnce 모드)
HTML 의 테이블 태그를 이용해 뿌려주거나 (html 모드)


[#M_XML 로드 코드 (열기)|XML 로드 코드 (닫기)|
(Language : actionscript 2.0)


  1. System.useCodepage = true;


  2.  


  3. myXML = new XML();


  4. myXML.load("http://minsangk.com/xmlTest/titleComment.php?mode=xmlOnce");


  5. myXML.ignoreWhite=true;


  6.  


  7. myXML.onLoad = synchroText;


  8.  


  9. function synchroText(success)


  10. {


  11.  if(success) {


  12.   mcMent.dynamicMent.text = myXML.firstChild.firstChild.firstChild.nodeValue;


  13.   mcDate.dynamicDate.text = myXML.firstChild.firstChild.attributes.date;


  14.  }


  15.  else {


  16.   mcMent.dynamicMent.text = "Comment Load Failed";


  17.   mcDate.dynamicDate.text = "Date Load Failed";


  18.  }


  19. }

_M#]
실제 코드는 눈물이 날 정도로 간단하다.
xml 을 로드하고 로드가 완료되면 뿌려준다- 이게 끝-.-

설명하고 말 것도 없는 단촐한 코드지만 몇가지만 짚자면.

(Language : javascript)


  1. System.useCodepage = true;

이게 없으면 한글 입력을 플래시가 못 알아듣는다.

(Language : javascript)


  1. myXML = new XML();


  2. myXML.load(“http://minsangk.com/xmlTest/titleComment.php?mode=xmlOnce”);


  3. myXML.ignoreWhite=true;

myXML 이라는 객체를 만들고, load 메소드로 XML 을 가져온다.
마지막 줄은 가져온 파일에서 공백을 삭제하라는 구문으로 정확한 XML 노드트리의 작동을 위해 꼭 필요하다.

onLoad 함수는 지정된 주소에서 값을 가져와 로드가 완료되면 (성공이든 실패든) 호출된다. 매개변수로 성공/실패 여부를 알려주는 boolean 변수를 하나 주니까 이걸로 if 문을 구성하면 된다. xml 로 가져온 값은 대강 아래와 같이 나올텐데-

(Language : xml)


  1. <?xml version=“1.0″ encoding=“euc-kr” ?>


  2. <root>


  3.     <comment id=“1″ date=“20071126″>한 줄기 미소를 위해, 나-</comment>


  4. </root>

(Language : javascript)


  1. if(success) {


  2.   mcMent.dynamicMent.text = myXML.firstChild.firstChild.firstChild.nodeValue;


  3.   mcDate.dynamicDate.text = myXML.firstChild.firstChild.attributes.date;


  4.  }


  5.  

여기서 myXML 의 firstChild 는 root
root 의 firstChild 는 comment
comment 의 firstChild.nodeValue 는 ‘한 줄기 미소를 위해, 나-’ 가 된다.

date 값은 comment(myXML.firstChild.firstChild) 의 속성(attribute) 값이므로,
myXML.firstChild.firstChild.attributes.date;

이렇게 구한 값들을 지정된 무비클립-동적텍스트-텍스트에 넣어주면 끝이다.

다음 포스트에선,
입력/수정/삭제를 할 폼에 대해 끄작여보자-.-.-

sinGraph.jpg

[minsangK.com] sin 함수 애니메이션 (블로그 타이틀 01)

[#M_글 들어가기 전에 블로그 관한 잡담 (열기)|글 들어가기 전에 블로그 관한 잡담 (닫기)|
하루 15시간씩 꼬박 앉아 블로그를 만들고 있다.
블로그가 삶의 기록이라면, 요즘 내 삶의 기록은 오로지 블로그 제작 과정이 전부일텐데, 하루 15시간씩 쓰다보니 도무지 포스팅 속도가 제작 속도를 못 따라 간다. 블로그에 자그마한 변화 하나라도 있을 때마다 글을 올려서 관련 포스트를 검색하는 것만으로 이 블로그가 어떻게 만들어졌는지 보여주고자 했었는데. 쉽지 않다. 이렇게 만들어 놓은걸 다음날은 철저하게 부수고 다시 두드리는 일도 심심찮게 있고. 이건 확정이야, 절대 안 바꿔- 이렇게 만들어 놓은 레이아웃도 몇일 지나면 사지를 분해해 재조립하기도 한다.

아무튼 그래서 'about블로그' 카테고리를 포기하고 'HelloWorld' 카테고리에 [minsangK.com] 접두어를 붙이기 시작했다. (사실 이거 고치는 것만 해도 완전 대공사였음, DB 접속해서 ID를 전부 다시 줄맞춰 수정하고 PHP 에서 Description 배열도 수정하고, 등등) 블로그에 관한 내용이 ‘HelloWorld’에 올라온다는 것은 이제 앞으로의 작업들이 대부분 코드와 스크립트로 점철되는 피곤한 작업이라는 뜻이기도-_M#]
타이틀에 들어간 플래시는 액션스크립트 2.0 으로 제작되었다. 메뉴를 플렉스로 만드느라 액션스크립트 3.0 을 머리 아프게 공부하고 있는 터라 그나마 만만하고 자신있는ㅠ 2.0으로 두드려보자- 라는 취지였지만 결과적으로 머리가 좀 아팠다. 플렉스에선 2.0 코드 두드리더니 플래시 가선 3.0 두드리고- 이러고 있다. 2.0은 XML을 불러오는 방식이 3.0과는 또 다르다. 레퍼런스(물론 한글 한글자도 안 들어간)를 뒤적거리며 어쨌든 기어코 완성을 시켰네.

하지만 스크립트의 포인트, 가장 중요한 부분은 Sin 함수를 이용한 눈송이 애니메이션-
이건 이미 예전에 한번 써먹었던 레퍼토리-_-라 두드리는데 큰 어려움은 없었다.
다른 점이 있다면 이건 그냥 수직하강 눈송이가 아니라 Sin 함수를 이용해 돌아간다는 점.

[Flash] http://freinture.mireene.com/test/snowSimulation.swf


이전에 만든 눈송이 애니메이션


[#M_눈송이 구현 코드 (열기)|눈송이 구현 코드 (닫기)|
by AS 2.0


  1. // 눈송이 갯수


  2. amount_of_Circles = 30;


  3.  


  4. // 캔버스 사이즈


  5. canvasWidth=900;


  6. canvasHeight=100;


  7.  


  8. // 크기, 알파 설정 (최소/최대값)


  9. minScale = 5;


  10. maxScale = 10;


  11. minAlpha = 20;


  12. maxAlpha = 50;


  13.  


  14. // 눈송이 생성, 초기화


  15. for(var i=0; i<amount_of_Circles; i++)


  16. {


  17.  this.attachMovie("circle","circle"+i,this.getNextHighestDepth());


  18.  this.initCircle(this["circle"+i]);


  19. }


  20.  


  21. // 눈송이 초기화 함수


  22. function initCircle(_mc:MovieClip)


  23. {


  24.  mc = _mc;


  25.  mc._x = random(_root.canvasWidth)-200;


  26.  mc._y = random(_root.canvasHeight);


  27.  mc._width = mc._height = random(_root.maxScale-_root.minScale) + _root.minScale;


  28.  mc._alpha = random(_root.maxAlpha-_root.minAlpha) + _root.minAlpha;


  29.  mc.xSpeed = random(3) + 1;


  30. }


  31.  


  32. // 눈송이 위치 이동 (onEnterFrame)


  33. this.onEnterFrame = function()


  34. {


  35.  for(i=0; i<amount_of_Circles; i++)


  36.  {


  37.   this["circle"+i]._x += this["circle"+i].xSpeed;


  38.   this["circle"+i]._y += Math.sin(this["circle"+i]._x/50);


  39.   //  this["circle"+i]._y = Math.sin(this["circle"+i]._x/30)*(canvasHeight/2)+canvasHeight/2;


  40.  


  41.   // 눈송이가 바깥으로 나갈 경우


  42.   if ( this["circle"+i]._x > canvasWidth ) {


  43.    initCircle(this["circle"+i]);


  44.   }


  45.  }


  46. }

_M#]
장황하게 써놨지만 실제로 중요한건 딱 두 줄이다. 이거-

(Language : javascript)


  1. this["circle"+i]._x += this["circle"+i].xSpeed;


  2. this["circle"+i]._y += Math.sin(this["circle"+i]._x/50);

x 값은 랜덤으로 지정된대로  오른쪽으로 달려간다.
y 값은 현재 x 값에 50을 나눠서 sin 함수에 넣고, 나온 결과값.
이해가 가지 않는다고? 음, 동감이야. 하지만 어렵게 이해하고 두드렸으니 잠깐 설명하자면-

일단 고등학교 수학시간으로 돌아가자. 그리 어려울 것도 없으니 겁먹지 말고.
sin( 0 ) 은 0 이고, sin( Math.PI / 2 ) 은 1 이다.
플래시의 sin 함수도 역시 라디안 값으로 동작하니까 고등학교 수학 시간하고 똑같이 생각하면 된다.
잠깐 여기서 90도(Math.PI/2) 가 넘어가면 어떻게 되는가? 그래프를 떠올려보자.

사용자 삽입 이미지그렇다 정점을 친 값은 떨어진다, 그리고 270도가 되면 마이너스값으로 바닥을 친뒤 한바퀴를 돌면 다시 제자리로 온다.
여기서 우리가 원하는 값은 한 프레임당 움직여야 할 y 값-
아, 갑자기 머리가 아파온다. 이거 구하려면 미적분이 다 나와야 할 것 같은 분위기다.

하지만 중요한건 방향성이다. 굳이 값을 알아내서 뭐하겠다는거냐.
우리가 원하는건 단지 y 값이 x 값의 증가값에 따라 출렁거려주기만 하면 되는거니까.
x 값은 선형증가하고 있으니 단지 그 증가하고 있는 값을 적당한 숫자의 나누기를 통해 작은수로 줄여주는 것이다.

왜 이렇게 마구리스러운 방법을 썼냐면 나도 할 말이 있다.

[Flash] http://www.minsangk.com/tt/attachment/1294582858.swf


 

위의 움직임은 아래와 같은 식으로 작성되었다. (나머지는 거의 비슷하다고 보면 된다)
(Language : javascript)
this["circle"+i]._y = Math.sin(this["circle"+i]._x/30)*(canvasHeight/2)+canvasHeight/2;

식이 좀 복잡해 보이지만 한가지 외엔 큰 차이가 없다. 바로
[ += 대신 = 이 사용되었다는것 ]
증가값을 조절하는게 아니라 _y 값을 직접 조정하는 것이다.

이 경우 진폭을 조절하긴 쉽다.
싸인함수 결과값은 어쩌니저쩌니 해도 결국 -1 부터 1 사이의 값이고, 여기에 50 을 곱하면 -50 부터 50 사이의 값이 된다. 여기에 다시 50을 더해주면 y 값은 0부터 100 까지의 범위를 넘지 않게 되는 것.

다만 위와 같이 너무도 정형화된, 이건 도무지 고등학교때 수학 선생님한테 얻어맞던 기억이 떠올라 등골이 싸해지는 애니메이션이 될 수 밖에 없는거다. 뭐, 여기서도 진폭과 x 의 시작 위치를 랜덤값으로 둘 경우 고등학교 수학 선생님이야 떠오르지 않겠지만, 현재 블로그의 타이틀처럼 도저히 싸인 곡선이라고는 믿을 수 없는 자연스러움을 구현하기엔 많은 애로사항이 꽃핀다.

블로그 타이틀 01 은 여기까지 끝내고, 다음은 02번-
플래시 액션스크립트 2.0 으로 구현하는 XML 로드다-

[FRDB Project] 03 – view.php 와 플래시 액션스크립트

그간 이래저래 공연도 끼어있고 해서 1,2번 포스트가 올라오던 시점에 비해 업데이트가 늦어졌다.
하지만 시간의 간극이 워낙 크다보니, 그 사이에 놀고 있지만은 않았다는 사실을 증명하듯.
의외로 꽤나 많은 부분에서 진척이 이루어졌다.

대망의 디자인 업데이트 된 페이지뷰가 등장하기 전에 몇가지 업데이트 사항을 기록하고자 한다.

1. menu.swf

[Flash] /attachment/1313033471.swf



- 별다른 설명이 필요 없는. 언제나 레이아웃 상단에 위치할 메인메뉴 네비게이션

* 동그라미에서 막대가 되는 애니메이션은 프레임을 이용했고, 각각의 메뉴가 독립적으로 동작하는 부분은 액션스크립트를 통한 프레임 액션 함수- MovieClip.prevFrame() MovieClip.nextFrame() -들을 이용하여 구현
* 동그라미에서 막대로 변하는 심볼은 하나지만, 각각에 대응하는 메뉴이름들은 전부 각각의 이름(접미어 _m) 으로 개별 등록되어 있고 액션스크립트를 통해 동적으로 등록- MovieClip.attachMovie() 후 일괄적으로 위치 배치 & 회전
* 동적으로 등록된 각각의 메뉴이름들은 재생된 프레임 비율을 계산하여, 등록된 Color 객체의 setRGB 메소드를 통해 밝기 변경
* 무비클립의 Tint 속성을 통해 개별 메뉴의 색 구분
* 각각의 메뉴에 대응하는 링크/타겟 배열을 두어 링크 관리를 용이하게 구현

※ 각각의 메뉴 무비클립 : menu01 ~ menu16 / 메뉴이름 동적연결 이름 (linkage name) menu01_m ~ menu16_m
[#M_menu.swf 액션스크립트 소스 - level0 (열기)|menu.swf 액션스크립트 소스 - level0 (닫기)|

(Language : javascript)


  1. // 본 파일은 소스코드 작성당시 파일이라 링크는 정확하지 않음


  2. var linkArray = new Array(


  3.       "http://minsangk.com/kid/test/02.html",


  4.       "http://minsangk.com/kid/test/03.html",


  5.       "http://minsangk.com/kid/test/04.html",


  6.       "http://naver.com",


  7.       "http://naver.com",


  8.       "http://naver.com",


  9.       "http://naver.com",


  10.       "http://minsangk.com/kid/test/08.html",


  11.       "http://minsangk.com/kid/test/10.html",


  12.       "http://pds6.egloos.com/pds/200711/08/03/12.bord2.html",


  13.       "http://pds7.egloos.com/pds/200711/08/03/11.bord1.html",


  14.       "http://minsangk.com/kid/test/09.html",


  15.       "http://pds7.egloos.com/pds/200711/08/03/13.bord3.html",


  16.       "http://pds7.egloos.com/pds/200711/08/03/14.bord5.html",


  17.       "http://cafe.naver.com/frdb",


  18.       "http://cafe.daum.net/kicha"


  19.       );


  20.  


  21. var targetArray = new Array(


  22.       "_self",


  23.       "_self",


  24.       "_self",


  25.       "_self",


  26.       "_self",


  27.       "_self",


  28.       "_self",


  29.       "_self",


  30.       "_self",


  31.       "_self",


  32.       "_self",


  33.       "_self",


  34.       "_self",


  35.       "_self",


  36.       "_blank",


  37.       "_blank"


  38.       );


  39.  


  40. headerTitle.onRelease = function()


  41. {


  42.  getURL("http://minsangk.com/kid/test/01.main(1).htm","_self");


  43. }


_M#]
[#M_menu.swf 액션스크립트 소스 - button_proto (열기)|menu.swf 액션스크립트 소스 - button_proto (닫기)|
(Language : javascript)


  1. stop();


  2.  


  3. // 최초 1회 실행


  4. if (count == undefined) {


  5.  // 각각의 메뉴 이름 동적으로 등록


  6.  this.attachMovie(this._name + "_m", this._name + "_m", this.getNextHighestDepth());


  7.  


  8.  // 등록된 메뉴 이름 무비클립의 재배치 / 회전


  9.  menuName = this[this._name + "_m"];


  10.  menuName._x = 9;


  11.  menuName._y = 54;


  12.  menuName._rotation = -49.5;


  13.  


  14.  count=1;


  15. }


  16.  


  17. // 메뉴 이름의 Color 객체 생성


  18. menuName_color = new Color(menuName);


  19. menuName_color.setRGB(0×000000);


  20.  


  21. // 롤오버-아웃시 rollover 변수의 값 토글


  22. this.onRollOver = function()


  23. {


  24.  rollover = true;


  25. }


  26.  


  27. this.onRollOut = function()


  28. {


  29.  rollover = false;


  30. }


  31.  


  32. this.onEnterFrame = function()


  33. {


  34.  if (rollover)


  35.  {


  36.   // 현재 프레임이 최종 프레임이 아니면 순방향 재생


  37.   if (this._currentframe != this._totalframes) {


  38.    this.nextFrame();


  39.   }


  40.   // 재생이 종료 되었을 경우 stop


  41.   else {


  42.    stop();


  43.   }


  44.  }


  45.  // 이외의 경우 역방향 재생


  46.  else


  47.  {


  48.   this.prevFrame();


  49.  }


  50.  


  51.  // 재생된 프레임 비율을 계산하여 setRGB 매개변수 포맷으로 변환


  52.  color_int = int ( (this._currentframe-1) / (this._totalframes-1) * 255 );


  53.  color_0x = “0x” + color_int.toString(16) + color_int.toString(16) + color_int.toString(16);


  54.  


  55.  // 메뉴 이름에 링크되어 생성된 Color 객체에 색 지정


  56.  menuName_color.setRGB(color_0x);


  57. }


  58.  


  59. // 클릭 시 해당되는 주소/타겟 으로 링크


  60. this.onRelease = function()


  61. {


  62.  linkIndex = Number(this._name.substr(4,2)) -1;


  63.  getURL(_root.linkArray[linkIndex],_root.targetArray[linkIndex]);


  64. }

_M#]
후배님이 디자인한 내용을 초안으로 최대한 노가다 작업을 아껴보고자 액션스크립트를 사용했다. 동적으로 연결되는 메뉴이름 무비클립들의 밝기를 일괄조정 하는 작업에서, 과도한 시스템 자원 낭비를 방지하기 위해  colorTransform 클래스를 안 쓰고 오로지 Color 객체의 setRGB 메소드만 사용했다. 왜 액션스크립트에는 변수를 포맷팅해서 출력해주는 함수가 없는가-_- 찾다찾다 gg치고 그냥 내가 하려하다보니 좀 난잡한 코드를 만든 감이 없잖아 많은듯-_- 어쨌든 구현에는 성공했다. 프레임 액션은 이것말고도 참 여러모로 쓸모가 많은 코드인듯 싶네. 여기 말고도 현재 제작중인 플라곤 홈페이지의 메인메뉴 네비게이션도 똑같은 방식으로 구현되어 있다. 그것도 그렇고 여기 이 녀석도 그렇고 어쨌든 메뉴 네비의 첫 구상을 내가 하지 않은 경우, 액션스크립트를 통해 자연스러운 애니메이션을 구현하다보면 결국 결론은 프레임 액션으로 귀결되는 것 같다. AS1.0 시절의 노가다성 프레임질에 AS2.0 을 통한 고급스러운 뒷마무리- 라는 느낌을 주는 기술. 어쨌거나 좀 더 화려하고 직관적인, 그러면서도 시스템 효율을 최대한으로 이끌어내는데에 참 유용한 기술인 것만은 분명하다. (다만 구현이 그렇다는 것이고, 구현 후에 수정하려면 여러모로 귀찮아진다는 것 때문에 본인은 별로 선호하지 않을뿐)


2. view.php

http://minsangk.com/frdb/view.php
- idx 파라미터를 넘겨받아 지정된 자료를 테이블로 출력하는 파일

* 구성된 레이아웃대로 각각의 필드를 출력
* 사업상황(state 필드) 의 내용에 따라 1:1 대응되는 신호등 이미지 출력
* 관련노선(linkingIDX 필드) 의 내용을 구분자(|)를 기준으로 explode 하고, 해당 idx 의 노선명을 쿼리 전송받아 각각의 링크를 가진 문자열로 출력
* 목록으로 되돌아가는 버튼 폼
* list.php 코드에 해당 인덱스를 매개변수로 하여 view.php 를 호출하는 하이퍼링크를 추가
 - <a href=”./view.php?idx=??”>

이건 후배님이 하고 있는 페이지 디자인의 초안이 나오면 들어가려고 계획된 것이었는데, 후배님의 PPT 발표 예정 상황과 겹쳐 하루만에 초고속 날림-_- 제작되었다. (그런데 중요한건 PPT 발표가 미뤄져서 이 녀석은 아직 미공개 상태라는거) 다른 페이지와 마찬가지로 CSS 가 눈꼽만큼만 사용된 극도의-_- 코드위주 페이지이지만 어쨌든 계획된 내용에서 필요한 부분으로 체크된 내용은 전부 구현되었다고 보아도 좋다. 관련자료 필드 추가가 이뤄지면 또 한번의 코드 수정은 불가피하겠지만, 그 외의 부분은 (디자인을 제외하고) 거의 완성 단계다.

워낙 오랜만에 다시 손 댄 PHP 코드라 내가 짜놓은 녀석들이 낯설어 보여 약간의 고생은 했지만, 요즘 과외 때문에 비슷한 구성과 색다른 문법을 지닌 JSP 를 공부하고 있는것이 나름의 상승 작용을 한 것 같은 느낌이다. PHP 코딩능력이 한결 좋아져서 이제 50라인 정도는 그냥 머릿속에 생각한 대로 옮기면 불필요한 중간 확인 과정을 거칠 필요 없이 작성이 가능해졌다.


3. 지역별분류.swf

[Flash] /attachment/1170838957.swf


- 입력된 DB 를 지역분류별로 출력하는 링크 네비게이션

* 각각의 조각지도를 롤오버 하면 최대 알파치로 진해지고, 롤아웃하면 다음 롤오버 액션에 상관없이 부드럽게 최소 알파치로 변경
X 각각의 조각지도에 대응하는 리스트 출력
(list.php 에서 각각의 상황에 맞는 vMode 추가가 이뤄지는대로 링크 예정)

※ 각각의 조각 지도 무비클립 : sub1 ~sub7

[#M_지역별분류.swf 액션스크립트 소스 - level0 (열기)|지역별분류.swf 액션스크립트 소스 - level0 (닫기)|
(Language : javascript)


  1. // sub (조각지도) 의 갯수


  2. AmountOf_sub = 7;


  3.  


  4. // 특정 링크 선택 변수(roll), 알파 변화 가속도(acc), 최대 알파치(maxAlpha), 최소 알파치(minAlpha) 초기화


  5. roll = 0;


  6. acc = 0.1;


  7. maxAlpha = 100;


  8. minAlpha = 40;


  9.  


  10. // 각각의 sub 가  롤오버되면 roll 변수에 sub 의 인덱스 저장


  11. for(var i =1; i<=AmountOf_sub; i++)


  12. {


  13.  this["sub"+i].onRollOver = function()


  14.  {


  15.   roll = substring(this._name,4,1);


  16.  }


  17.  this["sub"+i].onRollOut = function()


  18.  {


  19.   roll = 0;


  20.  }


  21. // 각각의 sub 를 최소 알파치로 초기화


  22.  this["sub"+i]._alpha = minAlpha;


  23. }


  24.  


  25. this.onEnterFrame = function()


  26. {


  27. // 선택된 sub 는 최대 알파치로 가속, 나머지 sub 는 최소 알파치로 가속


  28.  for(var i =1; i<=AmountOf_sub; i++)


  29.  {


  30.   if(i == roll) {


  31.    this["sub"+i]._alpha += (maxAlpha – this["sub"+i]._alpha)*acc;


  32.   }


  33.   else {


  34.    this["sub"+i]._alpha += (minAlpha – this["sub"+i]._alpha)*acc;


  35.   }


  36.  }


  37. }


_M#]
지도의 출처는 아마도 네이버가 아닐까 싶은데- 후배님이 손수 비트맵 파일을 따서 각각의 조각지도를 PNG 로 저장했고. 나는 그 파일을 받아 Magic Wand 툴로 투명 부분의 Shape 를 삭제해 심볼화했다. 군대 행정반에서부터 시작된 액션스크립트 2.0 공부는 사실상 이러한 스타일의 부드러운 메뉴 네비게이션을 구현하기 위해서 였다고 해도 과언이 아닐 거다. 이제는 그 코드 구현이 어느 정도 머릿속에 확고히 자리 잡아 어떠한 형식이라도 가장 간결한 형태로 코딩하는 방법을 찾았고. 위 코드는 대략 그 모든 조건이 최적화 되어 있다. 이 블로그에 구현될 메뉴 네비도 대략적으로는 이런 형식에서 크게 벗어나지 않는 형태가 될 듯. 문제는 노력과 시간. 일단 머릿속에 대강의 디자인과 구성이 들어가 있으니, FRDB 프로젝트가 끝나는대로 작업 시작이다-.-.- 그때쯤이면 넘치도록 뛰어난 후배님의 디자인 센스를 마구마구 부려먹는거다. 하하-.-.-


4. 수도권노선도.swf

 

[Flash] /attachment/1118899035.swf


- FRDB 에 DB화 되어 등록된 자료 중 수도권 분류 노선들과 1:1 매칭되는 수도권 노선도 플래시 파일

* 어느 위치에서나 토글(toggle) 방식으로 이동과 정지가 가능
* 화면 중앙을 중심으로 좌우상하 이동 폭에 따라 노선 이미지의 상하좌우 검색이 가능
* 노선 이미지의 경계선을 인식하여 유효범위가 오버플로우 되지 않음
* 등록된 노선을 오버마우스 하면 블러 필터를 통해 하이라이트 됨
* 등록된 노선을 배열로 관리하여 삽입, 수정, 삭제가 용이하게 구성
(위 파일은 현재 인천지하철 3개 노선만 등록되어 있음)
X 로드 매개변수로(GET Method) idx 를 입력받아 특정 노선을 하이라이트 시키고 그 위치로 전체 노선도를 위치시킴
(이건 조만간에 구현 예정 -_-_-)

※ 전체 노선도 무비클립 : mc_all / 각각의 노선 무비클립 : mc_all.sub?? (물음표 자리에 해당 노선의 idx)


[#M_수도권노선도 swf 액션스크립트 소스 - level0 (열기)|수도권노선도 swf 액션스크립트 소스 - level0 (닫기)|
(Language : javascript)


  1. // 노선도 이미지 전체 사이즈


  2. allWidth = 3100;


  3. allHeight = 2311;


  4.  


  5.  


  6. // 노선도 이미지 전체 사이즈


  7. allWidth = 3100;


  8. allHeight = 2311;


  9.  


  10. // 캔버스 전체 사이즈


  11. canvasWidth = 930;


  12. canvasHeight = 693;


  13.  


  14. // 이동 가속도, 이동/정지 모드 초기화


  15. acc = -0.05;


  16. _root.moveMode = false;


  17.  


  18. if(idx) {


  19. // idx 관련 구현 소스 들어갈 자리


  20. }


  21.  


  22. // 이동/정지 모드 토글


  23. mc_all.all.onRelease = function() {


  24.  if(_root.moveMode) {


  25.   _root.moveMode = false;


  26.  }


  27.  else {


  28.   _root.moveMode = true;


  29.  }


  30. }


  31.  


  32. this.onEnterFrame = function()


  33. {


  34. // 이동 모드일 때-


  35.  if (_root.moveMode == true) {


  36. // 화면 중앙을 중심으로 노선도의 좌우 이동


  37.   scrollStepX = (_root._xmouse - canvasWidth/2) *acc;


  38.   scrollStepY = (_root._ymouse - canvasHeight/2) *acc;


  39.  


  40. // 이미지 오버플로우 방지 if문


  41.   if(mc_all._x+scrollStepX >= canvasWidth-allWidth && mc_all._x+scrollStepX <= 0) {


  42.    mc_all._x += scrollStepX;


  43.   }


  44.   if(mc_all._y+scrollStepY >= canvasHeight-allHeight && mc_all._y+scrollStepY <= 0) {


  45.    mc_all._y += scrollStepY;


  46.   }


  47.  }


  48. }


  49.  


  50. // 블러 필터 클래스 import


  51. import flash.filters.BlurFilter;


  52.  


  53. // 관련 노선의 idx 를 배열로 등록


  54. var subListArray = new Array ( "93","95","96");


  55.  


  56. // 블러 필터 객체 생성


  57. var blur:BlurFilter = new BlurFilter(4,4,3);


  58.  


  59. // 관련 노선 필터 적용 (적용된 상태에서 알파값으로 하이라이트/노멀 상태 변경)


  60. for(var i in subListArray)


  61. {


  62.  this["sub"+subListArray[i]]._alpha=0;


  63.  this["sub"+subListArray[i]].filters=[blur];


  64.  


  65.  this["sub"+subListArray[i]].onRollOver = function()


  66.  {


  67.   this._alpha = 80;


  68.  }


  69.  


  70.  this["sub"+subListArray[i]].onRollOut = function()


  71.  {


  72.   this._alpha = 0;


  73.  }


  74. }

_M#]
후배님 수업시간에 누군가의 한마디 때문에 만들어야만 했던 녀석. 아마 그 학생은 이게 얼마나 힘든 작업인지 자기가 말하면서도 몰랐을 거다, 젠장 -_- 그 덕에 후배님의 피를 깎는 노가다와 본인의 머리털을 쥐어뜯는 노력이 만나 완성되었다. 지역별분류.swf 와 마찬가지로 후배님이 저 수많은 노선들을 손수 하나하나 포토샵으로 따서 PNG 로 저장해주었고, 나는 다시 그걸 Magic Wand 로 손보아 각각의 idx로 심볼화. 일단은 스크립트부터 완성시키느라 인천지하철 3개 노선 외에 나머지는 파일은 있으나 등록되어 있지 않은 상태. 지역별분류.swf 보다 몇배는 더 고심하고 고민하고 삽질해야 했던 스크립트였다. 이제 수십개의 관련 노선들을 추가하고 그 노선에 대응하는 idx 를 찾아 링크하고 각각의 노선 색깔에 맞는 하이라이트 컬러를 조정하고 등등의 노가다성 작업만 넘치도록 남았구나. 아아-_-_-



다음 FRDB Project 포스트는 이전 포스트에서 예고한 바와 같이 후배님이 제작중인 페이지 디자인을 중점적으로 소개해 보겠다. 아직은 이것저것 손 볼 것이 좀 많아 매 수업시간마다 있는 발표 과제 위주로 구성을 하다보니 전체적인 페이지 디자인의 윤곽이 흐릿해진 감이 있지만. PHP 코드 부분이나 중간중간 페이지를 빛내주는(ㅋ;) 플래시 액션스크립트가 어느 정도 궤도에 올랐으니, 조만간 페이지 디자인도 깔끔하게 이 무대에서 데뷔할 날이 올 것이다.


그런데,
소주 두어병 먹고 들어온 상태에서 내가 이런 포스트를 두드리게 될 줄 몰랐다. 요 아래 포스트는 우울해 죽을려고 하더니, 이렇게 신나게 이런 얘기를 떠들고 있는 것 보면. 나 그런대로 체질상 이게 맞는 거 같기도 하고. 에이, 모르겠네. 그냥 하는동안은 참 재밌었고, 해놓고 보니 꽤나 뿌듯하고. 두드리는대로 즉각적으로 결과가 튀어나오는 웹프로그래밍과 액션스크립트는 어쨌거나 참 매력 있는 녀석.

감당할 수 있는만큼만 최선을 다하면 그것도 참 열심히 사는 한 방법인데, 왠지 나란 인간은 그래서는 만족을 잘 못해버린다. 그래서 몰아놨다가 가끔 한번씩 스스로를 확 옥죄어버리면 늘 감당할 수 없을만큼 최선을 다해버리고 마는거다.

아, 참, 인생 좀 피곤하게 살아, 나도.