forked from: PV3D Carousel
Papervision3Dで被写界深度
* 参照: http://clockmaker.jp/blog/2008/07/pv3d_gw_blur/
// forked from tkinjo's PV3D Carousel
// forked from clockmaker's [PV3D] Field of Blur
/**
* Papervision3Dで被写界深度
* 参照: http://clockmaker.jp/blog/2008/07/pv3d_gw_blur/
*/
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.BlurFilter;
import mx.managers.CursorManager;
import org.papervision3d.core.effects.view.ReflectionView;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.MovieAssetMaterial;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Plane;
import com.flashdynamix.motion.Tweensy;
import fl.motion.easing.*;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
/**
* ...
* @author tkinjo
*/
public class Main extends ReflectionView
{
private static const ITEM_LENGTH:uint = 6;
private static const CAROUSEL_RADIUS:uint = 500;
private var carouselItems:Vector.<Plane>;
public function Main()
{
viewport.interactive = true;
surfaceHeight = -100;
camera.y = 100;
viewport.containerSprite.buttonMode = true;
// コンテナの生成
var container:DisplayObject3D = new DisplayObject3D();
scene.addChild( container );
// carousel の要素を生成
carouselItems = new Vector.<Plane>();
for ( var i:uint = 0; i < ITEM_LENGTH; i++ ) {
// Plane を生成
var movieAsset:MovieClip = new MovieClip();
movieAsset.graphics.beginFill( 0xffffff * Math.random() );
movieAsset.graphics.drawRect( 0, 0, 200, 100 );
movieAsset.graphics.endFill();
var material:MovieMaterial = new MovieMaterial ( movieAsset );
material.doubleSided = true;
var carouselItem:Plane = new Plane( material, movieAsset.width, movieAsset.height );
// イベントの設定
material.interactive = true;
carouselItem.addEventListener( InteractiveScene3DEvent.OBJECT_OVER, carouselItemOverHandler );
carouselItem.addEventListener( InteractiveScene3DEvent.OBJECT_PRESS, carouselItemPressHandler );
// 位置の決定
var angle:Number = 360 * i / ITEM_LENGTH + 180;
carouselItem.x = CAROUSEL_RADIUS * Math.sin( angle * Math.PI / 180 );
carouselItem.z = CAROUSEL_RADIUS * Math.cos( angle * Math.PI / 180 );
// フィルタをかける準備
carouselItem.useOwnContainer = true
container.addChild( carouselItem );
carouselItems.push( carouselItem );
}
addEventListener( Event.ENTER_FRAME, enterFrameHandler );
}
private function enterFrameHandler( event:Event ):void {
for ( var i:int = 0; i < ITEM_LENGTH; i++ ) {
var carouselItem:Plane = carouselItems[ i ] as Plane;
var blur:Number = Math.ceil( ( carouselItem.sceneZ + CAROUSEL_RADIUS ) / 500 );
carouselItem.filters = [ new BlurFilter( blur, blur, 2 ) ];
}
singleRender();
}
private function carouselItemOverHandler( event:InteractiveScene3DEvent ):void {
//new CursorManager
//CursorManager.removeCursor( cursorID );
}
private function carouselItemPressHandler( event:InteractiveScene3DEvent ):void {
// 変数名は適当…
var pressedItem:Plane = event.target as Plane;
var container:DisplayObject3D = pressedItem.parent as DisplayObject3D;
var pressedItemPositionDegree:Number = 360 * carouselItems.indexOf( pressedItem ) / carouselItems.length;
var containerRotationY:Number = ( container.rotationY % 360 > 0 ) ? container.rotationY % 360 : container.rotationY % 360 + 360;
var frontItemPositionDegree:Number = 360 - containerRotationY;
var relativeDegreeTemp:Number = pressedItemPositionDegree - frontItemPositionDegree;
var relativeDegree:Number = ( relativeDegreeTemp > 0 ) ? relativeDegreeTemp : 360 + relativeDegreeTemp;
// Math.round は 179.99... 対策
var rotation:Number = container.rotationY - ( ( Math.round( relativeDegree ) < 180 ) ? relativeDegree : -( 360 - relativeDegree ) );
Tweensy.to( container, { rotationY:rotation } );
for ( var i:uint = 0; i < carouselItems.length; i++ ) {
Tweensy.to( carouselItems[ i ], { rotationY:-rotation } );
}
}
}
}