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

Flip Panel -- めくれるサムシング。

ぱたぱたとめくれるパネル。

めくり処理は、FlipPanel内でPageクラスのdrawをスレッド制御してる感じ。

draw内は y-tti 氏のソースから拝借。あざっす!http://wonderfl.net/c/wJDq

めくりスピードは、スレッドに渡す引数で制御。
Get Adobe Flash player
by djakarta_trap 11 Oct 2010
    Embed
/**
 * Copyright djakarta_trap ( http://wonderfl.net/user/djakarta_trap )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/fVYK
 */

package
{
    import com.bit101.components.InputText;
    import com.bit101.components.PushButton;
    import com.bit101.components.TextArea;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.FocusEvent;
    import flash.events.MouseEvent;
    import flash.utils.Dictionary;
    import flash.utils.getDefinitionByName;
    import flash.utils.getQualifiedClassName;
    import net.hires.debug.Stats;
    import org.libspark.thread.EnterFrameThreadExecutor;
    import org.libspark.thread.Thread;
    
    [SWF(frameRate="60", backgroundColor="#FFFFFF")]
    
    /**
     * ...
     * @author djakarta-trap
     */
    public class FlipClassTest extends Sprite 
    {
        private var _flipPanel:FlipPanel;
        private var dic:Dictionary;
        private var flip1:FlipPanel;
        private var flip2:FlipPanel;
        private var flip3:FlipPanel;
        private var input:InputText;
        
        public function FlipClassTest() 
        {
            Thread.initialize(new EnterFrameThreadExecutor());
            
            var flipImageData:Array = [];
            
            for (var u:int = 0; u < 3 ; u++)
            {
                var arr:Array = [];
                for (var i:int = 1; i <= 10; i++)
                {
                    var pageAbove:Page = new Page(new CustomBitmapData(100, 50, i.toString() + " ページ目:上"));
                    var pageBelow:Page = new Page(new CustomBitmapData(100, 50, i.toString() + " ページ目:下"));
                    arr.push(new SpreadPage(pageAbove, pageBelow));
                };
                flipImageData.push(arr);
            };
            
            flip1 = new FlipPanel(flipImageData[0]);
            flip2 = new FlipPanel(flipImageData[1]);
            flip3 = new FlipPanel(flipImageData[2]);
            
            flip2.x = stage.stageWidth*0.5 - flip2.width*0.5;
            flip2.y = stage.stageHeight*0.5 - flip2.height*0.5 - 100;
            
            flip1.x = flip2.x - flip1.width - 20;
            flip1.y = flip2.y;
            
            flip3.x = flip2.x + flip2.width + 20;
            flip3.y = flip2.y;
            
            addChild(flip1);
            addChild(flip2);
            addChild(flip3);
            
            var btn1:PushButton = new PushButton(null, flip1.x, flip1.y + 100, "gotoPage", _onClick);
            
            var btn2:PushButton = new PushButton(null, flip2.x, flip2.y + 100, "gotoPage", _onClick);
            
            var btn3:PushButton = new PushButton(null, flip3.x, flip3.y + 100, "gotoPage", _onClick);
            
            dic = new Dictionary();
            dic[btn1] = flip1.gotoPage;
            dic[btn2] = flip2.gotoPage;
            dic[btn3] = flip3.gotoPage;
            
            btn1.y = btn2.y = btn3.y = stage.stageHeight - btn1.height;
            
            addChild(btn1);
            addChild(btn2);
            addChild(btn3);
            
            addChild(new Stats());
            
            var loopBtn:PushButton = new PushButton(null, stage.stageWidth * 0.5, stage.stageHeight * 0.5, "loop fliping", _toggleLoopFlip);
            loopBtn.x -= loopBtn.width*0.5;
            addChild(loopBtn);
            
            input = new InputText(null, 0, 0, "set page index you want to go.");
            input.width = 160;
            input.x = stage.stageWidth * 0.5 - input.width * 0.5;
            input.y = btn2.y - 50;
            input.restrict = "1234567890";
            input.addEventListener(FocusEvent.FOCUS_IN, function(e:FocusEvent):void { input.removeEventListener(e.type, arguments.callee); input.text = ""; } );
            
            addChild(input);
        };
        
        private function _toggleLoopFlip(e:MouseEvent):void 
        {
            flip1.loopFliping();
            flip2.loopFliping();
            flip3.loopFliping();
        }
        
        private function _onClick(e:MouseEvent):void 
        {
            dic[e.target].apply(null,[int(input.text)]);
        };
        
    }
}

interface IFlip 
{
    function flipForward():void;
    function flipBackward():void;
    function loopFliping():void;
    function gotoPage(pageIndex:int):void;
    function isFliping():Boolean;
}

import flash.display.DisplayObject;
import flash.display.Sprite;
import org.libspark.betweenas3.core.tweens.groups.SerialTween;
import org.libspark.thread.Thread;
import org.libspark.thread.ThreadState;
import org.libspark.thread.utils.SerialExecutor;

class FlipPanel extends Sprite implements IFlip
{
    private var _pages:Array/*SpreadPage*/;
    private var _pageIndex:int;
    private var _loopFlipThread:SerialExecutor;
    private var _currentFlipThread:Thread;
    private var _numPages:int;
    private var _gotoPageThread:SerialExecutor;
    
    /**
    * パタパタめくれるパネル。上下にめくれる。
    * 見開きページをSpreadPageインスタンスで管理してる。
    */
    public function FlipPanel(spreadPages:Array)
    {
        super();
        this._pages = spreadPages;
        _numPages = _pages.length;
        
        //全ページアド。でも、見えない状態でね。
        for (var i:int = _pages.length - 1; i >= 0; i--) 
        {
            var item:SpreadPage = _pages[i];
            item.mouseChildren = false;
            item.mouseEnabled = false;
            item.visible = false;
            addChild(item);
        };
        
        _initialize();
    };
    
    private function _initialize():void 
    {
        _pageIndex = 0;
        gotoAndStop(_pageIndex);
        _pages[_pageIndex].visible = true;
    };
    
    
    public function flipForward():void
    {
        var next:SpreadPage, current:SpreadPage;
        
        //今が最終見開きページの場合
        if (_pageIndex >= _pages.length - 1) {
            next = _pages[0];
        }else {
            next = _pages[_pageIndex + 1];
        };
        next.visible = true;
        current = _pages[_pageIndex];
        
        //次のページを準備する。
        next.prepareFlipForward();
        
        //アニメーションスタート
        _currentFlipThread = new FlipForwardThread(current, next, this, 8);
        _currentFlipThread.start();
        
        //データ更新
        if (_pageIndex >= _pages.length - 1) {
            _pageIndex = 0;
        }else {
            ++_pageIndex;
        };
    };
    
    /**
    * 指定された表示オブジェクトを、指定したツリーインデックスへ移動させる。
    */
    public function setPageIndex(target:DisplayObject, toIndex:int):void
    {
        if (!contains(target)) {
            return;
        };
        
        addChildAt(target, toIndex);
    };
    
    public function getPageIndex(target:DisplayObject):int
    {
        if (!contains(target)) {
            return -1;
        };
        
        return getChildIndex(target);
    }
    
    public function flipBackward():void
    {
        //今回は実装しない。
    };
    
    /**
     * めくりが永遠に続く。トグル的に機能する。 
    */
    public function loopFliping():void
    {
        if (_loopFlipThread && _loopFlipThread.state <= ThreadState.TIMED_WAITING) {
            _loopFlipThread.interrupt();
            _loopFlipThread = null;
            return;
        };
        
        _loopFlipThread = new SerialExecutor();
        
        if (_gotoPageThread && _gotoPageThread.state <= ThreadState.TIMED_WAITING) {
            _gotoPageThread.interrupt();
            _gotoPageThread = null;
            
            if (_currentFlipThread && _currentFlipThread.state <= ThreadState.TIMED_WAITING) {
                _loopFlipThread.addThread(_currentFlipThread);
            };
        };
        
        _loopFlipThread.addThread( new LoopFlipThread(this, 500));
        _loopFlipThread.start();
    };
    
    /**
    * 指定した見開きページへアニメーション移動させる。
    * @param goalIndex 行き先のページインデックス
    */
    public function gotoPage(goalIndex:int):void
    {
        var isGotoPaging:Boolean = false;
        
        if (_gotoPageThread && _gotoPageThread.state <= ThreadState.TIMED_WAITING) {
            isGotoPaging = true;
            _gotoPageThread.interrupt();
            _gotoPageThread = null;
        };
        
        _gotoPageThread = new SerialExecutor();
        var flipTimes:int = (_pageIndex < goalIndex) ? goalIndex - _pageIndex : (_numPages - (_pageIndex+1)) + (goalIndex + 1);
        
        if (_loopFlipThread && _loopFlipThread.state <= ThreadState.TIMED_WAITING) {
            _loopFlipThread.interrupt();
            _loopFlipThread = null;
            
            //今現在の1ページ分のめくりを非同期処理したいときはコメントアウトを解除。
            //if (_currentFlipThread && _currentFlipThread.state <= ThreadState.TIMED_WAITING) {
                //_gotoPageThread.addThread(_currentFlipThread);
            //};
        };
        
        _gotoPageThread.addThread(new SpecifiedTimesFlip(this, flipTimes, 500));
        _gotoPageThread.start();
    };
    
    /**
    * 指定した見開きページへ、アニメーションなしで移動させる 
    */
    public function gotoAndStop(goalIndex:int):void
    {
        if (_gotoPageThread && _gotoPageThread.state <= ThreadState.TIMED_WAITING) {
            _gotoPageThread.interrupt();
            _gotoPageThread = null;
        };
        if (_loopFlipThread && _loopFlipThread.state <= ThreadState.TIMED_WAITING) {
            _loopFlipThread.interrupt();
            _loopFlipThread = null;
        };
        
        var flipTimes:int = (_pageIndex < goalIndex) ? goalIndex - _pageIndex : (_numPages - (_pageIndex + 1)) + (goalIndex + 1);
        
        for (var i:int = 0; i < flipTimes; i++)
        {
            var highestPage:DisplayObject = getChildAt(numPages - 1);
            if (i == 0) highestPage.visible = false;
            if (i == flipTimes - 1) getChildAt(numPages - 2).visible = true; 
            addChildAt(highestPage, 0);
        };
        
        //update
        _pageIndex = goalIndex;
    }
    
    public function isFliping():Boolean
    {
        return false;
    }
    
    public function get numPages():int { return _numPages; }    
}


import flash.display.DisplayObjectContainer;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import org.libspark.thread.Thread;

/**
 * ページを表すクラス。見開き状態を1ページとしてます。
 * ...
 * @author djakarta-trap
 */
class SpreadPage extends Sprite
{
    /**
    * 捲れる際のパース感を現す。この値が大きいほど、パース感が増す。 
    */
    public static const distorion:Number = 4;
    
    private var _above:Page;
    private var _below:Page;
    
    public function SpreadPage(above:Page, below:Page)
    {
        this._below = below;
        this._above = above;
        
        addChild(_below);
        addChild(_above);
        _below.y = _above.originalHeight;
        
        _below.draw(new Point(0, 0), new Point(_below.originalWidth, 0), new Point(0, _below.originalHeight), new Point(_below.originalWidth, _below.originalHeight));
        _above.draw(new Point(0, 0), new Point(_above.originalWidth, 0), new Point(0, _above.originalHeight), new Point(_above.originalWidth, _above.originalHeight));
    };
    
    public function prepareFlipForward():void 
    {
        _above.draw(new Point(0, 0), new Point(_above.originalWidth, 0), new Point(0, _above.originalHeight), new Point(_above.originalWidth, _above.originalHeight));
        _below.draw(new Point(0, 0), new Point(_below.originalWidth, 0), new Point(-distorion, 0), new Point(_below.originalWidth + distorion, 0));
    }
    
    public function get above():Page { return _above; }
    public function get below():Page { return _below; }
}


import flash.display.BitmapData;
import flash.display.Shape;
import flash.geom.Matrix;
import flash.geom.Point;

/**
 * SpreadPageにおける1ページ分を表すクラス。
 * ...
 * @author djakarta-trap
 */
class Page extends Shape 
{
    private var _bitmapData:BitmapData;
    private var _initialMatrix1:Matrix;
    private var _initialMatrix2:Matrix;
    private var _originalWidth:Number;
    private var _originalHeight:Number;
    
    public function Page(bitmapData:BitmapData) 
    {
        super();
        this._bitmapData = bitmapData;
        
        _originalWidth = _bitmapData.width;
        _originalHeight = _bitmapData.height;
        
        _initialMatrix1 = _getTriangleMatrix(new Point(0, 0), new Point(_bitmapData.width, 0), new Point(0, _bitmapData.height));
        _initialMatrix2 = _getTriangleMatrix(new Point(_bitmapData.width, _bitmapData.height), new Point(0, _bitmapData.height), new Point(_bitmapData.width, 0));
    };
    
    public function draw(TL:Point, TR:Point, BL:Point, BR:Point):void
    {
        graphics.clear();
        
        var mat1:Matrix = _getTriangleMatrix(TL, TR, BL);
        var mat2:Matrix = _initialMatrix2.clone();
        mat1.concat(_initialMatrix1.clone());
        mat2.concat(_getTriangleMatrix(BR, BL, TR));
        
        graphics.beginBitmapFill(_bitmapData, mat1, false, false);
        graphics.moveTo(TL.x, TL.y);
        graphics.lineTo(TR.x, TR.y);
        graphics.lineTo(BL.x, BL.y);
        graphics.endFill();
        
        graphics.beginBitmapFill(_bitmapData, mat2, false, false);
        graphics.moveTo(BR.x, BR.y);
        graphics.lineTo(TR.x,TR.y);
        graphics.lineTo(BL.x, BL.y);
        graphics.endFill();
    };
    
    private function _getTriangleMatrix(p0:Point, p1:Point, p2:Point):Matrix 
    {
        var w:Number = _bitmapData.width;
        var h:Number = _bitmapData.height;
        var matrix:Matrix = new Matrix();
        matrix.a = (p1.x - p0.x) / w;
        matrix.b = (p1.y - p0.y) / w;
        matrix.c = (p2.x - p0.x) / h;
        matrix.d = (p2.y - p0.y) / h;
        matrix.tx = p0.x;
        matrix.ty = p0.y;
        
        return matrix;
    }
    
    public function get originalWidth():Number { return _originalWidth; };
    public function get originalHeight():Number { return _originalHeight; }
    
}

import flash.display.BitmapData;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;

class CustomBitmapData extends BitmapData
{
    public function CustomBitmapData(width:int, height:int, msg:String = null) 
    {
        super(width, height, false, 0xffffffff);
        
        var sp:Sprite = new Sprite();
        var tf:TextField = new TextField();
        
        sp.graphics.lineStyle(2, 0x666666);
        sp.graphics.beginFill(0xffffff);
        sp.graphics.drawRect(0, 0, width, height);
        sp.graphics.endFill();
        sp.graphics.lineStyle(1, 0x666666);
        sp.graphics.moveTo(0, 0);
        sp.graphics.lineTo(width, height);
        sp.graphics.moveTo(width, 0);
        sp.graphics.lineTo(0, height);
        sp.graphics.endFill();
        
        if (msg) {
            var tformat:TextFormat = new TextFormat("_sans", 12, 0x666666);
            tformat.align = TextFormatAlign.CENTER;
            
            tf.autoSize = TextFieldAutoSize.CENTER;
            tf.width = width;
            tf.wordWrap = true;
            tf.multiline = true;
            tf.selectable = false;
            tf.mouseEnabled = false;
            tf.defaultTextFormat = tformat;
            tf.text = msg;
            tf.x = 0;
            tf.y = sp.height * 0.5 - tf.height * 0.5;
            sp.addChild(tf);
        };
        
        draw(sp); 
    }
}

import flash.display.DisplayObjectContainer;
import flash.geom.Point;
import org.libspark.thread.Thread;

class FlipForwardThread extends Thread 
{
    private var _current:SpreadPage;
    private var _next:SpreadPage;
    private var _rad:Number;
    private var _tl:Point;
    private var _tr:Point;
    private var _bl:Point;
    private var _br:Point;
    private var _speed:Number;
    private var _panel:FlipPanel;
    
    public function FlipForwardThread(current:SpreadPage, next:SpreadPage, panel:FlipPanel, speed:Number = 2) 
    {
        super();
        this._panel = panel;
        this._speed = speed;
        this._next = next;
        this._current = current;
        
        _rad = 0;
        
        _tl = new Point();
        _tr = new Point();
        _bl = new Point();
        _br = new Point();
    };
    
    override protected function run():void 
    {
        if (isInterrupted) {
            next(null);
        }else {
            //update
            _rad += Math.PI / 180 * _speed;
            
            if (_rad >= Math.PI / 2) {
                _panel.setChildIndex(_next, _panel.numPages - 1);
                _current.above.draw(new Point(0, 0), new Point(_current.above.originalWidth, 0), new Point(0, _current.above.originalHeight), new Point(_current.above.originalWidth, _current.above.originalHeight));
                _nextBelowDown();
                return;
            };
            
            next(run);
            
            var _distortion:Number = SpreadPage.distorion * Math.cos(_rad);
            var _height:Number = _current.above.originalHeight * Math.sin(_rad);
            
            _tl.x = -_distortion; _tl.y = _height;
            _tr.x = _current.above.originalWidth + _distortion; _tr.y = _height;
            _bl.x =  0; _bl.y = _current.above.originalHeight;
            _br.x = _current.above.originalWidth; _br.y =  _current.above.originalHeight;
            
            _current.above.draw(_tl, _tr, _bl, _br);
            
        };
        
    }
    
    private function _nextBelowDown():void 
    {
        if (isInterrupted) {
            next(null);
        }else {
            
            next(_nextBelowDown);
            
            //update
            _rad += Math.PI / 180 * _speed;
            
            if (_rad >= Math.PI) {
                next(null);
                _panel.setChildIndex(_current, 0);
                _rad = Math.PI
            };
            
            var _distortion:Number = SpreadPage.distorion * Math.sin(_rad);
            var _height:Number = -_next.below.originalHeight * Math.cos(_rad);
            _tl.x = 0; _tl.y = 0;
            _tr.x = _next.below.originalWidth; _tr.y = 0;
            _bl.x = -_distortion; _bl.y = _height;
            _br.x = _next.below.originalWidth + _distortion; _br.y = _height;
            
            _next.below.draw(_tl, _tr, _bl, _br);
        }
    }
}

import org.libspark.thread.Thread;

class LoopFlipThread extends Thread 
{
    private var _flipPanel:FlipPanel;
    private var _duration:Number;
    
    public function LoopFlipThread(flipPanel:FlipPanel, duration:Number = 200)
    {
        super();
        this._duration = duration;
        this._flipPanel = flipPanel;
    };
    
    override protected function run():void 
    {
        if (isInterrupted) {
            next(null);
        }else {
            next(run);
            sleep(_duration);
            interrupted(_onInterrupt);
            _flipPanel.flipForward();
        };
    };
    
    private function _onInterrupt():void 
    {
        next(null);
    }
}

import org.libspark.thread.Thread;

class SpecifiedTimesFlip extends Thread 
{
    private var _flipPanel:FlipPanel;
    private var _flipTimes:int;
    private var _duration:Number;
    private var _counter:int;
    
    public function SpecifiedTimesFlip(flipPanel:FlipPanel, flipTimes:int, duration:Number) 
    {
        this._duration = duration;
        this._flipTimes = flipTimes;
        this._flipPanel = flipPanel;
        _counter = 0;
    };
    
    override protected function run():void 
    {
        if (isInterrupted) {
            next(null);
        }else {
            
            if (_counter >= _flipTimes) {
                next(null);
            }else {
                next(run);
                sleep(_duration);
                interrupted(_onInterrupt);
                //実行
                _flipPanel.flipForward();
                //update
                _counter++;
            };
        }
    }
    
    private function _onInterrupt():void 
    {
    }
}