BLOG main image
Category (342)
MySpace (89)
Astronomy (50)
Development (178)
Drum (25)
linux에서 subversion설정
누리에 없을 자그마한 자국
살라딘의 생각
saladin's me2DAY
3D Avata - BuddyPoke
기찬 개발이야기
[FLEX] ANT로 ASDOC 사용하기
THLIFE.net
Flash10 대응 Textcube 1.7.5.1..
텍스트큐브 공지사항
«   2008년 11월   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
325734 Visitors up to today!
Today 234 hit, Yesterday 963 hit
/Development/Flex/AIR 관련글 보기 2007년 08월 08일 23시 53분
사용자 삽입 이미지

Flex에서 Button(mx.controls.Button)을 다루다 보면 버튼을 임의의 각도로 회전시키고 싶은 경우가 있다. ( 굳이 Button뿐 아니라 Label, TextField와 같은 컴포넌트도 모두 마찬가지이다.)
하지만 Button의 속성값인 rotation이 0이 아닌 순간 버튼안에 글자가 사라져버린다.
영어든, 한글이든 마찬가지이다. 버튼은 내부적으로 글자를 UITextField를 addChild해서 사용하는데...
회전만 했다하면 UITextField에 label 글자 내용은 있으나 View상에서는 사라진다.

의외로 이러한 부분에 많이 어려워하시는 분들이 계셔서 도와드리는 차원에서 간단하게 컴포넌트를 만들었다.
사실 나도 Flex를 초반에 공부할 때, 이것때문에 꽤나 고생한 기억이 있다. ^^;

이 문제를 해결하기 위해서 크게 2가지 해결방법이 있다.

  1. 실제 폰트를 Embed 하는 방법 (SWF용량이 늘어나는 단점이 있음)
    나는 예전에 관련 글을 작성했었다.
    http://blog.jidolstar.com/101 를 참고한다.

  2. Bitmap 을 이용하는 방법(Bitmap이라 회전하면 약간 일그러지는 단점 있음)

여기서 언급하는 방법은 바로 bitmap을 이용하는 방법이다.
아래는 실행 결과이다.

기본적으로 Button을 상속받아 사용했고 label과 rotation을 override시켜서 기능을 확장했다.
확장된 함수는 label과 rotation값이 바뀔 때마다 rotation된 label Bitmap을 만들어준다.

상속받은 Class는 RotationButton이라고 명명했다.


RotationButton.as (Language : java)
package
{
    import mx.controls.Button;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.AntiAliasType;
    import flash.text.TextFormat;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import mx.core.UITextField;
    import mx.events.FlexEvent;
    import flash.events.MouseEvent;

    public class RotationButton extends Button
    {
        public function RotationButton()
        {
            super();
            this.addEventListener( FlexEvent.CREATION_COMPLETE, onInit );
        }
       
        private function onInit( event:FlexEvent ):void
        {
            this.label = super.label;
        }
       
        override public function set label(value:String):void
        {
            super.label = value;
            setRotationLabel();
        }
       
        override public function set rotation(value:Number):void
        {
            super.rotation = value;
            setRotationLabel();
        }
       
        private function setRotationLabel():void
        {
            var tf:UITextField = super.textField;
            if( null == tf ) return;

            var bmp:Bitmap;
            bmp = Bitmap( this.getChildByName( "bitmapLabel" ) );
            if( null != bmp)
            {
                bmp.bitmapData.dispose();
                this.removeChild( bmp );
            }         
            var bmpData:BitmapData = new BitmapData( tf.width, tf.height, true, 0x00CCCCCC );
            bmpData.draw( tf );
           
            bmp = new Bitmap( bmpData, "auto", false );
            bmp.smoothing = true;
            bmp.name = "bitmapLabel";
            bmp.x = this.width/2 - tf.width/2;
            bmp.y = this.height/2 - tf.height/2;
            this.addChild( bmp );
        }
    }
}



아래 소스는 RotationButton을 활용한 예제이다.


RotationButtonTest.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*" creationComplete="startTimer()">
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.utils.Timer;
            import flash.events.TimerEvent;

            public var r1:int = 0;
            public var r2:int = 50;
            public function startTimer():void
            {
                var timer:Timer = new Timer( 300, 0 );
                timer.delay = 100;
                timer.start();
                timer.addEventListener( TimerEvent.TIMER, onTick );
            }
           
            private function onTick( event:TimerEvent ):void
            {
                r1 += 4;
                r2 -= 6;
                if( r1 >= 360 ) r1 = 0;
                else if( r1 < 0) r1 = 359;
                if( r2 >= 360 ) r2 = 0;
                else if( r2 < 0) r2 = 359;
                rotationButton1.rotation = r1;
                rotationButton2.rotation = r2;
            }
        ]]>

    </mx:Script>
    <local:RotationButton id="rotationButton1"
        width="121" height="42" x="54.5" y="67"
        label="Hello Flex" 
        rotation="0"
        color="#ff0000" fontSize="12" fontFamily="굴림"
        click="mx.controls.Alert.show('1번 누름')"/>

    <local:RotationButton id="rotationButton2"
        width="121" height="42" x="100.5" y="175"
        label="안녕~ 플렉스"
        rotation="0" color="#ff00ff" fontSize="14" fontFamily="궁서"
        click="mx.controls.Alert.show('2번 누름')"/>

    <local:RotationButton id="rotationButton3"
        width="175" height="42" x="265" y="49"
        label="버튼에 마우스 올리면  이상해"
        rotation="355" color="#0000ff" fontSize="11" fontFamily="돋움"
        click="mx.controls.Alert.show('3번 누름')"/>

    <local:RotationButton id="rotationButton4"
        width="175" height="42" x="285" y="154"
        label="회전 0도"
        rotation="0" color="#0ffff" fontSize="12" fontFamily="돋움"
        click="mx.controls.Alert.show('3번 누름')"/>

</mx:Application>
 


회전이 된 버튼에 마우스가 올라가면 글자가 흐릿해지는데 왜 그런지는 아직 알 수 없었다.
혹시라도 이유를 안다면 함께 공유했으면 한다.

위의 예시처럼 버튼을 상속받지 않고 나만의 버튼을 하나 만들어 보는 것은 어떨까? Button도 어짜피 UIComponent를 상속받은 것이니 말이다.

한가지 더 언급할 것은 많은 수의 Sprite나 UIComponent가 Flex위에 동적으로 움직인다면 CPU부하가 심해진다. 만약 Sprite나 UIComponent와 같은 DisplayObject들이 함께 움직이는 경우라면 위와 같은 방식으로 BitmapData 만들어 사용하는 것이 속도 개선 및 CPU사용량을 줄이는데 큰 장점이 있다. 중요한 점은 BitmapData를 사용한 후 메모리에 반환할 때 dispose()함수를 수행하도록 하여 쓸데없이 메모리를 사용하는 것을 방지하자.

글쓴이 : 지돌스타(http://blog.jidolstar.com/189)

이 글의 관련글
Trackback Address :: http://blog.jidolstar.com/trackback/189
Name
Password
Homepage
Secret