Archive for the 'Flash-Tip' Category

Page 2 of 4

How to implement User RectBorder

플래시에서 제공되는 component 들은 종류에 비해 디자인적인 확장성에서 제약이 있기 때문에 많이 사용되지 않고 있다. 물론 나도 특별한 경우를 제외하고는 사용하지 않는 편이다.
나름대로 디자인에 큰 영향이 없다면 제공되는 기본 component 를 사용하지만 간혹가다 뜻하지 않는 문제점에 부딛히게 되면 여간 힘든게 아니다. 많이 사용해 보지 않는 문제점을 해결하는 것이 만만치 않다. 특히 기본 component 를 사용할때 가장 문제가 되는것이 바로 border 처리 문제일것이다.
halo theme 에서 제공되는 border를 쓰자니 디자인에 걸릴때가 참 많이 발생하게 된다.
물론 theme 파일을 수정하여 요소들을 수정할 수 있지만 여간 손이 많이 가는게 아닐 뿐더러 자칫하면 내장 클래스를 건드리게 되어 플래시 전체의 component 의 UI 가 뜻하지 않게 될수도 있다.

이런 저런 문제로 그동안 사용을 극도로 꺼려했지만 이번에 러퍼런스를 보고 가장 손쉽게 border 를 사용자가 맞게 구성하는 방법을 찾아내어 소개해 본다.

기본적인 방법은 내장 component 에서 사용하는  RectBorder 을 편집하여 사용자가 만든 border 를 사용할 수 있게 하는 것이다.

1. 플래시가 설치되어 있는 폴더에서 Class/mx/skins 폴더에 사용자 정의 테두리에 사용할 사용자 정의 패키지 이름으로 새 폴더를 만든다.
ex: C:\Program Files\Macromedia\Flash 8\en\First Run\Classes\mx\skins
2. 이폴더에 RectBorder.as 이름으로 사용자 정의 클래스를 만든다.
3.다음 코드를 삽입한다.

import mx.core.ext.UIObjectExtensions;
class mx.skins.myTheme.RectBorder extends mx.skins.RectBorder {
static var symbolName:String = "RectBorder";
static var symbolOwner:Object = RectBorder;
var className:String = "RectBorder";
#include "../../core/ComponentVersion.as"
// All of these borders have the same size edges, 1 pixel.
var offset:Number = 4;
function init(Void):Void {
super.init();
}
function drawBorder(Void):Void {
// The graphics are on the symbol's timeline,
// so all you need to do here is size the border.
_width = __width;
_height = __height;
}
// Register the class as the RectBorder for all components to use.
static function classConstruct():Boolean {
UIObjectExtensions.Extensions();
_global.styles.rectBorderClass = RectBorder;
_global.skinRegistry["RectBorder"] = true;
return true;
}
static var classConstructed:Boolean = classConstruct();
static var UIObjectExtensionsDependency = UIObjectExtensions;
}

위코드는 사용자 정의 Symbol 을 사용하여 사용자가 정의한  RectBorder을 사용하여 border를 설정하는 것이다.

4. 새로운 Symbol 을 생성한 후  linkage property 에서 아래와 같이 설정한다.
Identifier :  RectBorder
As 2.0 Class : mx.skins.myTheme.RectBorder

5. 조금전에 생성한 RectBorder symbol 을 편집해 원하는 border 를 그린다.
단지 좌표값을 0,0 에 맞추어 속이 빈 사각형 박스를 그리기만 하면 된다.

6. RectBorder를 사용하는 여러 component 요소를 스테이지로 드래그합니다.
예를 들어 List, TextArea 및 TextInput component
7. export movie 를 통해 확인해 보면 자신이 만든 border 사용하여 그려진 것을 볼 수 있다.

이런 방법을 사용하면 전체적으로  borderStyle 에 영향받지 않고 자신이 원하는 border 를 구성할 수 있을 것이다.

How to sort Objects(Class)

sortOn (Array.sortOn method)

public sortOn(fieldName:Object, [options:Object]) : Array

Sorts the elements in an array according to one or more fields in the array. The array should have the following characteristics:

  • The array is an indexed array, not an associative array.
  • Each element of the array holds an object with one or more properties.
  • All of the objects have at least one property in common, the values of which can be used to sort the array. Such a property is called a field.If you pass multiple fieldName parameters, the first field represents the primary sort field, the second represents the next sort field, and so on. Flash sorts according to Unicode values. (ASCII is a subset of Unicode.) If either of the elements being compared does not contain the field that is specified in the fieldName parameter, the field is assumed to be undefined, and the elements are placed consecutively in the sorted array in no particular order.오브젝트를 일반적인 단일속성이 아닌 한개 이상의 여러 속성을 기준으로 정렬할시 사용되는 메서드이다. 오브젝트를 정렬할때 종종 사용하던 방법이였는데 이번 프로젝트를 진행하면서 클래스 자체를 정렬할때 사용해 보았는데 제대로 작동하였다.

    클래스는 당연히 오브젝트의 일종이다. 따라서 클래스 안에 있는 멤버 변수들을 기준으로 정렬이 가능하다는 의미다. 자신이 클래스를 사용하여 이미지 갤러리같은 정렬의 기능이 있는 컨텐츠를 제작할시에 아주 유용한 기능일 것이다.

    // widget class : 정렬에 사용될 클래스

    class com.dstrict.UB.project.ces2007.widget.Widget {
      public var _id:String;
      public var _title:String;
      public var _date:Number;
      public function Widget(id:String,title:String,date:Number) {
      _id=id;
      _title=title;
      _date=date;
    }
    }
    // example code
     
    import com.dstrict.UB.project.ces2007.widget.Widget ;
    var widgetArr:Array=new Array();
    var widget1:Widget=new Widget("vkimone","widget1",20061213);
    var widget2:Widget=new Widget("kimkijeung","widget2",20061110);
    var widget3:Widget=new Widget("Tom","widget3",20061115);
    var widget4:Widget=new Widget("Jane","widget4",20061211);
    widgetArr.push(widget1);
    widgetArr.push(widget2);
    widgetArr.push(widget3);
    widgetArr.push(widget4);
    for(var i=0; i<widgetArr.length ; i++){
    trace(i+"  : "+widgetArr[i]._id+" : "+widgetArr[i]._title+"  ----------->"+widgetArr[i]._date);
     
    trace("======================================");
    widgetArr.sortOn("_date",Array.NUMERIC| Array.DESCENDING);
    for(var i=0; i<widgetArr.length ; i++){
    trace(i+"  : "+widgetArr[i]._id+" : "+widgetArr[i]._title+"  ----------->"+widgetArr[i]._date);
    }

    //result
    0  : vkimone : widget1  ———–>20061213
    1  : kimkijeung : widget2  ———–>20061110
    2  : Tom : widget3  ———–>20061115
    3  : Jane : widget4  ———–>20061211
    ======================================
    0  : vkimone : widget1  ———–>20061213
    1  : Jane : widget4  ———–>20061211
    2  : Tom : widget3  ———–>20061115
    3  : kimkijeung : widget2  ———–>20061110

    각각의 아이디값과 제목 그리고 날짜 정보를 포함하는 widget 클래스에서 여러개의 객체를 생성한후
    배열에 넣은 다음 오브젝트 속성인 _date 를 기준으로 내림차순으로 숫자 정렬했을때의 결과값이다.
    각 클래스 속성을 기준으로 통채로 정렬이 된다.

    만역 클래스를 이용해 철저히 오브젝트들을 캡슐화(encapsulation)했다면 손쉽게 오브젝트 정렬을 사용할 수 있을 것이다.

  • Blink Effect

    작업을 하다가 우연하게 발견한 팁이다.

    전에는 아무생각없이 blink 효과를 구현하려면 그냥 간단하게 모션트윈으로 키프레임 에니메이션을 만들어서 사용하곤했다. 그런데 actionscript 로 blink 효과가 가능했다.

    PropertyTweenEase class 는 이전 포스트에서 새롭게 구현한 방법을 사용했다.

    import mx.transitions.easing.Bounce;
    import com.dstrict.UB.util.transitions.tween.PropertyTweenEase;
     
    function blink(){
    	src_mc._alpha=0;
    	PropertyTweenEase.tween(src_mc,{_alpha:100},Bounce.easeIn,8);
    }
     
    start_btn.onRelease=function(){
    	blink();
    }

    플래시에서 기본으로 내장되어있는 이징 패키지 함수를 이용한 방법으로 Bounce 클래스는 뜻 그대로 뛰어오르는 느낌을 낼 수 있게 해준다.

    따라서 Bounce 클래스에서 증가하는 느낌의 easeIn 함수를 사용하면 손쉽게 번쩍거리는 효과를 만들 수 있다.

    wmode and setInterval

    IE 에서 wmode 를 적용한 swf 파일과 default swf 파일간의 차이점이 있다.
    즉, opaque 또는 transparent 로 설정하고 swf 실행할 경우 발행하는 모든 이벤트 들이 프레임 갱신때 까지 딜레이 된다는 점이다. 다시말해 프레임 속도보다 빨리 실행하지 못한다는 말이다.
    문제가 되는 부분은 프레임 보다 빨리 setInterval 을 사용하여 함수를 실행할때 발생하게 된다.
    flash IDE 에서는 정상적으로 interval 값이 설정되어 호출되지만 wmode 가 설정된 html 파일을 IE 에서 확인할 경우 기존에 설정해 놓은 framerate 보다 빨리 호출되지 않는다. 이것은 IE 의 버그로서 firefox 에서는 발생하지 않는다.

    bug test

    wmode and performance

    • Window: Use the Window value to play a Flash Player movie in its own rectangular window on a web page. This is the default value for wmode and it works the way the classic Flash Player works. This normally provides the fastest animation performance.
    • Opaque: By using the Opaque value you can use JavaScript to move or resize movies that don’t need a transparent background. Opaque mode makes the movie hide everything behind it on the page. Additionally, opaque mode moves elements behind Flash movies (for example, with dynamic HTML) to prevent them from showing through.
    • Transparent: Transparent mode allows the background of the HTML page, or the DHTML layer underneath the Flash movie or layer, to show through all the transparent portions of the movie. This allows you to overlap the movie with other elements of the HTML page. Animation performance might be slower when you use this value.

    wmode 를 그다지 신경쓰지 않고 있던 부분이기 하지만 간과하기에는 너무 큰 performance 차이를 보였다. 실제 전에도 웹에 올리기 전(플래시 플레이어에서 확인했을시) 에는 별 무리 없이 돌아가던 사이트가 웹상에 올리고 나면  framerate 가 떨어지는 느낌을 받았던 적이 많았다.

    이건 정확히 말하자면 웹상에 올려서라기 보단 html 로 사이트를 봤기 때문이란 생각이 든다.

    이전에 포스팅한 글에서 framerate 와 브라우저 간의 관계에서 브라우저 플러그인에서는 과도한 cpu 사용을 막기위한 방법으로 강제로 framerate를 떨어뜨리는 현상을 볼 수 있다.

    그래서 html 페이지에서 플래시 파일을 확인하면 framerate 가 떨어지는 것이다.

    보통 사이트 제작시에는 wmode 를 설정하지 않았다. default 인 window 로 설정한 것이다.

    보통 wmode는 DHTML 을 flash 와 같이 사용하기 위해 설정하는 것으로 알고 있다.

    하지만 wmode 와 performance 와의 상관관계가 상당부분 있는 것 같다.

    대부분의 레퍼런스 문서나 자료에는 wmode 가 window 일때 가장 에니메이션 성능이 좋다고 나온다고 말하고 있지만 실제 테스트 결과 opaque 가 가장 좋은 framerate 를 보였다.

    이부분이 가장 의문시 되었던 점이다. 분명 테스트를 해보고 레퍼런스를 제작했을텐데 왜 이런결과가 나오는 것일까?…레퍼런스에서 나오는 성능은 framerate와는 좀 다른 의미로 쓰인것일까 의문이 들었다.

    하지만 이 의문점은 테스트를 하면서 자연스럽게 해결되었다. opaque 로 설정한후 테스트를하면 이전보다 훨씬 높은 framerate 를 보여준다. 하지만 performance 가 눈에 띄게 올라가게 된다.

    이는 opaque 모드가 배경을 불투명으로 바꾸어 플래시로 하여금 부담을 줄여준 이유도 있겠지만 이 모드를 적용할시에 framerate 를 높인 이유가 클것이다. 하지만 opaque 모드는 framerate 가 높아지는 대신 cpu 사용량이 올라가게 된다.

    사양이 좋은 컴퓨터에서는 큰 무리가 없겠지만 저 사양의 컴퓨터에서의 사용은 어느정도고려해야한댜.

    http://www.communitymx.com/content/article.cfm?cid=E5141&print=true

    Frame rates in the Flash Player

    [퍼온글]
    There have been numerous posts about frame rate issues in Flash over the years, sometimes with quite inconsistent tips and workarounds. As we are approaching the final phase of development for Flash Player 9 at Adobe our bug database is filling up with duplicate bugs concerning old known issues. What is frustrating to designers is that they perceive the Flash Player changing its behavior over the past few releases, although it has not. Well, that might actually be the problem.

    Flash uses a relative timing model, meaning it does not really care about a global frame rate, but will instead try to enforce frame intervals as best as it can. Say you have f.ex. set your frame rate to 30 frames/sec. That means that the Flash Player will try to wait for 33 milliseconds before trying to display the next frame (excluding the time it takes to render the frame). This loose timing causes all kinds of problems. First, the Flash Player depends on high level OS events to deliver timing messages. In the worst case this means the use of WM_TIMER, dependence on the NetScape plugin API or in the best case we use multimedia timers provided by a special Internet Explorer API. Second, we round frame intervals to milliseconds since Windows and MacOS can’t support fractional time intervals. Third, the OS, the browser and the Flash Player will add overhead to the code executed on each frame, meaning that in the end the actual frame rate will sway between -10 to +5 frames/sec from the actual selected frame rate, depending in what environment you play it in. In Flash Player 8 and Flash Player 9 new overhead is originating mostly from the GC, something for which there is no workaround. As I said we do not calculate frame rates on a global basis so we can’t correct it actively.

    Lets talk about maximum frame rates. In Internet Explorer this is 100 frames/sec. Why? Because the minimum time slice Windows timers can provide is 10 milliseconds. What about FireFox? FireFox does not use special timers and made a decision to limit the maximum frame rate for plugins. Why? The thinking is that users constantly complain that plugins take too much CPU time. A valid complaint I think and every designer who puts online ads out there at higher than 8-12 frames/sec and more that 2 or 3% CPU usage should be ashamed. While a single ad will not be a problem, most pages easily serve 2 or 3 ads on a single page.

    The Mozilla team also decided that plugins would get no time when they are on a hidden tab so it would not render the browser unresponsive or less responsive by adding new tabs. So do not be surprised if your SWFs and FLVs do no play on hidden tabs. Apple went even a step further in Safari: If the browser is not active, plugins will only get about 4 frames/sec, mainly to save battery and avoid the dreaded noise of the fans. Try it, go to Google Video, play a video and then switch to another application. The frame rate will drop to about 4 frames/sec. While we could drive our own background thread and work around this, there is a reason they decided to take these steps. We would be ill advised to just hack around it.

    What does this mean? Well, the frame rate you select does not really mean too much and you should not depend on it in a way to be accurate to the millisecond. This especially goes for ANY sort of synchronization. If you need synchronization your only choice is placing code in ActionScript which will ‘correct’ your timing or workarounds like placing a streaming sound on your main time line (In which case we use the audio device to report time correctly to the nanosecond. Due to bugs this does not work correctly on Linux right now, which is the reason audio and video are out of sync, even for FLVs :-( )

    What does the future hold? As I explained in a earlier post we will likely add synchronization primitives into the player to allow SMILE like global timing at some point. But there is also a good chance we’ll limit what users can actually do when it comes to frame rates and overall CPU usage. There are various ways we could enforce low CPU usage. SWF files originating from a different domain (speaking advertisement) could get a lower priority and have a frame rate cap which would be user selectable. Secondly, with the advent of GPU support in the OS there will be a time when we finally add VBL wait, meaning tearing free drawing. In most cases this means the maximum frame rate will be 60 frames/sec. On high CPU load we might actually cut this into half, e.g. 30 frames/sec. OS X already does this in certain conditions.

    firefox 와 safari 에서 유독 flash framerate 가 떨어지는 현상이 있다고 느꼈었는데… 강제로 플러그인에서 막아놓은 결과였다. 무분별한 framerate 의 사용으로 인해 사이트가 느려지고 사용자 컴퓨터가 다운되는 걸 막기 위한 궁여지책이 아닌가 생각든다.
    flash player 9 에서는 framerate 0.1 에서 1000까지 지원한다고 나와있지만 과연 어느정도의 성능을 보여줄지..
    위에서 언급한 내용대로라면 플레이어 근본을 바꾸지 않는다면 힘들다는 생각이 들지만 AS3 을 기반으로 제작한 flash player 9 의 성능은 AVM2 로 전혀 새로운 머신으로 탈바꿈했다고 하니 한번 기대해 볼만하다.
    근데 사운드가 포함된 stream 파일도 200-300 framerate 를 지원할까궁금하다.

    Advanced progressive download

    대부분의 flash video 를 사용할경우 progressive download 방식을 활용하여 용량 큰 무비를 사용할 수 있게 한다.
    하지만 이 방식은 단순히 영상을 플레이하는데 목적이 있을때만 적용가능한 일이다.
    다시말해 비디오자체를 트랜지션(transition) 무비로 사용할 경우 적절하지 못한 방법이다.
    영상을 트랜지션 무비로 사용하려면 로딩타임이 존재하면 안된다.
    flv 파일을 사용하여 progressive download 로 트랜지션 무비를 구현할경우 초기화 타임이 생기게 되어
    약간의 딜레이가 생긴다.(이는 사운드 파일을 포함했을경우 더 큰 영향을 준다.)

    테스트해 본 결과 레퍼런스에는 권장하지 않는 방법이긴 하지만 swf 파일안에 video 파일을 임베드하는 방법이 위의 문제를 가장 잘 해결할수 있는것 같다. 이 방법에는 사운드 싱크에 문제가 있긴 하지만 오디오 파일이 존재하지 않을경우 가장 딜레이 없이 영상을 플레이 할 수 있는 방법이다.

    하지만 사운드가 포함될 경우에는 문제가 있다.
    사운드 싱크의 해결을 위해 stream 으로 설정할 경우 로딩없는 플레이가 적용되지 않는다.
    반드시 20%정도 로딩이 완료되어야지만 그때서 재생이 되는 현상이 발생한다.

    사운드 싱크가 그리 큰 문제가 되지 않는다면 사운드 sync 를 stream 이 아닌 event 로 설정해야 원하는 로딩없는 플레이를 할 수 있다. 물론 사운드의 압축한 상태는 충분히 작은 상태로 만들어야 한다.

    따라서 로딩없는 transition movie 를 구성하기 위해서는 사운드가 없는 비디오파일을 재생할 경우 가장 잘 적용되고 사운드가 포함될 경우에는 사운드 파일의 sync 를 event 로 설정해서 최대한 압축한후 사용해야한다.

    Optimization of the flash site

    가끔 빈 클립에 플래시 파일을 로드해서 사용할 경우 원래 제작한 플래시 파일보다
    framerate 가 현저히 떨어지는 경우가 있다.
    차이점이라면 단지 빈 클립에 로드를 했다는 점…….!!!!!!!!

    결국 이 차이점이 performance 측면에서 엄청난 결과를 가져왔다.
    만약 이런 현상이 본인이 제작한 플래시 컨텐츠에서 발생했다면 반드시 빈클립의 좌표점을 확인해보자…
    빈클립 절대 좌표의 중심점이 원점(0,0)이 아닐경우 플래시 상대좌표 계산으로 연산속도가 떨어지는 현상이 발생한다.
    특히 슬라이딩 범위가 큰 플래시 무비를 제작할경우 더욱 차이가 확연하다.

    BitmapData trouble shooting

    Drawing Method 와 BitmapData 간의 충돌문제

    Drawing Method를 통해 생성한 객체를 마스크 클립으로 활용할때(특히, 동적으로 scroll mask 만들때)
    마스크되어지는 클립안에 Transition 되는 BitmapData 객체가 있을 경우 BitmapData의 외곽선이 Redrawing
    되는 현상이 발생한다. (flash player 에서 다시그리기 생성탭을 클릭했을때와 비슷한 현상)

    따라서 Transition 되는 무비클립을 BitmapData 로 생성한 오브젝트로 마스크를 적용할경우 반드시 마스크 오브젝트는 비트맵이어야한다.

    cacheAsBitmap 속성을 true 로 설정해야함.

    URL Encoding

    escape 함수
    escape(expression:String) : String
    매개 변수를 문자열로 변환하거나 영숫자가 아닌 모든 문자를 % 16진수 시퀀스로 바꾸는
    URL 인코딩 형식으로 인코딩합니다. URL 인코딩 문자열에서 사용되면 퍼센트 부호(%)는
    이스케이프 문자를 시작하는 데 사용되고 이는 모듈러스 연산자(%)와 동일하지 않습니다.

    URL인코딩은 웹에서 흔히 볼수 있는 것으로
    “kimkijeung%20vkimone”를  “kimkijeung%vkimone” 이런식으로 인코딩을 하는 것을 말한다.


    외부 데이터와 연동을 시킬 때는 꼭 사용해야 에러를 막을 수 있다. 반대로 바꿔 주는 함수로는 unescape 가 있다.


    예) a=escape(“김기정”);
        trace(a);


    /* 이 구문을  실행하면 output 창에


    %EA%B9%80%EA%B8%B0%EC%A0%95


    과 같이 나온다. */


    다른 나라 사람의 언어 환경을 고려하지 않는다면 별 해당사항이 없겠다.
    하지만 각 나라마다 고유의 언어 셋이 있어 나라 별로 컴퓨터에서 사용하는 언어가 다르다.
    플래시에서 그냥 static field 를 사용하여 작성한다면 그냥 적은 그대로 보이겠지만
    외부 데이타를 가져 와서 보여 줘야 한다면 반드시 주의할 점이 있다.

    플래시에서의 정보는 유니코드(utf-8) 로 입출력된다. 플래시가 기본적으로 외부 텍스트를 해석할테
    System.useCodePage 값을 true 로 설정하지 않느다면 말이다.

    useCodePage  는 Flash Player가 외부 텍스트 파일을 해석할 때 유니코드를 사용할 것인지 현재 운영 체제의 기존 코드 페이지를 사용할 것인지 여부를 지정하는 부울 값이다
    간혹가다 유니코드로 인코딩 되지 않은 외부데이타를 불러올때 플래시에서 깨져서 보이는 경우가 있다. 이럴때 useCodePage 값을 true 로 설정하면 현재 운영체제에 맞는 코드 페이지를 사용하여 텍스트가  재대로 보이게 된다.

    하지만, System.useCodepage를 true로 설정하는 경우, 현재 운영 체제의 기존 코드 페이지에 외부 텍스트 파일에 사용된 문자가 포함되어 있어야만  텍스트를 표시할 수 있습니다. 예를 들어, 중국
    어 문자가 포함된 외부 텍스트 파일을 로드하는 경우, CP1252 코드 페이지에는 중국어 문자
    가 들어 있지 않기 때문에 이 페이지를 사용하는 시스템에서 이 문자들이 표시되지 않는다.

    모든 운영 체제 사용자가 SWF 파일에 사용된 외부 텍스트 파일을 볼 수 있게 보장하려면 모
    든 외부 텍스트 파일을 유니코드로 인코딩하고 System.useCodepage를 기본값인 false로 설
    정해야 한다.

    하지만 이걸로 모든 문자가 표시되는 것이 아니다. 플래시에서 데이타를 저장하고 그걸 다시 불러올때 이런 방식으로 해도 데이타는 원하는 값을 표시할수 없다.
    반드시 특수문자나 다른 나라 언어를 저장할때는 텍스트 정보를 URL 인코딩 방식으로 변환하여 보내야 한다.

    여기서 escape, 와 unescape 를 사용하면 된다.
    그리고 반드시 URL 인코딩을 사용하려면  System.useCodepage 는 기본값인 false 로 놓아두어야 한다. 그렇지 않으면 각 나라의 운영체제의 코드 체계의 문자들의 바뀌어져 인코딩 되어 다른 결과가 보여질 것이다.