前回のスクロールバーは、計算をするところと、描画するところをわけましょうみたいな話でした。

これを具体的に実装すると次のようになります。

スクロールバーをクラス化する

まえのコードのスクロールバーの部分はまるごとクラスに分離できそうなので、分けます。

Scrollbar.asというファイルにコピペして編集したのが下記コードです。

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;

    public class Scrollbar extends Sprite {
        private var _range:Rectangle;
        private var _percent:Number = 0;
       
        public var bar:Sprite;
        public var bg:Sprite;

        public function Scrollbar () {
            // 初期化
            bar.y = bg.y;
            bar.buttonMode = true;
           
            _range = new Rectangle( bg.x, bg.y,  0, bg.height - bar.height );
           
            // スライドのイベントリスナー設定
            bar.addEventListener( MouseEvent.MOUSE_DOWN, onPressBar );
            bar.addEventListener( MouseEvent.MOUSE_UP, onReleaseBar );
            bar.stage.addEventListener( MouseEvent.MOUSE_UP, onReleaseBar );
        }
        private function onPressBar( e:MouseEvent ):void {
            bar.startDrag( false, _range );
            addEventListener( Event.ENTER_FRAME, onUpdateBar );
        }
        private function onReleaseBar( e:MouseEvent ):void {
            bar.stopDrag();
            removeEventListener( Event.ENTER_FRAME, onUpdateBar );
        }
        // パーセント値を更新
        private function onUpdateBar( e:Event ):void {
            var relativePositio:Number = bar.y - bg.y;
            _percent = relativePositio / _range.height;
           
            dispatchEvent( new ScrollEvent( ScrollEvent.SCROLL ) );
        }
       
        public function get percent():Number {
            return _percent;
        }
    }
}

パーセント値をプライベート変数にし、取り出す用のGetterのみ設定してます。

また値を更新した際にScrollEvent.SCROLLというカスタムイベントを送出しています。

これにより、Event.ENTER_FRAMEと違ってスクロールバーを触っていないときは余計な処理をしないですむようになります。またイベントに具体的な名前が付くため何の変化があったのかわかりやすくなります。

あとはほとんどコピペなので、クラスになれてないひとも、じっくりみれば理解できると思います。

クラスをつくる手順としても、とりあえずタイムラインにベタでコード書いていって、まとまってきたら切り出すくらいに考えるとつくりやすいと思います。(実際AS2だとそういうことが多い)

スクロール・イベントと反映する関数をつなげる

スクロールバーの部品をシンボル化して、リンケージにScrollbarクラスを設定します。

ステージのインスタンスには"scrollbar"というインスタンス名をつけています。

Scrollbarがイベントを送出してるので、前回ENTER_FRAMEで反映していたところを下記のように変えます。

// スクロールバーのイベント設定

scrollbar.addEventListener( ScrollEvent.SCROLL, onScroll );
scrollbar.addEventListener( ScrollEvent.SCROLL, onUpdateValue );

また、受け取る関数でも値をScrollbar.percentから取り出すようにします。

function onScroll( e:ScrollEvent ):void {
    konchi.y = scrollbar.percent * _rangeKonchiY + _offsetKonchiY;
    konchi.scaleX = konchi.scaleY = scrollbar.percent * _rangeKonchiScale + _offsetKonchiScale;
} 

せっかくなので、パーセントで分けるといろいろ便利な例としてイージング処理をするようにしてみました。このように変えてもScrollbar自体は変更が必要ないです。

サンプルをアップしておくので適当に参考にしてみてください。

Flashのサンプルです。

ちなみにチェックボックスも即席ですが同じような考え方で実装されています。

HTML5飯