topBanner  
globalMenu_top globalMenu_profile globalMenu_picture globalMenu_story globalMenu_blog globalMenu_sample globalMenu_mail
円周3Dスライド(AS3.0)

このページのコンテンツには、Adobe Flash Player の最新バージョンが必要です。

Adobe Flash Player を取得

マウスのホイール操作に対応して3D上で回転するメニューを作ってみました。
ネタ元はこちらのサイトです。
格好良かったので真似てみました。

まず、3DのライブラリであるPapervision3Dを使います。
このときのポイントですが、Y座標とZ座標にそれぞれsin()とcos()を割り当てて円周上にオブジェクトを 配置していったとき、cos()がマイナスになるとマテリアル(張っている絵)が180度回転してしまいました。

メモ.

そこで、cos()がマイナスになるところでは、マテリアルを張ったオブジェクトを180度回転させて修正しました

次に、画面奥に表示されるオブジェクトについては、ぼかしをかけて遠近感を表現しました。
参考プログラムによると、DisplayObject3Dの「useOwnContainer」というプロパティにフィルターをかけられるとの事で、早速実装しました。

メモ.

Papervision3Dのオブジェクトにフィルターをかけたい場合は、「useOwnContainer」というプロパティを使う。
さらに、「useOwnContainer」を使うとワールド座標も取得できる!

これで完成! と思いきや、まだ罠がありました。
完成したFlashをHTMLに埋め込むと、マウスのホイールボタンが反応しないのです orz

それについても調べました。参考サイトによると、HTMLタグ属性「wmode」の設定が影響しているらしいです。

DreamweaverでFLASHファイル(SWF)をHTMLに埋め込むと、自動的に「wmode」属性を持ったタグが埋め込まれるのでそれを削除してやっとFLASHが動作しました。

メモ.

HTMLにFLASHを埋め込んだ場合、FLASHに対してマウスホイールが効かない場合がある。
そのときは、「wmode」属性を持ったタグを削除するか、JavaScriptでマウスホイールの設定をFLASHに移すという処理が必要になる↓

使用ライブラリ.
Papervision3D
ソースコード. ※jpg画像は別途用意する必要があります
package {
	import flash.display.*;
	import flash.events.*;
	import flash.filters.BlurFilter;

	//papervision3Dクラスをインポート
	import org.papervision3d.scenes.*;
	import org.papervision3d.objects.*;
	import org.papervision3d.objects.primitives.*;
	import org.papervision3d.cameras.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.materials.utils.*;
	import org.papervision3d.view.*;
	import org.papervision3d.render.*;

	public class circleMenu3D extends Sprite {
		// _______________________________________________________________________
		//■プロパティ宣言
		private var _scene:Scene3D;
		private var _camera:Camera3D;
		private var _viewport:Viewport3D;
		private var _renderer:BasicRenderEngine;
		private var _material:BitmapFileMaterial;
		private var _rootNode:DisplayObject3D;
		private var _objHolder:Array = [];
		private var _objLength:int = 10;
		private var _counter:Number = 0;
		private var _targetNow:Number = 0;
		private var _movingNow:Boolean = false;
		private var _blurList:Array = [];

		// _______________________________________________________________________
		//■コンストラクタ
		public function circleMenu3D():void {
			//ステージ設定
			stage.frameRate = 60;
			stage.quality = "BEST";
			stage.scaleMode = "noScale";
			stage.align = StageAlign.TOP_LEFT;
			initialize3D();
		}

		// _______________________________________________________________________
		//■3D空間の初期設定
		private function initialize3D():void {
			var i:int;

			//3Dシーン生成
			_scene = new Scene3D  ;

			//ビューポートの生成
			_viewport = new Viewport3D(this.stage.stageWidth,this.stage.stageHeight);

			//カメラ設定
			_camera = new Camera3D  ;
			_camera.z = -2000;
			_camera.focus = 500;
			_camera.zoom = 1;

			//画面にビューポートを追加
			this.addChild(_viewport);

			//描画エンジンの生成
			_renderer = new BasicRenderEngine  ;

			//rootNode生成
			_rootNode = new DisplayObject3D  ;
			_scene.addChild(_rootNode);

			//マテリアルを格納する配列
			var _materialHolder:Array = new Array();

			//マテリアル生成
			for(i=0; i<_objLength; i++){
				_material = new BitmapFileMaterial("samples/" + i + ".jpg");
				//裏面も表示する
				_material.doubleSided = true;
				_material.smooth = true;
				_materialHolder.push(_material);
			}
						
			//オブジェクト生成
			for (i=0; i<_objLength; i++) {
				var planeObj = new Plane(_materialHolder[i],200,200,4,4);
				_objHolder.push(planeObj);
			}
			
			var obj:DisplayObject3D;
			var deg:Number = 360 / _objHolder.length;
			var radius:int = 1200;
			
			//円周上にオブジェクトを配置
			for (i=0; i<_objHolder.length; i++) {
				obj = _objHolder[i];
				_rootNode.addChild(obj);
				obj.x = 0;
				obj.y = Math.sin(i * deg * Math.PI / 180) * radius;
				obj.z = -(Math.cos(i * deg * Math.PI / 180) * radius);
				obj.lookAt(_rootNode);
				//cos()がマイナスの場合はオブジェクトを反転させる
				if(i>2&&i<8) obj.roll(180);
				//深度を表現するために必要
				obj.useOwnContainer = true;
			}

			// イベント呼び出し
			stage.addEventListener(Event.ENTER_FRAME,drawFrame);
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, MouseWheelFunc);
		}

		// _______________________________________________________________________
		//■マウスホイールイベント
		function MouseWheelFunc(event:MouseEvent) {
			// ホイールの回転方向を判定し、現在の回転を制御する変数に蓄積
			if (event.delta > 0) _targetNow++;
			else if (event.delta < 0) _targetNow--;
			_movingNow = true;
		}

		// _______________________________________________________________________
		//■ENTER_FRAMEイベント処理
		private function drawFrame(event:Event):void {
			if(_movingNow){
				if(_targetNow>0){
					_counter += 6;
					_rootNode.rotationX+=6;
					if(_counter == 36){
						_counter = 0;
						_targetNow--;
					}
				}
				else if(_targetNow<0){
					_counter -= 6;
					_rootNode.rotationX-=6;
					if(_counter == -36){
						_counter = 0;
						_targetNow++;
					}
				}else{
					_movingNow = false;
				}
			}
			//ワールド座標からぼかし具合を判定
			for (var i:int=0; i<_objHolder.length; i++) {
				var obj:DisplayObject3D = _objHolder[i] as DisplayObject3D;
				if(obj.sceneZ>0) obj.filters = [new BlurFilter(3, 3, 2)];
				else obj.filters = [new BlurFilter(0, 0, 2)];
			}
			
			//cameraから見たsceneをviewportに描画
			_renderer.renderScene(_scene, _camera, _viewport);
		}
	}
}