/plugins/mstandio/UniversalMap/navigation/MapViewer.as
http://universalmap.googlecode.com/ · ActionScript · 560 lines · 397 code · 72 blank · 91 comment · 60 complexity · 565d435fef3ea85da1c53641c6b5da9a MD5 · raw file
- package plugins.mstandio.UniversalMap.navigation {
-
- /**
- * MapViewer provides masked map, and dragging interface if needed
- * it also executes updates on maps and navigation points
- * casted form UniversalMap
- * drag and scalling based on http://blog.des84.com/2009/04/16/drag-large-images-updated-now-with-zoom.des84
- * @author mstandio
- */
-
- import flash.display.Loader;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.display.Bitmap;
- import flash.events.MouseEvent;
- import flash.ui.Mouse;
- import flash.net.URLRequest;
- import flash.events.IOErrorEvent;
- import flash.system.ApplicationDomain;
- import flash.utils.getDefinitionByName;
- import flash.utils.getQualifiedClassName;
-
- import gs.TweenLite;
-
- import plugins.mstandio.UniversalMap.UniversalMap;
- import plugins.mstandio.UniversalMap.navigation.*;
- import plugins.mstandio.utils.combobox.ComboBox;
-
- public class MapViewer extends Sprite {
-
- [Embed(source="../images/interface/hand_closed.png")]
- private var Bitmap_handClosed:Class;
- [Embed(source="../images/interface/hand_opened.png")]
- private var Bitmap_handOpened:Class;
- [Embed(source = '../images/interface/map_navigation_move.png')]
- private var Bitmap_mapNavigationMove :Class;
- [Embed(source = '../images/interface/map_navigation_zoom.png')]
- private var Bitmap_mapNavigationZoom :Class;
-
-
- private var mapMask:Sprite;
- private var mapMaskWidth:Number;
- private var mapMaskHeight:Number;
-
- private var mapContainer:Sprite; // contains map image and navigation points, masked by mapMask
-
- private var map:Map; // Data structure containing url of image, name and array of naviagtion points
- private var mapChanged:Boolean; // if update comes from new space on same map or from new map
-
- private var mapImage:Loader; // External image
- private var mapWidth:Number; // Size of external image
- private var mapHeight:Number;
-
- private var cursor:Bitmap; // Grabbing hand cursor
- private var mouseOver:Boolean;
- private var dragActive:Boolean; // If grabbing hand is dragging map
- private var normalCursorForced:Boolean; // When mouse moves over NavigationPoint
-
- private var mapNavigation:Sprite; // container for mapNavigationMove and mapNavigationZoom
- private var mapNavigationMove:Sprite; // alternative to dragging navigation that scrolls map
- private var mapNavigationZoom:Sprite; // additional buttons for dragging
-
- private var mapNavigationSpeed:Number; // see constructor
- private var mapNavigationZoomSpeed:Number;
- private var mapNavigationZoomMax:Number;
-
- private var params:NavigationPointParameters; // passed down to specific NavigationPoint
-
- /**
- * Constructor - captain obvoius strikes back
- * @param map
- * @param mapMaskWidth
- * @param mapMaskHeight
- * @param params
- */
- public function MapViewer(map:Map, mapMaskWidth:Number, mapMaskHeight:Number, params:NavigationPointParameters) {
-
- this.map = map;
-
- this.mapMaskWidth = mapMaskWidth;
- this.mapMaskHeight = mapMaskHeight;
- this.params = params;
-
- /****hard-coded params if you wanna change them, well, good luck*****************/
- this.mapNavigationSpeed = 15; // Speed of scrolling with navigation arrows
- this.mapNavigationZoomSpeed = 0.15; // Scale change after map zoom
- this.mapNavigationZoomMax = 1.5; // Scale for maximum zoom
- /********************************************************************************/
-
- this.normalCursorForced = false;
- this.dragActive = false;
-
- this.mapMask = new Sprite();
- this.mapMask.graphics.beginFill(0x000000);
- this.mapMask.graphics.drawRect(0, 0, this.mapMaskWidth, this.mapMaskHeight);
- this.mapMask.graphics.endFill();
- this.addChild(mapMask);
-
- this.mapContainer = new Sprite();
- this.mapContainer.mask = mapMask;
- this.addChild(mapContainer);
-
- this.loadMap();
- }
-
- /**
- * loading map from requested url
- */
- private function loadMap():void {
-
- this.mapImage = new Loader();
- var request:URLRequest = new URLRequest(this.map.mapUrl);
- this.mapImage.load(request);
- this.mapImage.contentLoaderInfo.addEventListener(Event.COMPLETE, mapLoaded);
- this.mapImage.addEventListener(IOErrorEvent.IO_ERROR, mapNotLoaded);
- }
-
- /**
- * When Map is loaded
- * @param e
- */
- private function mapLoaded(e:Event):void {
- this.mapImage.removeEventListener(Event.COMPLETE, mapLoaded);
- this.mapImage.removeEventListener(IOErrorEvent.IO_ERROR, mapNotLoaded);
-
- this.mapWidth = e.target.width; // size of image
- this.mapHeight = e.target.height;
-
- this.mapChanged = true;
-
- this.mapContainer.addChild(this.mapImage);
- this.determineDrag(); // if dragging interface is needed
-
- this.updateNavigationPoints(this.params); // places navigation points on map Container according to recieved params
- }
-
- /**
- * When map is not loaded
- * @param e
- */
- private function mapNotLoaded(e:Event):void {
- this.mapImage.removeEventListener(IOErrorEvent.IO_ERROR, mapNotLoaded);
- this.mapImage.removeEventListener(Event.COMPLETE, mapNotLoaded);
- TweenLite.killDelayedCallsTo(loadMap);
- TweenLite.delayedCall(3, loadMap);
- }
-
- /**
- * Determines if size of map reqiures dragging interface
- */
- private function determineDrag():void {
- // if image size is bigger then map window
- if ((this.mapHeight > this.mapMaskHeight) || (this.mapWidth > this.mapMaskWidth)) {
- // if dragging hasn't been activated yet
- if(dragActive == false){
- this.dragActive = true;
- mapContainer.addEventListener(MouseEvent.ROLL_OVER, overMc);
- mapContainer.addEventListener(MouseEvent.ROLL_OUT, outMc);
- mapContainer.addEventListener(MouseEvent.MOUSE_MOVE, moveMc);
- mapContainer.addEventListener(MouseEvent.MOUSE_DOWN, dragMc);
- mapContainer.addEventListener(MouseEvent.MOUSE_UP, unDragMc);
- cursor = new Bitmap(new Bitmap_handOpened().bitmapData);
- cursor.name = "cursor";
- cursor.alpha = 1 / UniversalMap.mapAlpha;
- cursor.visible = false;
- parent.addChild(cursor);
- if (this.mapNavigation == null) {
- this.buildMapNavigation();
- }
- this.addChild(this.mapNavigation);
- this.mapNavigationZoom.visible = this.map.mapAllowZoom;
- }
- }
- // image is smaller than map window or size is equal
- else {
- // if it hasnt been deactivated yet
- if (dragActive = true) {
- this.dragActive = false;
- mapContainer.removeEventListener(MouseEvent.ROLL_OVER, overMc);
- mapContainer.removeEventListener(MouseEvent.ROLL_OUT, outMc);
- mapContainer.removeEventListener(MouseEvent.MOUSE_MOVE, moveMc);
- mapContainer.removeEventListener(MouseEvent.MOUSE_DOWN, dragMc);
- mapContainer.removeEventListener(MouseEvent.MOUSE_UP, unDragMc);
- if (this.getChildByName("cursor") != null) {
- removeChild(getChildByName("cursor"));
- }
- if (this.getChildByName("mapNavigation") != null) {
- removeChild(getChildByName("mapNavigation"));
- }
- }
- this.mapContainer.x = this.mapMaskWidth * 0.5 - this.mapContainer.width * 0.5; // center map
- this.mapContainer.y = this.mapMaskHeight* 0.5 - this.mapContainer.height * 0.5;
- }
-
- // if MapNavigation has been placed or removed then replace Combobox
- (UniversalMap(root)).placeComboBox();
- }
-
- /**
- * Checks state of each navigation point and updates its state with params
- * @param params
- */
- public function updateNavigationPoints(params:NavigationPointParameters):void {
- if(this.mapChanged){
- // removes all navigation points and map
- while (this.mapContainer.numChildren) {
- if (this.mapContainer.getChildAt(0) is this.getClass(NavigationPoint)) {
- NavigationPoint(this.mapContainer.getChildAt(0)).killCam();
- }
- this.mapContainer.removeChildAt(0);
- }
- this.mapContainer.addChild(this.mapImage);
- }
- this.params = params;
- var somePointShowing:Boolean = false; // determines if map should scroll to the center or not
-
- for each(var navigationPoint:NavigationPoint in map.navigationPoints) {
- if (this.mapChanged) {
- // adding navigation points again
- this.mapContainer.addChild(navigationPoint);
- navigationPoint.restorebeforeZoom();
- }
-
- if ((params.currentSpace == navigationPoint.targetSpace) || (params.currentSpace + ".preview" == navigationPoint.targetSpace) || (params.currentSpace == navigationPoint.targetSpace + ".preview")) {
- // point represents current space
- navigationPoint.showCam(params);
- navigationPoint.focus();
- somePointShowing = true;
- }else {
- // point doesnt represent current space
- if (this.mapChanged) {
- navigationPoint.killCam();
- }else{
- navigationPoint.hideCam();
- }
- }
- }
-
- this.mapChanged = false;
-
- // scroll to the center of the map, couse current map has no point representing current space
- if (!somePointShowing) {
- this.gotoXY(this.mapImage.width / 2, this.mapImage.height / 2, true);
-
- // set child index of showing point to highest value
- }else {
- for each(navigationPoint in map.navigationPoints) {
- if ((params.currentSpace == navigationPoint.targetSpace) || (params.currentSpace + ".preview" == navigationPoint.targetSpace) || (params.currentSpace == navigationPoint.targetSpace + ".preview")) {
- this.mapContainer.setChildIndex(navigationPoint, this.mapContainer.numChildren - 1);
- break;
- }
- }
- }
-
- UniversalMap(root).firstShowWindow();
-
- }
-
- /**
- * Updates MapViewer with new map and new parameters of camera for navigation point
- * @param map
- * @param params
- */
- public function changeMap(map:Map, params:NavigationPointParameters):void {
- // removes all navigation points and map
- TweenLite.killTweensOf(this.mapContainer);
- this.mapContainer.x = this.mapContainer.y = 0;
- while (this.mapContainer.numChildren){
- this.mapContainer.removeChildAt(0);
- }
-
-
- this.map = map;
- this.params = params;
-
- // begin map building
- this.loadMap();
- }
-
- /**
- * Returning to normal cursor for entering NavigationPoint
- * casted from NavigationPoint
- * @param e
- */
- public function forceNormalCursor(command:Boolean):void {
- if(this.dragActive){
- if (command) {
- this.normalCursorForced = true;
- }else{
- this.normalCursorForced = false;
- }
- }
- }
-
- /**
- * Adds mapNavigation with navigation buttons
- */
- private function buildMapNavigation():void {
-
- this.mapNavigation = new Sprite();
- this.mapNavigation.name = "mapNavigation";
-
- // building mapNavigationMove
- this.mapNavigationMove = new Sprite();
- var m_n:Bitmap = new Bitmap(new Bitmap_mapNavigationMove().bitmapData);
- mapNavigationMove.addChild(m_n);
- var goLeft:Sprite = new Sprite();
- goLeft.graphics.beginFill(0x000000,0);
- goLeft.graphics.drawRect(0, 0, 15, 15);
- goLeft.graphics.endFill();
- goLeft.buttonMode = true;
- mapNavigationMove.addChild(goLeft);
- var goRight:Sprite = new Sprite();
- goRight.graphics.beginFill(0x000000,0);
- goRight.graphics.drawRect(0, 0, 15, 15);
- goRight.graphics.endFill();
- goRight.buttonMode = true;
- mapNavigationMove.addChild(goRight);
- var goUp:Sprite = new Sprite();
- goUp.graphics.beginFill(0x000000,0);
- goUp.graphics.drawRect(0, 0, 15, 15);
- goUp.graphics.endFill();
- goUp.buttonMode = true;
- mapNavigationMove.addChild(goUp);
- var goDown:Sprite = new Sprite();
- goDown.graphics.beginFill(0x000000,0);
- goDown.graphics.drawRect(0, 0, 15, 15);
- goDown.graphics.endFill();
- goDown.buttonMode = true;
- mapNavigationMove.addChild(goDown);
- goLeft.y = m_n.height * 0.5 - goLeft.height * 0.5;
- goRight.y = m_n.height * 0.5 - goLeft.height * 0.5;
- goRight.x = m_n.width - goRight.width;
- goUp.x = m_n.width * 0.5 - goUp.width * 0.5;
- goDown.x = m_n.width * 0.5 - goDown.width * 0.5 ;
- goDown.y = m_n.height - goDown.height ;
- goLeft.addEventListener(MouseEvent.CLICK, mapNavLeft);
- goRight.addEventListener(MouseEvent.CLICK, mapNavRight);
- goUp.addEventListener(MouseEvent.CLICK, mapNavUp);
- goDown.addEventListener(MouseEvent.CLICK, mapNavDown);
- this.mapNavigationMove.x = this.mapNavigationMove.y = 2;
-
- this.mapNavigation.addChild(this.mapNavigationMove);
-
- // building mapNavigationZoom
- this.mapNavigationZoom = new Sprite();
- this.mapNavigationZoom.name = "mapNavigationZoom";
- var m_n_z:Bitmap = new Bitmap(new Bitmap_mapNavigationZoom().bitmapData);
- mapNavigationZoom.addChild(m_n_z);
- var zoomIn:Sprite = new Sprite();
- zoomIn.graphics.beginFill(0x000000,0);
- zoomIn.graphics.drawRect(0, 0, 21, 18);
- zoomIn.graphics.endFill();
- zoomIn.buttonMode = true;
- mapNavigationZoom.addChild(zoomIn);
- var zoomOut:Sprite = new Sprite();
- zoomOut.graphics.beginFill(0x000000,0);
- zoomOut.graphics.drawRect(0, 0, 21, 18);
- zoomOut.graphics.endFill();
- zoomOut.buttonMode = true;
- mapNavigationZoom.addChild(zoomOut);
- zoomIn.x = m_n_z.width * 0.5 - zoomIn.width * 0.5;
- zoomOut.y = m_n_z.height - zoomOut.height ;
- zoomOut.x = m_n_z.width * 0.5 - zoomOut.width * 0.5 ;
- zoomIn.addEventListener(MouseEvent.CLICK, mapZoomIn);
- zoomOut.addEventListener(MouseEvent.CLICK, mapZoomOut);
- this.mapNavigationZoom.x = (this.mapNavigationMove.width +this.mapNavigationMove.x) * 0.5 - this.mapNavigationZoom.width * 0.5;
- this.mapNavigationZoom.y = this.mapNavigationMove.y + this.mapNavigationMove.height + 8; // 8 is vertical distance between mapNavigation and mapNavigationZoom
- this.mapNavigation.alpha = 1 / UniversalMap.mapAlpha;
- this.mapNavigation.addChild(mapNavigationZoom);
- }
-
- private function mapNavLeft(e:MouseEvent):void {
- this.gotoXY(-mapContainer.x-mapNavigationSpeed, -mapContainer.y+(mapMaskHeight*0.5));
- }
- private function mapNavRight(e:MouseEvent):void {
- this.gotoXY(-mapContainer.x+mapMaskWidth+mapNavigationSpeed, -mapContainer.y+(mapMaskHeight*0.5));
- }
- private function mapNavUp(e:MouseEvent):void {
- this.gotoXY(-mapContainer.x+(mapMaskWidth*0.5), -mapContainer.y-mapNavigationSpeed);
- }
- private function mapNavDown(e:MouseEvent):void {
- this.gotoXY(-mapContainer.x+(mapMaskWidth*0.5), -mapContainer.y+mapMask.height+mapNavigationSpeed);
- }
-
- private function mapZoomIn(e:MouseEvent):void {
-
- var xScaleOld:Number = this.mapImage.scaleX;
- var yScaleOld:Number = this.mapImage.scaleY;
- var widthOld:Number = this.mapImage.width;
-
- if ((this.mapImage.width * (xScaleOld + this.mapNavigationZoomSpeed)) / this.mapWidth <= this.mapNavigationZoomMax) {
-
- this.mapImage.scaleX = (xScaleOld + this.mapNavigationZoomSpeed);
- this.mapImage.scaleY = (yScaleOld + this.mapNavigationZoomSpeed);
- verifyDrag(new Event(Event.ENTER_FRAME));
- this.rescalePoints((this.mapImage.width) / widthOld);
- }
- }
- private function mapZoomOut(e:MouseEvent):void {
- var xScaleOld:Number = this.mapImage.scaleX;
- var yScaleOld:Number = this.mapImage.scaleY;
-
- var widthOld:Number = this.mapImage.width;
- var heightOld:Number = this.mapImage.height;
- this.mapImage.scaleX = (xScaleOld - this.mapNavigationZoomSpeed);
- this.mapImage.scaleY = (yScaleOld - this.mapNavigationZoomSpeed);
-
- if (this.mapImage.width <= this.mapMaskWidth || this.mapImage.height <= this.mapMaskHeight ){
- if ( this.mapImage.width <= this.mapMaskWidth ){
- this.mapImage.width = this.mapMaskWidth;
- this.mapImage.height = this.mapMaskWidth / (widthOld / heightOld);
- }else if (this.mapImage.height <= this.mapMaskHeight) {
- this.mapImage.height = this.mapMaskHeight;
- this.mapImage.width = (widthOld / heightOld) * this.mapMaskHeight;
- }
- }
-
- verifyDrag(new Event(Event.ENTER_FRAME));
- this.rescalePoints((this.mapImage.width)/widthOld);
- }
-
- /**
- * Rescales all present navigation points
- * @param ratio
- */
- private function rescalePoints(ratio:Number):void {
- for (var i:Number = 0; i<this.mapContainer.numChildren ; i++ ) {
- this.mapContainer.getChildAt(i);
- if (this.mapContainer.getChildAt(i) is this.getClass(NavigationPoint)) {
- NavigationPoint(this.mapContainer.getChildAt(i)).rescale(ratio);
- }
- }
- // go to zoomed point
- this.gotoXY( ((this.mapMaskWidth * 0.5 - this.mapContainer.x) * ratio) , ((this.mapMaskHeight * 0.5 - this.mapContainer.y ) * ratio ), false);
- }
-
- /**
- * Moves map to specified position
- * @param x
- * @param y
- */
- public function gotoXY(x:Number, y:Number, useTween:Boolean=true):void {
- if (this.dragActive && x>0 && y>0 && x<= this.mapWidth && y<= this.mapHeight) {
- var x:Number = x;
- var y:Number = y;
- x = (x < this.mapMask.width * 0.5) ? this.mapMask.width * 0.5 :
- ((x > this.mapImage.width - this.mapMask.width * 0.5) ? this.mapImage.width - this.mapMask.width * 0.5 : x);
- y = (y < this.mapMask.height * 0.5) ? this.mapMask.height * 0.5 :
- ((y > this.mapImage.height - this.mapMask.height * 0.5) ? this.mapImage.height - this.mapMask.height * 0.5 : y);
- if (useTween) {
- TweenLite.to(this.mapContainer, 1, { x: - x + this.mapMaskWidth * 0.5 , y: - y + mapMaskHeight * 0.5 } )
- }else {
- this.mapContainer.x = - x + this.mapMaskWidth * 0.5;
- this.mapContainer.y = - y + this.mapMaskHeight * 0.5;
- }
- }
- }
-
-
- /**
- * mouse enters mapMask
- */
- private function overMc(m:MouseEvent):void {
- this.cursor.x = mouseX - this.cursor.width * 0.5;
- this.cursor.y = mouseY;
- this.mouseOver = true;
- Mouse.hide();
- this.cursor.visible = true;
- }
-
- /**
- * mouse leaves mapMask
- */
- private function outMc(m:MouseEvent):void {
- this.mouseOver = false;
- Mouse.show();
- cursor.visible = false;
- }
-
- /**
- * Displays dragging hand
- */
- private function moveMc(m:MouseEvent):void {
- this.cursor.x = mouseX - this.cursor.width * 0.5;
- this.cursor.y = mouseY;
- if (mouseOver && !this.normalCursorForced) {
- this.cursor.visible = true;
- Mouse.hide();
- }else{
- this.cursor.visible = false;
- Mouse.show();
- }
- }
-
- /**
- * Starts dragginng
- */
- private function dragMc(m:MouseEvent):void {
- if (!this.normalCursorForced) {
- TweenLite.killTweensOf(this.mapContainer);
- mapContainer.startDrag();
- mapContainer.addEventListener(Event.ENTER_FRAME, verifyDrag);
- cursor.bitmapData = new Bitmap_handClosed().bitmapData;
-
- for each(var navigationPoint:NavigationPoint in map.navigationPoints) {
- if (navigationPoint.getShowing()) {
- navigationPoint.setUnFocused();
- }
- }
- }
- }
-
- /**
- * Stops dragginng
- */
- private function unDragMc(m:MouseEvent):void {
- mapContainer.stopDrag();
- mapContainer.removeEventListener(Event.ENTER_FRAME, verifyDrag);
- cursor.bitmapData = new Bitmap_handOpened().bitmapData;
- if (mouseOver && !this.normalCursorForced) {
- verifyDrag(new Event(Event.ENTER_FRAME));
- }
- }
-
- /**
- * Corrects location of dragged Sprite if it goes out of mapMask
- * also cancels dragging if clicked mouse goes out of mapMask
- */
- private function verifyDrag(e:Event):void{
- if ( mapContainer.x > mapMask.x ){
- mapContainer.x = mapMask.x;
- }
- if ( mapContainer.x < (( mapMask.x + mapMask.width) - this.mapImage.width ) ){
- mapContainer.x = (( mapMask.x + mapMask.width) - this.mapImage.width );
- }
- if ( mapContainer.y > mapMask.y ){
- mapContainer.y = mapMask.y;
- }
- if ( mapContainer.y < (( mapMask.y + mapMask.height ) - this.mapImage.height ) ){
- mapContainer.y = (( mapMask.y + mapMask.height ) - this.mapImage.height );
- }
- if (!mouseOver){
- mapContainer.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));
- }
- }
-
- public function getDragActive():Boolean {
- return this.dragActive;
- }
-
- public function getNavigationWidth():Number {
- return this.mapNavigation.width;
- }
-
- public function getClass(obj:Object):Class {
- return Class(getDefinitionByName(getQualifiedClassName(obj)));
- }
- }
- }