📄 cubeform.as
字号:
/**************************************************************
CubeForm.as
Created by: Derrick Grigg
derrick@dgrigg.com
http://www.dgrigg.com
Created on: April 18, 2007
Version: 1.0.0
This is released under a Creative Commons license. More information can be found here:
http://creativecommons.org/licenses/by/2.5/
***************************************************************/
package com.dgrigg.containers
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageQuality;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.utils.clearInterval;
import flash.utils.setInterval;
import flash.geom.Point;
import flash.events.Event;
import mx.core.UIComponent;
import mx.containers.ViewStack;
import mx.core.Container;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.objects.Plane;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.materials.BitmapMaterial;
/**
* Dispatched after cube rotates to selected side.
*/
[Event(name="change",type="flash.events.Event")]
/**
* Renders a view stack as a 3d cube using the PaperVision engine.
* The cube can rotate to the 6 different sides to display a view
* from the view stack and allow the user to interact with it.
*/
public class CubeForm extends UIComponent
{
/**
* Papervision camerea.
*/
protected var camera:Camera3D;
/**
* Papervision scene.
*/
protected var scene:Scene3D;
/**
* Sprite that form is rendered in.
*/
protected var sprite:Sprite;
/**
* Value to store a reference to the rotation interval.
*/
protected var intRotate:int;
/**
* @private
*/
protected var _selectedIndex: int = 0;
/**
* Array of the six planes that make up the cube.
* Each item in the array consists of a <code>plane</code> which is the Papervision Plane
* and a <code>view</code> which is a reference to the child in the view stack.
*/
protected var planes:Array;
/**
* The view stack the form is bound to.
*/
protected var _viewStack:ViewStack;
/**
* Root display object for the cube form.
*/
protected var rootNode:DisplayObject3D;
/**
* Number of steps used to rotate the cube;
*
* @default 10
*/
public var rotationSteps:int = 10;
/**
* @param canvas The sprite to generate the cube form in.
*/
public function CubeForm(canvas:Sprite)
{
sprite = canvas;
init();
}
private function init():void
{
var s:Stage = sprite.stage;
s.quality = StageQuality.BEST;
setupScene();
}
private function setupScene():void
{
scene = new Scene3D(sprite);
camera = new Camera3D();
camera.zoom = 10;
camera.focus = 100;
rootNode = scene.addChild(new DisplayObject3D(), 'rootNode');
scene.renderCamera(camera);
}
/**
* The view stack that is bound to the cube form.
* <ul>
* <li>The view stack must have atleast six children, otherwise an error will be thrown.</li>
* <li>The view stack must have it's <code>creationPolicy</code> property set to <code>all</code>.</li>
* <li>Each view in the view stack must have it's width and height explicity set,
* otherwise the view does not get rendered properly during initialization.</li>
* </ul>
*
*/
public function set viewStack (vs:ViewStack):void
{
var plane: Plane;
var view:Container;
planes = new Array();
_viewStack = vs;
//check to see if there are 6 views in the view stack
//if no throw an error
var children:Array = _viewStack.getChildren();
if (children.length > 5)
{
view = children[0] as Container;
plane = createPlane(view, 0 , 0 ,-(_viewStack.width/2));
rootNode.addChild(plane, 'plane0');
planes.push({plane:plane, view:view});
view = children[1] as Container;
plane = createPlane(view, (_viewStack.width/2), 0, 0, 0, 270, 0);
rootNode.addChild(plane, 'plane1');
planes.push({plane:plane, view:view});
view = children[2] as Container;
plane =createPlane(view, 0, 0, (_viewStack.width/2), 0, 180, 0);
rootNode.addChild(plane, 'plane2');
planes.push({plane:plane, view:view});
view = children[3] as Container;
plane =createPlane(view, -(_viewStack.width/2), 0, 0, 0, 90, 0);
rootNode.addChild(plane, 'plane3');
planes.push({plane:plane, view:view});
view = children[4] as Container;
plane =createPlane(view, 0, (_viewStack.width/2), 0, 270, 0, 0);
rootNode.addChild(plane, 'plane4');
planes.push({plane:plane, view:view});
view = children[5] as Container;
plane =createPlane(view, 0, -(_viewStack.width/2), 0, 90, 0, 0);
rootNode.addChild(plane, 'plane5');
planes.push({plane:plane, view:view});
//render the scene to get determine the rendered dimensions
scene.renderCamera( camera );
//position the view stack directly over the cube form
var p:Point = sprite.localToGlobal(new Point(0,0));
_viewStack.x = p.x - _viewStack.width/2;
_viewStack.y = p.y - _viewStack.height/2;
//adjust the camera zoom to compensate for any scaling that has occurred,
//in order to keep the cube at the exact scale of the view stack
camera.zoom = (_viewStack.width/sprite.width)*10;
scene.renderCamera(camera);
} else {
var error:Error = new Error('Error: the viewStack must contain at least six children');
throw(error);
}
}
/**
* @private
*/
protected function createPlane(panel:UIComponent, pX:int=0, pY:int=0, pZ:int=0, pRotationX:int=0, pRotationY:int=0, pRotationZ:int=0):Plane
{
var bmp:BitmapData = new BitmapData(_viewStack.width, _viewStack.height);
bmp.draw(panel);
var material:BitmapMaterial = new BitmapMaterial(bmp);
material.smooth = true;
var initObj:Object = {x:pX, y:pY, z:pZ, rotationX:pRotationX, rotationY: pRotationY, rotationZ:pRotationZ};
var plane:Plane = new Plane(material, bmp.width, bmp.height, 4, 4, initObj);
return plane;
}
/**
* Index of selected plane on the cube form.
*
* @default 0
*/
public function get selectedIndex():int
{
return _selectedIndex;
}
public function set selectedIndex(val:int):void
{
//get the selected plane and re-render that side in order
//to reflect the current data on the view
var obj:Object = planes[_selectedIndex];
var plane:Plane = obj.plane as Plane;
var bmp:BitmapData = new BitmapData(obj.view.width, obj.view.height);
bmp.draw(obj.view);
var material:BitmapMaterial = new BitmapMaterial(bmp);
plane.material = material;
this.scene.renderCamera( camera );
obj.view.visible = false;
//get the current cube's rotation values
_selectedIndex = val;
var curRotation:Object = {x:rootNode.rotationX, y:rootNode.rotationY, z:rootNode.rotationZ};
var destRotation:Object;
switch (_selectedIndex)
{
case 0:
destRotation = {x: 0, y:0, z:0};
break;
case 1:
destRotation = {x: 0, y:90, z:0};
break;
case 2:
destRotation = {x: 0, y:180, z:0};
break;
case 3:
destRotation = {x: 0, y:270, z:0};
break;
case 4:
destRotation = {x: 90, y:0, z:0};
break;
case 5:
destRotation = {x: 270, y:0, z:0};
break;
}
var steps: Object = new Object();
steps.x = Math.floor((destRotation.x - curRotation.x)/rotationSteps);
steps.y = Math.floor((destRotation.y - curRotation.y)/rotationSteps);
steps.z = Math.floor((destRotation.z - curRotation.z)/rotationSteps);
intRotate = setInterval(rotateCube, 50, steps, destRotation);
}
private function rotateCube(steps:Object, dest:Object):void
{
if (Math.abs(rootNode.rotationX) != dest.x) rootNode.rotationX += steps.x;
if (Math.abs(rootNode.rotationY) != dest.y) rootNode.rotationY += steps.y;
if (Math.abs(rootNode.rotationX) != dest.z) rootNode.rotationZ += steps.z;
scene.renderCamera( camera );
if (Math.abs(rootNode.rotationX) == dest.x && Math.abs(rootNode.rotationY) == dest.y && Math.abs(rootNode.rotationZ) == dest.z)
{
//reset the rotation values back to a value <= 360
if (Math.abs(rootNode.rotationX) >= 360) rootNode.rotationX = Math.abs(rootNode.rotationX) - 360;
if (Math.abs(rootNode.rotationY) >= 360) rootNode.rotationY = Math.abs(rootNode.rotationY) - 360;
if (Math.abs(rootNode.rotationZ) >= 360) rootNode.rotationZ = Math.abs(rootNode.rotationZ) - 360;
clearInterval(intRotate);
_viewStack.selectedIndex = _selectedIndex;
dispatchEvent(new Event(Event.CHANGE));
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -