3_08 http://beautifl.net/book/ amashio forked:0favorite:0lines:838license : MIT License modified : 2011-09-03 15:55:59 Embed Tweet package{ import caurina.transitions.properties.CurveModifiers; import caurina.transitions.properties.DisplayShortcuts; import flash.display.Sprite; import flash.events.Event; import flash.system.Security; [SWF(width = "465", height = "465", backgroundColor = "0xFFFFFF", frameRate = "60")] //main public class Main extends Sprite { public static const WIDTH:uint = 444; public static const HEGHT:uint = 398; public static const SEGMENT_X:uint = 5; public static const SEGMENT_Y:uint = 3; public static const TAG:String = 'sunset'; public static const NUM:uint = 20; public function Main():void{ Wonderfl.capture_delay(30); if (stage) { _init() } else { addEventListener(Event.ADDED_TO_STAGE, _init) } ; } //1.初期設定 private function _init(e:Event = null):void{ removeEventListener(Event.ADDED_TO_STAGE, _init); Security.allowDomain( "*" ); Security.loadPolicyFile("http://query.yahooapis.com/crossdomain.xml"); Security.loadPolicyFile("http://api.flickr.com/crossdomain.xml"); for (var i:int = 1, len:uint = 5; i <= len; i++){ Security.loadPolicyFile("http://farm" + i + ".static.flickr.com/crossdomain.xml"); } //tweener初期設定 CurveModifiers.init(); DisplayShortcuts.init(); new Init(new Context(this), Main.TAG, Main.NUM).start() } } } import __AS3__.vec.Vector; import caurina.transitions.Tweener; import com.bit101.components.FPSMeter; import com.bit101.components.InputText; import com.bit101.components.Label; import com.bit101.components.ProgressBar; import com.bit101.components.PushButton; import com.bit101.components.ComboBox; import flash.display.*; import flash.events.*; import flash.geom.*; import flash.net.*; import flash.system.LoaderContext; import flash.utils.ByteArray; import jp.progression.commands.lists.LoaderList; import jp.progression.commands.net.LoadBitmapData; class Init { private var _isDebug:Boolean = true; private var _context:Context;//Initクラス内でデータを持ち回す為のクラス private var _controller:Controller;//本の作成を行うクラス private var _graSh:Shape; private var _saveTurnOver:MotionSave;//アニメーションのキャッシュ化クラス private var _imgPathList:Vector.<String>; private var _loaderList:LoaderList;//複数読み込むリスト progressionから private var _apiLoader:URLLoader = new URLLoader(); private var _isBuilding:Boolean;//設置状態確認? private var _isInit:Boolean = true;//初期化判定 private var _isLoaderListExecuting:Boolean; private var _progress:ProgressBar; private var _comboBox:ComboBox;//読み込む写真を数を選ぶcombobox private var _tagInput:InputText; private var _errorLabel:Label; private var _tagApi:String; private var _numApi:uint; private var _header:Sprite; // public function Init(context:Context, tag:String, num:uint){ _context = context; _tagApi = tag; _numApi = num; _progress = new ProgressBar(_context.container, 182, 220); _graSh = _createGradationShape();// _errorLabel = new Label(_context.container, 210, 222, "Not Found"); _errorLabel.visible = false; } // private function _createGradationShape():Shape{ var result:Shape = new Shape(); var mtx:Matrix = new Matrix() mtx.createGradientBox( Main.WIDTH, 0, 0, 0, 0);//Matrixスタイルを作成(width, height, rotation, x軸の平行移動距離, y軸の平行移動距離) //beginGradientFill(BitmapData, Matrix, Boolean, smooth) result.graphics.beginGradientFill(GradientType.LINEAR, [0x0, 0x0, 0x0, 0x0, 0x0], [0.0, 0.3, 0.6, 0.3, 0.0], [77, 112, 127, 142, 177], mtx); result.graphics.drawRect(0, 0, Main.WIDTH, Main.HEGHT ); return result;//返す } private function _resizeBmd(source:BitmapData):BitmapData{ var result:BitmapData = new BitmapData(Main.WIDTH, Main.HEGHT); var n:Number = Math.max(Main.WIDTH / source.width , Main.HEGHT / source.height); var mtx:Matrix = new Matrix(); mtx.createBox(n, n, 0, (Main.WIDTH - source.width * n) * 0.5, (Main.HEGHT - source.height * n) * 0.5); result.draw(source, mtx, null, null, null, true); result.draw(_graSh) return result; } // private function _reset():void{ _context.reset(); _errorLabel.visible = false; if (_apiLoader.hasEventListener(Event.COMPLETE)) { _apiLoader.removeEventListener(Event.COMPLETE, _connectAPIComplete) }; if (_apiLoader.hasEventListener(IOErrorEvent.IO_ERROR)) { _apiLoader.removeEventListener(IOErrorEvent.IO_ERROR, _error) }; } //初期設定時にスタート public function start():void{ _build();//label等の内容を設置 connect();// } // public function connect():void{ Tweener.addTween(_progress, { _autoAlpha:1.0, transition:'linear', time:0.2 } );//progressBarの表示 _connectAPI(); } //読み込み先を設定して読み込み private function _connectAPI():void{ var request:URLRequest = new URLRequest('http://query.yahooapis.com/v1/public/yql');//すべての情報を 1 つの HTTP 要求にキャプチャする var variables:URLVariables = new URLVariables();//アプリケーションとサーバーの間で変数を転送できる //variables = new URLVariables(); たぶんいらない variables['q'] = "SELECT * FROM flickr.photos.search(" + _numApi + ") WHERE tags='" + _tagApi + "'"; variables['format'] = 'xml'; request.data = variables; _apiLoader.load(request); _apiLoader.addEventListener(Event.COMPLETE, _connectAPIComplete); _apiLoader.addEventListener(IOErrorEvent.IO_ERROR, _error); } //読み込みが完了したら解析 private function _connectAPIComplete(e:Event):void{ _header.visible = true; _apiLoader.removeEventListener(Event.COMPLETE, _connectAPIComplete); _apiLoader.removeEventListener(IOErrorEvent.IO_ERROR, _error); var xml:XML = new XML(_apiLoader.data); _imgPathList = new Vector.<String>();//イメージurlの配列 for (var i:int = 0, len:uint = xml.results.photo.length(); i < len; i++){ var node:XML = xml.results.photo[i] as XML; _imgPathList.push("http://farm" + node.@farm + ".static.flickr.com/" + node.@server + "/" + node.@id + "_" + node.@secret + ".jpg"); } _progress.value += 0.025; len = _imgPathList.length; if (len < 1){ //読み込みされていないのでエラー _error(); return } _loaderList = new LoaderList(); //取得されたurlからイメージをロード for ( i = 0; i < _imgPathList.length; i++ ){ var loadBmdData:LoadBitmapData = new LoadBitmapData(new URLRequest(_imgPathList[i]), { cacheAsResource:false } ); loadBmdData.context = new LoaderContext(true); _loaderList.addCommand(loadBmdData); } // _loaderList.onProgress = function():void { _progress.value = this.percent * 0.01 * ((_isInit) ? 0.9 : 0.95) + 0.045;// } // _loaderList.onComplete = function():void{ for ( var i:int = 0, len:uint = this.data.length; i < len; i++ ){ //_contextクラスのbmdList配列につっこむ _context.bmdList.push(_resizeBmd(this.data[i])); } _isLoaderListExecuting = false; _progress.value += 0.025;// _isInit ? _motionSaveStart() : _finish()//初期化中かの判断 } _loaderList.execute(); _isLoaderListExecuting = true; } //エラー処理 private function _error(e:* = null):void{ _header.visible = true; if (_apiLoader.hasEventListener(Event.COMPLETE)) { _apiLoader.removeEventListener(Event.COMPLETE, _connectAPIComplete); } if (_apiLoader.hasEventListener(IOErrorEvent.IO_ERROR)) { _apiLoader.removeEventListener(IOErrorEvent.IO_ERROR, _error); } _errorLabel.visible = true; Tweener.addTween(_progress, { _autoAlpha:0.0 } ); } //セーブ private function _motionSaveStart():void{ _isBuilding = true; var dammyBmd:BitmapData = new BitmapData(1, 1, false); _saveTurnOver = new MotionSave(dammyBmd, dammyBmd, Main.SEGMENT_X, Main.SEGMENT_Y); _saveTurnOver.addEventListener(Event.COMPLETE, _fromLeftMotionComplete); _saveTurnOver.turn(MotionSave.LEFT); } private function _fromLeftMotionComplete(e:Event):void{ _saveTurnOver.removeEventListener(Event.COMPLETE, _fromLeftMotionComplete); _context.fromLeft = _saveTurnOver.data.clone(); _progress.value += 0.025; _saveTurnOver.addEventListener(Event.COMPLETE, _fromRightMotionComplete); _saveTurnOver.turn(MotionSave.RIGHT); } private function _fromRightMotionComplete(e:Event):void{ _saveTurnOver.removeEventListener(Event.COMPLETE, _fromRightMotionComplete); _context.fromRight = _saveTurnOver.data.clone(); _progress.value += 0.025; _saveTurnOver = null; _isBuilding = false; _finish(); } //_comboBoxなどUIを表示する private function _build():void{ _header = new Sprite(); _context.container.addChild(_header).visible = false; new FPSMeter(_header, 10, 7); new Label(_header, 124, 7, 'num : '); _comboBox = new ComboBox(_header, 154, 7); _comboBox.width = 50; for (var i:int = 1; i<= 10; i++){ _comboBox.addItem( { label:String(i * 10), data:i * 10 } ); } _comboBox.selectedIndex = Math.floor(_numApi / 10) - 1; new Label(_header, 215, 7, 'tag : '); _tagInput = new InputText(_header, 242, 9, _tagApi); _tagInput.width = 100; new PushButton(_header, 355, 7, 'search', function():void{ if (_isBuilding){ return; } if (_controller){ _controller.close(); } _tagApi = _tagInput.text; _numApi = _comboBox.selectedItem.data; _reset(); _progress.value = 0; if(_isLoaderListExecuting){ _loaderList.interrupt(); } // connect(); }); } //初期化設定終了後 private function _finish():void{ _progress.value = 1; if (_isInit){ _controller = new Controller(_context); _isInit = false; } _controller.build(_context.bmdList); _controller.start();// Tweener.addTween(_progress, { _autoAlpha:0.0, transition:'linear', time:0.2 } );//progressbar 消す } } //Initクラス内でデータを持ち回す為のクラス class Context { public var fromLeft:PointListData; public var fromRight:PointListData; public var container:DisplayObjectContainer; public var bmdList:Vector.<BitmapData>; public function Context(container:DisplayObjectContainer){ this.container = container; reset() } public function reset():void{ bmdList = new Vector.<BitmapData>(); } } //本の作成を行うクラス class Controller{ private var _context:Context, _book:Book; public function Controller(context:Context){ _context = context; _book = new Book(Main.WIDTH, Main.HEGHT, _context.fromLeft, _context.fromRight); _context.container.addChild(_book); } public function build(list:Vector.<BitmapData>):void{ var dammy:BitmapData = new BitmapData(1,1, false, 0x0); _book.addPage(dammy); for (var i:int = 0, len:uint = list.length; i < len; i++){ _book.addDoublePage(list[i]); } _book.addPage(dammy);// _book.build(); } public function start():void{ _book.open(0); Tweener.addTween(_book, { _autoAlpha:1.0, transition:'easeOutCubic', time:0.6, delay:0.2 } ); } public function close():void{ Tweener.addTween(_book, { _autoAlpha:0.0 } ); _book.reset(); } } //本クラス class Book extends Sprite{ private var _pageWidth:uint, _pageHeight:uint, _fromLeftData:PointListData, _fromRightData:PointListData; private var _viewCount:int = -1; //現在のページ番号 初期値はページなし状態 private var _isNextTurning:Boolean; private var _isPrevTurning:Boolean; private var _isLock:Boolean; private var _bmdList:Vector.<BitmapData> = new Vector.<BitmapData>(); private var _motionList:Vector.<Piece> = new Vector.<Piece>(); public function Book(pageWidth:uint, pageHeight:uint, fromLeftData:PointListData, fromRightData:PointListData){ _pageWidth = pageWidth; _pageHeight = pageHeight; _fromLeftData = fromLeftData; _fromRightData = fromRightData; alpha = 0; x = 10; y = 34; new PushButton(this, 0, 405, 'prev', function():void { prev() } ); new PushButton(this, 345, 405, 'next', function():void { next() } ); _bmdList = new Vector.<BitmapData>(); _motionList = new Vector.<Piece>(); } public function reset():void{ if (_viewCount + 1 <= _motionList.length - 1){ Piece(_motionList[_viewCount + 1]).hide(); Piece(_motionList[_viewCount]).hide(); } _bmdList = new Vector.<BitmapData>(); _motionList = new Vector.<Piece>(); _viewCount = 0; } private function _divisionBmd(src:BitmapData, rect:Rectangle):BitmapData{ var result:BitmapData = new BitmapData(rect.width, rect.height, true, 0xFF000000); result.draw(src, new Matrix(1, 0, 0, 1, -rect.x, -rect.y)); return result; } // public function addPage(bmd:BitmapData):void{ //bmd配列をBookでの_bmdListにいれる //dummyのみ? _bmdList.push(bmd); } // public function addDoublePage(bmd:BitmapData):void { var w:Number = bmd.width * 0.5, h:Number = bmd.height; _bmdList.push(_divisionBmd(bmd, new Rectangle(0, 0, w, h)), _divisionBmd(bmd, new Rectangle(w, 0, w, h))); } // public function build():void{ for (var i:int = 0, len:uint = (_bmdList.length>>1); i < len; i++){ // _motionList.push(new Piece(this, i, _bmdList[i * 2], _bmdList[i * 2 + 1], _fromLeftData, _fromRightData)) } } public function next():void{ if (_isLock || _isPrevTurning || _viewCount >= _motionList.length -2) { return }; _viewCount++ var waitPiece:Piece = _motionList[_viewCount + 1]; var turnPiece:Piece = _motionList[_viewCount]; waitPiece.frontWait(); turnPiece.next(); turnPiece.addEventListener(Event.COMPLETE, _onNextCompleteHandler); turnPiece.addEventListener(Event.CHANGE, _onHalfTurnHandler); _isNextTurning = true; _isLock = true; } public function prev():void{ if (_isLock || _isNextTurning || _viewCount <= 0) { return }; _viewCount--; var waitPiece:Piece = _motionList[_viewCount]; var turnPiece:Piece = _motionList[_viewCount + 1]; waitPiece.backWait(); turnPiece.prev(); turnPiece.addEventListener(Event.COMPLETE, _onPrevCompleteHandler); turnPiece.addEventListener(Event.CHANGE, _onHalfTurnHandler); _isPrevTurning = true; _isLock = true; } // private function _onHalfTurnHandler(e:Event):void{ e.target.removeEventListener(Event.CHANGE, _onHalfTurnHandler); _isLock = false; } //book表示 public function open(num:uint):void{ _motionList[num].backWait(); _motionList[num + 1].frontWait(); _viewCount = num; } // private function _onNextCompleteHandler(e:Event):void{ _isNextTurning = false; Piece(e.target).removeEventListener(Event.COMPLETE, _onNextCompleteHandler); var target:Piece = _motionList[Piece(e.target).id - 1]; if (target != null) { target.hide(); } } // private function _onPrevCompleteHandler(e:Event):void{ _isPrevTurning = false; Piece(e.target).removeEventListener(Event.COMPLETE, _onPrevCompleteHandler); var target:Piece = _motionList[Piece(e.target).id + 1]; if (target != null) { target.hide(); } } } //両面表示のページクラス class Piece extends EventDispatcher{ private var _id:uint, _fromLeft:MotionLoad, _fromRight:MotionLoad, _container:DisplayObjectContainer; public function Piece(container:DisplayObjectContainer, id:uint, frontBmd:BitmapData, backBmd:BitmapData, fromLeftData:PointListData, fromRightData:PointListData){ _id = id; _fromLeft = new MotionLoad(container, frontBmd, _reverse(backBmd), fromLeftData); _fromRight = new MotionLoad(container, backBmd, _reverse(frontBmd), fromRightData); _fromLeft.x = (Main.WIDTH>>1); } private function _reverse(source:BitmapData):BitmapData{ var result:BitmapData = new BitmapData(source.width, source.height, true, 0); result.draw(source, new Matrix( -1, 0, 0, 1, source.width, 0)); return result; } private function _removeListener():void{ if (_fromLeft.hasEventListener(Event.COMPLETE)) { _fromLeft.removeEventListener(Event.COMPLETE, _onLeftCompleteHandler); } if (_fromRight.hasEventListener(Event.COMPLETE)) { _fromRight.removeEventListener(Event.COMPLETE, _onRightCompleteHandler); } } //次のページの処理 public function next(delayTime:Number = 0.0):void{ _removeListener(); _fromLeft.hide(); _fromRight.show(); _fromRight.addEventListener(Event.CHANGE, _onHalfTurnHandler); _fromRight.move(); _fromRight.addEventListener(Event.COMPLETE, _onRightCompleteHandler); } //前のページの処理 public function prev(delayTime:Number = 0.0):void{ _removeListener(); _fromRight.hide(); _fromLeft.show(); _fromLeft.addEventListener(Event.CHANGE, _onHalfTurnHandler); _fromLeft.move(); _fromLeft.addEventListener(Event.COMPLETE, _onLeftCompleteHandler); } private function _onHalfTurnHandler(event:Event):void{ event.target.removeEventListener(Event.CHANGE, _onHalfTurnHandler); dispatchEvent(event); } public function backWait():void{ _removeListener(); _fromLeft.hide(); _fromRight.show(0); _fromRight.wait(); } public function frontWait():void{ _removeListener(); _fromLeft.show(0); _fromRight.hide(); _fromLeft.wait(); } public function hide():void{ _fromLeft.hide(); _fromRight.hide(); } //左の処理 private function _onLeftCompleteHandler(event:Event):void{ _fromLeft.removeEventListener(Event.COMPLETE, _onLeftCompleteHandler) dispatchEvent(event); } //右の処理 private function _onRightCompleteHandler(event:Event):void{ _fromRight.removeEventListener(Event.COMPLETE,_onRightCompleteHandler) dispatchEvent(event); } public function get id():uint { return _id }; } //アニメーションのキャッシュ化クラス class MotionSave extends Shape{ public static const LEFT:String = 'left'; public static const RIGHT:String = 'right'; private var _isLayout:Boolean = false; private var _angle:String;; private var _speed:Number = 0.0035; private var _delay:Number = 0.001; private var _gap:Number = 0.05; private var _turnTransition:String = 'easeInOutSine'; private var _gapTransition:String = 'easeInOutSine'; private var _sp:SegmentPoint, _sourceW:uint, _sourceH:uint, _isRendering:Boolean = false; private var _data:PointListData, _count:uint, _isHalfTurn:Boolean; public function MotionSave(frontSource:BitmapData, backSource:BitmapData = null, segmentX:uint = 1, segmentY:uint = 1){ _sp = new SegmentPoint(false, graphics, frontSource, backSource, segmentX, segmentY); _sourceW = frontSource.width; _sourceH = frontSource.height; _data = new PointListData(segmentX, segmentY); } private function _layout(angle:String):void{ _angle = angle; for (var i:int = 0, len:uint = _sp.points.length; i < len; i++) { _setPosition(_sp.points[i], _sp.defaultPoints[i], angle); } } private function _setPosition(pt:Point, defPt:Point, angle:String):void{ if (angle == MotionSave.RIGHT) { pt.x = _sourceW * 2 - defPt.x; pt.y = defPt.y; }else if (angle == MotionSave.LEFT) { pt.x = -defPt.x; pt.y = defPt.y; } } private function _setTween(pt:Point, defPt:Point, angle:String):Number{ var time:Number, curvePath:Array = []; if (angle == MotionSave.RIGHT){ time = ((1 - defPt.x / _sourceW) * _speed +defPt.y / _sourceH * _delay) * 100; curvePath = [ { y:(defPt.y/_sourceH + _gap)* _sourceH } ]; Tweener.addTween(pt, { x:defPt.x, time:time, transition:_turnTransition}); Tweener.addTween(pt, { y:defPt.y, _bezier:curvePath, time:time, transition:_gapTransition}); }else if (angle == MotionSave.LEFT){ time = (defPt.x / _sourceW * _speed + defPt.y / _sourceH * _delay) * 100; curvePath = [ { y:(defPt.y / _sourceH - _gap) * _sourceH } ]; Tweener.addTween(pt, { x:defPt.x, time:time, transition:_turnTransition}); Tweener.addTween(pt, { y:defPt.y, _bezier:curvePath, time:time, transition:_gapTransition}); } return time; } private function _changeAngle(angle:String):void{ _sp.ascent = (angle == MotionSave.RIGHT) ? false : true; _angle = angle; } private function _removeTweens():void{ for (var i:int = 0, len:uint = _sp.points.length; i < len; i++){ Tweener.removeTweens(_sp.points[i]); } Tweener.removeTweens(this); } private function _startRendering():void{ _count = 0; if (_isRendering) { return }; addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler); _isRendering = true; } private function _stopRendering():void{ if (!_isRendering) { return; } removeEventListener(Event.ENTER_FRAME, _onEnterFrameHandler); _isRendering = false; } public function initLayout(angle:String):void{ if (_isRendering) { _removeTweens(); } _layout(angle); _sp.saveDraw(); _isLayout = true; } public function turn(angle:String):void{ if (angle != null) { _changeAngle(angle); } if (_isRendering) { _removeTweens(); } if (!_isLayout || _angle != angle) { _layout(angle); } var maxTime:Number = 0, time:Number; _isHalfTurn = false; for (var i:int = 0, len:uint = _sp.points.length; i < len; i++){ time = _setTween(_sp.points[i], _sp.defaultPoints[i], angle); if (time > maxTime) { maxTime = time; } } Tweener.addTween(this, { delay:maxTime, onComplete:_onCompleteTween } ); _startRendering(); _isLayout = false; } private function _onCompleteTween():void{ _stopRendering(); _onEnterFrameHandler() dispatchEvent(new Event(Event.COMPLETE)); } private function _onEnterFrameHandler(event:Event = null):void{ _sp.saveDraw(); _data.frontIndices[_count] = _sp.indicesFront; _data.backIndices[_count] = _sp.indicesBack; _data.vertices[_count] = _sp.vertices; if (!_isHalfTurn) { _checkHalfTurn(); } _count++; } private function _checkHalfTurn():void{ for (var i:int = 0, len:uint = _sp.points.length; i < len; i++){ if ((_angle == MotionSave.LEFT && _sp.points[i].x < 0) || (_angle == MotionSave.RIGHT && _sourceW < _sp.points[i].x)) { return; } } _isHalfTurn = true; _data.halfTurnId = _count; } public function get data():PointListData { return _data; } } //キャッシュを元にBitmapDataに対してアニメーションを再現するクラス class MotionLoad extends Shape { private var _isRendering:Boolean = false;//めくっているか private var _isShow:Boolean = false; //見えているか private var _container:DisplayObjectContainer; private var _count:uint; private var _maxCount:uint; private var _sp:SegmentPoint; private var _data:PointListData; public function MotionLoad(container:DisplayObjectContainer, frontSource:BitmapData, backSource:BitmapData, data:PointListData){ _container = container; _data = data.clone(); _data.vertices = _adjustVertices(_data.vertices, frontSource.width, frontSource.height); _maxCount = _data.frontIndices.length; _sp = new SegmentPoint(true, graphics, frontSource, backSource, _data.segmentX, _data.segmentY); } private function _startRendering():void{ if (_isRendering) { return; } addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler); _isRendering = true; } private function _stopRendering():void{ if (!_isRendering) { return; } removeEventListener(Event.ENTER_FRAME, _onEnterFrameHandler); dispatchEvent(new Event(Event.COMPLETE)); _container.setChildIndex(this, 0); _isRendering = false; } private function _adjustVertices(vertices:Vector.<Vector.<Number>>, w:Number, h:Number):Vector.<Vector.<Number>>{ var num:Number, result:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(); for (var j:int = 0; j < vertices.length; j++){ var list:Vector.<Number> = new Vector.<Number>(); for (var i:int = 0; i < vertices[j].length; i++){ num = vertices[j][i]; list[i] = (i % 2 == 0) ? num * w : num * h; } result[j] = list; } return result; } public function move(delayTime:Number = 0.0):void{ _count = 0; if (_isRendering) { Tweener.removeTweens(this) }; if (0 < delayTime) { _onEnterFrameHandler() }; Tweener.addTween(this, { delay:delayTime, onComplete:_startRendering } ); } public function wait():void{ _count = _maxCount -1; _onEnterFrameHandler(); } public function show(depth:Number = NaN):void{ if (_isShow) { return }; if (isNaN(depth)){ _container.addChild(this); }else{ _container.addChildAt(this, depth); } _isShow = true; } public function hide():void{ if (!_isShow) { return }; this.visible; _container.removeChild(this); _isShow = false; } public function setDepth(num:uint):void{ _container.setChildIndex(this, num); } private function _onEnterFrameHandler(e:Event = null):void { if (_count < _maxCount){ _sp.loadDraw(_data.vertices[_count], _data.frontIndices[_count], _data.backIndices[_count]); if (_count == (_data.halfTurnId -4)){ dispatchEvent(new Event(Event.CHANGE)); } _count++; }else{ _stopRendering(); } } } //キャッシュデータの保存クラス class PointListData{ public var segmentX:uint; public var segmentY:uint; public var halfTurnId:uint; public var frontIndices:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(); public var backIndices:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(); public var vertices:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(); public function PointListData(segmentX:uint, segmentY:uint):void{ this.segmentX = segmentX this.segmentY = segmentY; } private function _deepCopy(list:*):*{ var result:ByteArray = new ByteArray(); result.writeObject(list); result.position = 0; return(result.readObject()); } public function clone():PointListData{ var result:PointListData = new PointListData(segmentX, segmentY); result.frontIndices = Vector.<Vector.<int>>(_deepCopy(frontIndices)); result.backIndices = Vector.<Vector.<int>>(_deepCopy(backIndices)); result.vertices = Vector.<Vector.<Number>>(_deepCopy(vertices)); result.halfTurnId = halfTurnId; return result } } //DrawTrianglesによってBitmapDataを分割・描画するクラス class SegmentPoint{ protected var _frontSource:BitmapData; protected var _backSource:BitmapData; private var _graphics:Graphics; private var _divisionW:Number; private var _divisionH:Number; private var _sourceW:Number; private var _sourceH:Number; private var _loadMode:Boolean; private var _isAscent:Boolean = true; private var _points:Vector.<Point>; private var _defaultPoints:Vector.<Point>; private var _indices:Vector.<int>; private var _uvtData:Vector.<Number>; private var _vertices:Vector.<Number>; private var _indicesFront:Vector.<int>; private var _indicesBack:Vector.<int>; public function SegmentPoint(loadMode:Boolean, graphics:Graphics = null, frontSource:BitmapData = null, backSource:BitmapData = null, segmentX:uint = 1, segmentY:uint = 1 ){ _loadMode = loadMode; _graphics = graphics; _frontSource = frontSource; _backSource = backSource; _sourceW = _frontSource.width; _sourceH = _frontSource.height; _divisionW = _frontSource.width / segmentX; _divisionH = _frontSource.height / segmentY; //loadしているなら(?) if (_loadMode){ _uvtData = new Vector.<Number>((segmentX + 1) * (segmentY + 1) * 2, true); }else{ var baseCount:uint = (segmentX + 1) * (segmentY + 1); _uvtData = new Vector.<Number>(baseCount * 2, true); _points = new Vector.<Point>(baseCount, true); } for (var yy:int = 0; yy <= segmentY; yy++){ for (var xx:int = 0; xx <= segmentX; xx++){ _uvSave(xx, yy, segmentX, segmentY); if (!_loadMode){ var id:uint = xx + yy * (segmentX + 1); _points[id] = new Point(xx * _divisionW, yy * _divisionH); } } } if (!_loadMode){ baseCount = (segmentX + 1) * (segmentY + 1); _defaultPoints = new Vector.<Point>(baseCount, true); _indices = new Vector.<int>(baseCount * 6, true); for (yy = 0; yy < segmentY; yy++){ for (xx = 0; xx <= segmentX; xx++){ _indicesSave(xx, yy, segmentX, segmentY); } } _defaultPoints = _pointlistCopy(_points); } } public function saveDraw():void{ var len:uint = _points.length; var trianglePointList:Vector.<Point>; _vertices = new Vector.<Number>(len * 2, true); _indicesFront = new Vector.<int>(); _indicesBack = new Vector.<int>(); for (var k:int = 0; k < len; k++){ var pt:Point = _points[k] as Point; _vertices[k * 2] = pt.x; _vertices[k * 2 + 1] = pt.y; } if (!_backSource){ _indicesFront = _indices; }else{ len = _indices.length / 3; for (var i:int = 0; i < len; i++){ trianglePointList = new Vector.<Point>(3, true); for (var j:int = 0; j < 3; j++){ var id:uint = _indices[ i * 3 + j]; trianglePointList[j] = new Point(_vertices[id * 2], _vertices[id * 2 + 1]); } var flag:Boolean = _frontCheck(trianglePointList); if ((_isAscent) ? flag : !flag){ _indicesFront.push(_indices[i*3], _indices[i*3 + 1], _indices[i*3 + 2]); }else{ _indicesBack.push(_indices[i*3], _indices[i*3 + 1], _indices[i*3 + 2]); } } } } public function loadDraw(vertices:Vector.<Number>, frontIndices:Vector.<int>, backIndices:Vector.<int>):void{ _graphics.clear(); if (frontIndices.length){ _graphics.beginBitmapFill(_frontSource, null, false, true); _graphics.drawTriangles(vertices, frontIndices, _uvtData); } if (backIndices.length){ _graphics.beginBitmapFill(_backSource, null, false, true); _graphics.drawTriangles(vertices, backIndices, _uvtData); } _graphics.endFill(); } private function _uvSave(xx:uint, yy:uint, segmentX:uint, segmentY:uint):void{ var id:uint = xx + yy * (segmentX + 1); _uvtData[id * 2] = xx / segmentX; _uvtData[id * 2 + 1] = yy / segmentY; } private function _conversionToUnitVector(vertices:Vector.<Number>):Vector.<Number>{ var len:uint = vertices.length; var num:Number; var result:Vector.<Number> = new Vector.<Number>(len, true); for (var i:int = 0; i < len; i++){ num = vertices[i]; result[i] = (i % 2 == 0) ? num / _sourceW : num / _sourceH; } return result; } private function _indicesSave(xx:uint, yy:uint, segmentX:uint, segmentY:uint):void{ if (xx < segmentX){ var i:uint = xx + yy * (segmentX + 1); var id:uint = (i - yy) * 6; _indices[id] = i; _indices[id + 1] = i + 1; _indices[id + 2] = i + segmentX + 1; _indices[id + 3] = i + 1; _indices[id + 4] = i + segmentX + 2; _indices[id + 5] = i + segmentX + 1; } } private function _pointlistCopy(list:Vector.<Point>):Vector.<Point>{ var result:Vector.<Point> = new Vector.<Point>(); var len:uint = list.length; for (var i:int = 0; i < len; i++){ result[i] = Point(list[i]).clone(); } return result } private function _frontCheck(list:Vector.<Point>):Boolean{ var num:Number = (list[0].x - list[2].x) * (list[1].y - list[2].y) - (list[0].y - list[2].y) * (list[1].x - list[2].x); return (0 < num) ? true : false; } public function get points():Vector.<Point> { return _points; } public function get defaultPoints():Vector.<Point> { return _defaultPoints; } public function get ascent():Boolean { return _isAscent; } public function set ascent(value:Boolean):void{ if (_isAscent == value) { return }; _indices.reverse(); _isAscent = value; } public function get vertices():Vector.<Number> { return _conversionToUnitVector(_vertices) } public function get indicesFront():Vector.<int> { return _indicesFront; } public function get indicesBack():Vector.<int> { return _indicesBack; } } Code Fullscreen Preview Fullscreen len Event.COMPLETE NativeWindowResize.RIGHT transition time Event.CHANGE dispatchEvent DisplayObjectContainer NativeWindowResize.LEFT Tweener.addTween BitmapData Vector hasEventListener Tweener.removeTweens target Point graphics Boolean setChildIndex addEventListener