In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

似非iPhone風スクロール

Get Adobe Flash player
by sowcodWonderfl 26 Oct 2009
  • Related works: 3
  • Talk

    paq at 27 Oct 2009 09:40
    Nullエラーが??
    paq at 27 Oct 2009 09:41
    TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。 at ScrollContainer/onEnterFrame()

    Tags

    Embed
/**
 * Copyright sowcodWonderfl ( http://wonderfl.net/user/sowcodWonderfl )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/iRXl
 */

package {
    import flash.display.Sprite;
    import flash.geom.Point;
    [SWF(frameRate=60)]
    public class ScrollTest extends Sprite {
        // iPhoneのスクロールのような動きをさせるテスト。
        // 画面内をドラッグしながらボタンを放すと投げれます。
        //
        // 画面端で跳ね返りすぎるなどするので、iPhoneのものと
        // 同じ動きでは無いです。
        // 画面端でバウンドして画面端で止まるようにするには
        // 加速度を調節してとかいうやり方じゃ出来ないですね。
        
        private var _container:ScrollContainer;
        private var _content:Content;
        
        public function ScrollTest() {
            this._content = new SampleContent();
            
            this._container = new ScrollContainer();
            this._container.content = this._content;
            
            this._container.size = new Point(465,465);
            
            this.addChild(this._container);
        }
    }
}

import flash.events.MouseEvent;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.display.Sprite;
import flash.display.Graphics;

// スクロールコンテナに入れるオブジェクトはこれを実装する。
interface Content {
    function get sprite() : Sprite; // 描画オブジェクトを取得
    function get size() : Point; // サイズを取得
}

// スクロールコンテナの中に入れてるコンテンツ。
class SampleContent extends Sprite implements Content {
    public function SampleContent() {
        this.drawSelf();
    }
    public function get sprite() : Sprite {
        return this;
    }
    public function get size() : Point {
        // コンテンツの大きさ
        return new Point(1200,1200);
    }
    public function drawSelf():void {
        var g:Graphics = this.graphics;
        g.lineStyle(0,0xff0000);
        g.beginFill(0x00aaaa);
        g.moveTo(0,0);
        for(var i:Number = 0; i<100; ++i) {
            g.lineTo(Math.random()*1200,Math.random()*1200);
        }
        g.endFill();
    }
}

// ベースのコンテナ
class AreaContainer extends Sprite {
    private var _content:Content = null;
    private var _size:Point;
    private var _hitArea:Sprite;
    private var _contentSprite:Sprite;
    
    // setter and getter
    public function set content(value:Content):void {
        if(this._content != null) this._contentSprite.removeChild(this._content.sprite);
        this._content = value;
        this._contentSprite.addChild(this._content.sprite);
    }
    public function get content():Content { return this._content; }
    
    public function set size(value:Point):void {
        // サイズに合わせてクリック可能領域も調整
        this._size = value;
        this._hitArea.width = value.x;
        this._hitArea.height = value.y;
    }
    public function get size():Point { return this._size; }
    
    // constructor
    public function AreaContainer() {
        // クリック可能領域作成
        this._hitArea = createHitArea();
        this.addChild(this._hitArea);
        this.hitArea = this._hitArea;
        
        this._contentSprite = new Sprite();
        this.addChild(this._contentSprite);
    }
    
    private function createHitArea():Sprite {
        var sp:Sprite = new Sprite();
        sp.visible = false;
        var hitg:Graphics = sp.graphics;
        hitg.beginFill(0x000000);
        hitg.drawRect(0,0,100,100);
        hitg.endFill();
        return sp;
    }
}

// スクロール機能付きコンテナ
class ScrollContainer extends AreaContainer {
    private var _firstP:Point; // クリックした時点のマウス座標
    private var _beforeP:Point; // 前フレームのマウス座標
    private var _baseP:Point; // クリックした時点でのコンテンツの座標
    private var _beforeContentP:Point; // 前フレームのコンテンツの座標
    private var _velocity:Point; // 移動速度
    private var _isMouseDown:Boolean;
    private var _hScrollBar:ScrollBar;
    private var _vScrollBar:ScrollBar;
    
    override public function set size(value:Point):void {
        super.size = value;
        this._vScrollBar.height = value.y * value.y / this.content.size.y;
        this._hScrollBar.width = value.x * value.x / this.content.size.x;
        this._vScrollBar.x = this.size.x - this._vScrollBar.width;
        this._hScrollBar.y = this.size.y - this._hScrollBar.height;
    }
    
    public function ScrollContainer() {
        this._vScrollBar = new ScrollBar();
        this._vScrollBar.width = 10;
        this.addChild(this._vScrollBar);
        this._hScrollBar = new ScrollBar();
        this._hScrollBar.height = 10;
        this.addChild(this._hScrollBar);
        
                this._vScrollBar.visible = this._hScrollBar.visible = false;
        
        // イベント登録
        this.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
        this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
        this.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
    }
    
    private function onMouseDown(ev:MouseEvent):void {
        this._isMouseDown = true;
        this._beforeP = new Point(this.mouseX, this.mouseY);
        this._firstP = this._beforeP.clone();
        this._baseP = new Point(this.content.sprite.x, this.content.sprite.y);
        this._beforeContentP = this._baseP.clone();
        
                this._vScrollBar.visible = this._hScrollBar.visible = true;
    }
    
    private function onEnterFrame(ev:Event):void {
        var maxP:Point = content.size.subtract(this.size); // 最大スクロール値
        var newContentP:Point;
        if(this._isMouseDown) {
            // ドラッグ中
            var newP:Point = new Point(this.mouseX, this.mouseY);
            var diffP:Point = newP.subtract(this._firstP);
            newContentP = this._baseP.add(diffP);
            
            // 端オーバー時の処理
            if(newContentP.x > 0) newContentP.x = newContentP.x / 2;
            if(newContentP.y > 0) newContentP.y = newContentP.y / 2;
            if(newContentP.x < -maxP.x)
                newContentP.x = (maxP.x + newContentP.x) / 2 + -maxP.x;
            if(newContentP.y < -maxP.y)
                newContentP.y = (maxP.y + newContentP.y) / 2 + -maxP.y;
            
            // 座標の適用
            this.content.sprite.x = newContentP.x;
            this.content.sprite.y = newContentP.y;
            
            this._velocity = newContentP.subtract(this._beforeContentP);
        } else {
            if(this._beforeContentP.x > 0) 
                this._velocity.x = this._velocity.x * 0.9 - this._beforeContentP.x * 0.05;
            if(this._beforeContentP.y > 0) 
                this._velocity.y = this._velocity.y * 0.9 - this._beforeContentP.y * 0.05;
            if(this._beforeContentP.x < -maxP.x)
                this._velocity.x = this._velocity.x * 0.9 - (maxP.x + this._beforeContentP.x) * 0.05;
            if(this._beforeContentP.y < -maxP.y)
                this._velocity.y = this._velocity.y * 0.9 - (maxP.y + this._beforeContentP.y) * 0.05;
                
            newContentP = (new Point(this.content.sprite.x, this.content.sprite.y)).add(this._velocity);
            
            this._velocity = new Point(this._velocity.x * 0.95, this._velocity.y * 0.95);
            if(this._velocity.length < 0.1) {
                this._velocity = new Point();
                this._vScrollBar.visible = this._hScrollBar.visible = false;
            }
            this.content.sprite.x += this._velocity.x;
            this.content.sprite.y += this._velocity.y;
        }
        
        // スクロールバー
        this._vScrollBar.y = - this.size.y * this.content.sprite.y / this.content.size.y;
        this._hScrollBar.x = - this.size.x * this.content.sprite.x / this.content.size.x;
        
        this._beforeContentP = newContentP;
        this._beforeP = newP;
    }
    
    private function onMouseUp(ev:MouseEvent):void {
        this._isMouseDown = false;
    }
}

class ScrollBar extends Sprite {
    public function ScrollBar() {
        this.drawSelf();
    }
    private function drawSelf() : void {
        var g:Graphics = this.graphics;
        g.beginFill(0x808080,0.5);
        g.drawRect(0,0,50,50);
        g.endFill();
    }
}