- 円周3Dスライド(AS3.0)
-
-
-
マウスのホイール操作に対応して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);
}
}
}
|