package com.publicreative.pv.interaction { import flash.display.Sprite; import flash.display.Stage; import flash.geom.Point; import org.papervision3d.view.layer.util.ViewportLayerSortMode; import com.publicreative.utils.MathUtils; import flash.display.DisplayObject; import org.papervision3d.objects.DisplayObject3D; import flash.events.MouseEvent; /** * ... * @author Mark Stewart :: http://www.publicreative.com */ public class MouseGrab { public static const X:String = "x"; public static const Y:String = "y"; public static const Z:String = "z"; public static const XY:String = "xy"; public static const XZ:String = "xz"; public static const YZ:String = "yz"; public static const HORIZONTAL:String = "horiz"; public static const VERTICAL:String = "vert"; private var _do :DisplayObject3D; private var _base:DisplayObject; private var _init:Boolean = false; private var _currentPoint:Point; private var _startPoint:Point; private var _mouseDown:Boolean = false; private var _camRx:Number = 0; private var _camRy:Number = 0; private var _downPoint:Point; private var _percentX:Number; private var _percentY:Number; private var _horizontalType:String; private var _verticalType:String; private var _vMultiplier:Number; private var _vEase:Number; private var _vLow:Number; private var _vHigh:Number; private var _vRadius:Number; private var _hMultiplier:Number; private var _hEase:Number; private var _hLow:Number; private var _hHigh:Number; private var _hRadius:Number; public function MouseGrab( displayObject3d:DisplayObject3D , base:DisplayObject ) { super(); _do = displayObject3d; _base = base; } public function addSingleAxis( movement:String , axis:String , multiplier:Number = 1000, ease:Number = 10, lowLimit:Number = -2000 , highLimit:Number = 2000 , startOffset:Number = 90 ):void { if (axis == XY || axis == XZ || axis == YZ) throw new Error("For multiple axis movement use addDoubleAxis function"); if (!_init) addListeners(); if (movement == HORIZONTAL) { _horizontalType = axis; _hMultiplier = multiplier; _hEase = ease; _hLow = lowLimit; _hHigh = highLimit; _downPoint.offset(startOffset, 0); } else { _verticalType = axis; _vMultiplier = multiplier; _vEase = ease; _vLow = lowLimit; _vHigh = highLimit; _downPoint.offset(0, startOffset); } } public function addDoubleAxis( movement:String ,axis:String ,radius:Number= 1000,multiplier:Number = 1000, ease:Number = 10 , startOffset:Number = 90):void { if (axis == X || axis == Z || axis == Y) throw new Error("For single axis movement use addSingleAxis function"); if (!_init) addListeners(); if (movement == HORIZONTAL) { _horizontalType = axis; _hMultiplier = multiplier; _hEase = ease; _hRadius = radius; _downPoint.offset(startOffset, 0); } else { _verticalType = axis; _vMultiplier = multiplier; _vEase = ease; _vRadius = radius; _downPoint.offset(0, startOffset); } } private function addListeners():void { _init = true; _currentPoint = new Point(0,0); _startPoint = new Point(0,0); _downPoint = new Point( 0,0 ); _base.addEventListener( MouseEvent.MOUSE_DOWN, mouseDown , false , 0 , true); _base.addEventListener( MouseEvent.MOUSE_UP , mouseUp , false , 0 , true); } private function mouseDown(ev:MouseEvent):void { _startPoint = new Point(_base.stage.mouseX , _base.stage.mouseY); _downPoint = new Point(_camRx , _camRy); _mouseDown = true; } private function mouseUp(ev:MouseEvent):void { _mouseDown = false; } public function processFrame():void { if(_mouseDown) { _currentPoint.x = _base.mouseX; _currentPoint.y = _base.mouseY; } switch( _verticalType) { case X: { _percentY = (_currentPoint.y - _startPoint.y) / _base.stage.stageHeight; _camRy = _downPoint.y + (_percentY * _vMultiplier); if (_camRy < _vLow) _camRy = _vLow; if (_camRy > _vHigh) _camRy = _vHigh; _do.x += (_camRy - _do.x) / _vEase; break; } case Y: { _percentY = (_currentPoint.y - _startPoint.y) / _base.stage.stageHeight; _camRy = _downPoint.y + (_percentY * _vMultiplier); if (_camRy < _vLow) _camRy = _vLow; if (_camRy > _vHigh) _camRy = _vHigh; _do.y += (_camRy - _do.y) / _vEase; break; } case Z: { _percentY = (_currentPoint.y - _startPoint.y) / _base.stage.stageHeight; _camRy = _downPoint.y + (_percentY * _vMultiplier); if (_camRy < _vLow) _camRy = _vLow; if (_camRy > _vHigh) _camRy = _vHigh; _do.z += (_camRy - _do.z) / _vEase; break; } case XY: { _percentY = (_currentPoint.y - _startPoint.y)/_base.stage.stageHeight; _camRy = _downPoint.y + (_percentY * _vMultiplier / 5); _do.x += ((Math.cos( MathUtils.toRadians( _camRy )) * _vRadius) - _do.x) / _vEase; _do.y += ((Math.sin( MathUtils.toRadians( _camRy )) * -_vRadius) - _do.y) / _vEase; break; } case XZ: { _percentY = (_currentPoint.y - _startPoint.y)/_base.stage.stageHeight; _camRy = _downPoint.y + (_percentY * _vMultiplier / 5); _do.x += ((Math.cos( MathUtils.toRadians( _camRy )) * _vRadius) - _do.x) / _vEase; _do.z += ((Math.sin( MathUtils.toRadians( _camRy )) * -_vRadius) - _do.z) / _vEase; break; } case YZ: { _percentY = (_currentPoint.y - _startPoint.y)/_base.stage.stageHeight; _camRy = _downPoint.y + (_percentY * _vMultiplier / 5); _do.y += ((Math.cos( MathUtils.toRadians( _camRy )) * _vRadius) - _do.y) / _vEase; _do.z += ((Math.sin( MathUtils.toRadians( _camRy )) * -_vRadius) - _do.z) / _vEase; break; } } switch( _horizontalType) { case X: { _percentX = (_currentPoint.x - _startPoint.x) / _base.stage.stageWidth; _camRx = _downPoint.x + (_percentX * _hMultiplier); if (_camRx < _hLow) _camRx = _hLow; if (_camRx > _hHigh) _camRx = _hHigh; _do.x += (_camRx - _do.x) / _hEase; break; } case Y: { _percentX = (_currentPoint.x - _startPoint.x) / _base.stage.stageWidth; _camRx = _downPoint.x + (_percentX * _hMultiplier); if (_camRx < _hLow) _camRx = _hLow; if (_camRx > _hHigh) _camRx = _hHigh; _do.y += (_camRx - _do.y) / _hEase; break; } case Z: { _percentX = (_currentPoint.x - _startPoint.x) / _base.stage.stageWidth; _camRx = _downPoint.x + (_percentX * _hMultiplier); if (_camRx < _hLow) _camRx = _hLow; if (_camRx > _hHigh) _camRx = _hHigh; _do.z += (_camRx - _do.z) / _hEase; break; } case XY: { _percentX = (_currentPoint.x - _startPoint.x)/_base.stage.stageWidth; _camRx = _downPoint.x + (_percentX * _hMultiplier / 5); _do.x += ((Math.cos( MathUtils.toRadians( _camRx )) * _hRadius) - _do.x) / _hEase; _do.y += ((Math.sin( MathUtils.toRadians( _camRx )) * _hRadius) - _do .y) / _hEase; break; } case XZ: { _percentX = (_currentPoint.x - _startPoint.x)/_base.stage.stageWidth; _camRx = _downPoint.x + (_percentX * _hMultiplier / 5); _do.x += ((Math.cos( MathUtils.toRadians( _camRx )) * _hRadius) - _do.x) / _hEase; _do.z += ((Math.sin( MathUtils.toRadians( _camRx )) * -_hRadius) - _do.z) / _hEase; break; } case YZ: { _percentX = (_currentPoint.x - _startPoint.x)/_base.stage.stageWidth; _camRx = _downPoint.x + (_percentX * _hMultiplier / 5); _do.y += ((Math.cos( MathUtils.toRadians( _camRx )) * _hRadius) - _do.y) / _hEase; _do.z += ((Math.sin( MathUtils.toRadians( _camRx )) * -_hRadius) - _do.z) / _hEase; break; } } } } }