前回同様 Advanced ActionScript 3.0 Animation を参考に画像を筒状に並べて3D回転させてみた。
サンプルでは Rotate Carousel(回転木馬)と名前がついていた。
サンプルは Shape を並べていて表裏が関係ない、Bitmap に置換えるときに注意が必要。
Flash Player 10 で追加された3D関連のクラスを把握するのに時間がかかりそうな予感。
Matrix3d, Vector3D, PerspectiveProjection が重要な働きをしている。
Demo : Rotate Carousel v.1 - Flash Player 10 が必要です。
ポップアップされたウインドウをリサイズすると面白い。
もう一つ。
PerspectiveProjection.fieldOfView
を小さくしたものを作った。
Demo : Rotate Carousel v.2 - Flash Player 10 が必要です。
全ての画像が見えるようになると、手前の画像が表を向いている必要があるので、v.2 では rotationY を +180 している。
PerspectiveProjection.fieldOfView
は魚眼効果を出す働きがある。
値が大きいと効果も大きくなる、0 から 180 の間で設定できる。
package { import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.display.Sprite; import flash.display.DisplayObject; import flash.display.Bitmap; import flash.geom.Vector3D; import flash.geom.Point; [SWF(backgroundColor=0xFFFFFF, frameRate='24')] public class RotateCarousel extends Sprite { [Embed(source="dim1.png")] private var dim1:Class; [Embed(source="dim2.png")] private var dim2:Class; [Embed(source="dim3.png")] private var dim3:Class; [Embed(source="dim4.png")] private var dim4:Class; [Embed(source="dim5.png")] private var dim5:Class; [Embed(source="dim6.png")] private var dim6:Class; private var _images:Array; private var _num:uint; private var _surfaces:Array; private var _sprite:Sprite; private var _radius:uint = 300; public function RotateCarousel() { super(); stage.addEventListener(Event.RESIZE, resizeHandler); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; root.transform.perspectiveProjection.fieldOfView = 50;// v.1 : 130 _sprite = new Sprite(); _sprite.x = stage.stageWidth / 2; _sprite.y = stage.stageHeight / 2; _sprite.z = 300;//v.1 : 0 addChild(_sprite); _images = [dim1, dim2, dim3, dim4, dim5, dim6]; _num = _images.length; var n:uint = _num; _surfaces = []; for (var i:int = 0; i < n; i++) { var angle:Number = Math.PI * 2 / n * i; var s:Sprite = makeSurface(i); s.x = Math.cos(angle) * _radius; s.z = Math.sin(angle) * _radius; s.rotationY = -360 / n * i + 90; s.rotationY += 180;//v.1 : 0 _surfaces[_surfaces.length] = s; } sortSurfaces(); addEventListener( Event.ENTER_FRAME, enterFrameHandler ); } private function makeSurface(n:uint):Sprite { var d:Bitmap = new _images[n]() as Bitmap; var s:Sprite = new Sprite(); s.addChild(d) d.x = -100; d.y = -100; _sprite.addChild(s); return s; } private function resizeHandler(event:Event):void { root.transform.perspectiveProjection.projectionCenter = new Point(stage.stageWidth / 2, stage.stageHeight / 2); _sprite.x = stage.stageWidth / 2; _sprite.y = stage.stageHeight / 2; } private function enterFrameHandler(event:Event):void { _sprite.rotationY += (stage.stageWidth / 2 - mouseX) * .01; _sprite.y += (mouseY - _sprite.y) * .1; sortSurfaces(); } private function sortSurfaces():void { _surfaces.sort(depthSort); for (var i:int = 0; i < _surfaces.length; i++) { _sprite.addChildAt(_surfaces[i] as Sprite, i); } } private function depthSort(objA:DisplayObject, objB:DisplayObject):int { var posA:Vector3D = objA.transform.matrix3D.position; posA = _sprite.transform.matrix3D.deltaTransformVector(posA); var posB:Vector3D = objB.transform.matrix3D.position; posB = _sprite.transform.matrix3D.deltaTransformVector(posB); return posB.z - posA.z; } } } |
TextMate + Flex SDK 3.3