2013-04-10 148 views
1

我有一個以.ai格式顯示的美國地圖。我想在我的Flex應用程序中使用它。
問題是地圖切片狀態線,我想操縱應用程序內的狀態。Adob​​e Illustrator到Flash Builder 4.6

說明:在我的應用程序中,我希望能夠點擊一個國家來突出顯示它,並將所有其他國家趕出現場,然後再將所有國家帶回來使整個國家。就像一個拼圖遊戲。

我將Adobe Illustrator中的FXG文件導入到了Flash Builder 4中的Flex應用程序中,但我無法一次處理每個狀態!

會真的很感謝幫助! 歡呼聲

+2

在Flex應用程序,如果你想以不同的方式處理它們,你需要個人資產爲每個地圖件。否則,你將不得不做一些位圖處理,這聽起來像一條非常複雜的路線。 – JeffryHouser 2013-04-11 00:30:34

+0

感謝您的建議!我已經開始走下去了... :( – 2013-04-11 00:40:55

回答

1

我最終轉換到FXG MXML ...

我用下面的代碼來做到這一點:

FXG to MXML Converter

我改變

d:userlabel

到屬性ID和它的工作非常好!...

+0

不知道,感謝分享(+1) – 2013-04-17 20:19:47

1

有一個FxgParser庫,但它似乎沒有輸出狀態名稱,如果它們在.fxg文件中標記爲d:userLabel屬性。你可以修改源代碼來解決這個問題。

下面是如何::

編輯fxgparser.parser.Path.as然後在類的頂部添加此命名空間:

public static const aab:Namespace = new Namespace("aab", "http://ns.adobe.com/fxg/2008/dt"); 

然後在解析()方法的末尾添加此:

target.name = [email protected]::userLabel; 

爲插畫CS6似乎增加,而不是ID或其他東西,並FxgParser在默認情況下會忽略這個編號userLabel屬性。

代碼將是非常類似上面:

package { 

    import flash.display.*; 
    import flash.events.*; 
    import flash.geom.Point; 
    import flash.net.*; 
    import flash.utils.Dictionary; 

    import com.greensock.*; 
    import fxgparser.FxgDisplay; 

    [SWF(width='1368', height='936', backgroundColor='#ffffff', frameRate='30')] 
    public class FXGTest extends Sprite{ 

     private var states:Sprite;//container holding each state Shape 
     private var positions:Dictionary = new Dictionary();//original position to restore states to 

     public function FXGTest() { 
      addEventListener(Event.ADDED_TO_STAGE,init); 
     } 
     private function init(e:Event):void{ 
      new URLLoader(new URLRequest("usa-wikipedia.fxg")).addEventListener(Event.COMPLETE,fxgLoaded); 
     } 
     private function fxgLoaded(e:Event):void{ 
      //trace(e.target.data); 
      var map:FxgDisplay = addChild(new FxgDisplay(new XML(e.target.data))) as FxgDisplay; 
      trace(listChildren(map)); 
      //map.item.item.item.* 
      states = Sprite(Sprite(Sprite(map.getChildAt(0)).getChildAt(0)).getChildAt(0)); 
      for(var i:int = 0 ; i < states.numChildren; i++){ 
       var s:DisplayObject = DisplayObject(states.getChildAt(i));//can't add mouse listeners because the states are Shape instances 
       positions[s.name] = new Point(s.x,s.y);//store the positions in a hash to get the state position by name 
      } 
      stage.addEventListener(MouseEvent.CLICK,handleClick); 
     } 
     private function handleClick(e:MouseEvent):void{ 
      if(e.target is Stage) restore(); 
      else blast(getObjectsUnderPoint(new Point(mouseX,mouseY))[0].name);//named shapes are stored in a sprite so use getObjetsUnderPoint 
     } 
     private function blast(name:String):void{ 
      var blastRadius:Number = stage.stageWidth+stage.stageHeight;//or some other number 
      var c:DisplayObject = states.getChildByName(name);//selected 
      for(var i:int = 0 ; i < states.numChildren; i++){ 
       var s:DisplayObject = states.getChildAt(i); 
       if(s != c){//everything else goes except this 
        var angle:Number = Math.atan2(s.y-c.y,s.x-c.x);//direction relative to the clicked state 
        var x:Number = s.x + (Math.cos(angle) * blastRadius);//get a position offset from the clicked state (blast centre) 
        var y:Number = s.y + (Math.sin(angle) * blastRadius);//outwards at a random angle 
        TweenLite.to(s,1+Math.random() * 2,{x:x,y:y});//tween with different speeds for a bit of depth 
       } 
      } 
     } 
     private function restore():void{ 
      for(var i:int = 0 ; i < states.numChildren; i++){ 
       var s:DisplayObject = DisplayObject(states.getChildAt(i)); 
       TweenLite.to(s,.5+Math.random() * .5,{x:positions[s.name].x,y:positions[s.name].y});//tween states back into the original positions 
      } 
     } 
     private function listChildren(d:DisplayObjectContainer):String{ 
      var result = 'parent: '+d.name+'\n\t'; 
      for(var i:int = 0 ; i < d.numChildren; i++){ 
       var c:DisplayObject = d.getChildAt(i); 
       result += '\tchild: '+c.name+'\n'; 
       if(c is DisplayObjectContainer) result += listChildren(DisplayObjectContainer(c)); 
      } 
      return result; 
     } 


    } 

} 

您也可以下載上面的類,改性fxgparser圖書館和國家FXG 01​​,看到正在運行的演示here 或者您可以使用SVG而不是FXG 。同樣的開發商也有一個SvgParser庫,你可以像這樣:

svn export http://www.libspark.org/svn/as3/SvgParser 

您可以將您的文件。愛易保存爲.svg文件。 下面是使用一個簡單的例子US map from wikipedia

package { 
    import flash.display.*; 
    import flash.events.*; 
    import flash.geom.Point; 
    import flash.net.*; 
    import flash.utils.Dictionary; 

    import svgparser.SvgDisplay; 
    import com.greensock.*; 

    [SWF(width='1368', height='936', backgroundColor='#ffffff', frameRate='30')] 
    public class SVGTest extends Sprite { 

     private var states:Sprite;//container holding each state Shape 
     private var positions:Dictionary = new Dictionary();//original position to restore states to 

     public function SVGTest() { 
      addEventListener(Event.ADDED_TO_STAGE,init);//make sure we have the stage ready 
     } 
     private function init(e:Event):void{ 
      removeEventListener(Event.ADDED_TO_STAGE,init);//stage ready, load the svg 
      new URLLoader(new URLRequest("http://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg")).addEventListener(Event.COMPLETE,svgLoaded); 
     } 
     private function svgLoaded(e:Event):void{//svg loaded 
      var map:SvgDisplay = addChild(new SvgDisplay(new XML(e.target.data))) as SvgDisplay;//use the parser 
      trace(listChildren(map));//quick debug of the maps display list 
      states = Sprite(map.getChildAt(0));//we want to access the main container 
      for(var i:int = 0 ; i < states.numChildren; i++){ 
       var s:DisplayObject = DisplayObject(states.getChildAt(i));//can't add mouse listeners because the states are Shape instances 
       positions[s.name] = new Point(s.x,s.y);//store the positions in a hash to get the state position by name 
      } 
      stage.addEventListener(MouseEvent.CLICK,handleClick); 
     } 
     private function handleClick(e:MouseEvent):void{ 
      if(e.target is Stage) restore(); 
      else blast(getObjectsUnderPoint(new Point(mouseX,mouseY))[0].name);//named shapes are stored in a sprite so use getObjetsUnderPoint 
     } 
     private function blast(name:String):void{ 
      var blastRadius:Number = stage.stageWidth+stage.stageHeight;//or some other number 
      for(var i:int = 0 ; i < states.numChildren; i++){ 
       var s:DisplayObject = states.getChildAt(i); 
       if(s.name != name){//everything else goes except this 
        var angle:Number = Math.random() * Math.PI * 2;//pick a random angle 
        var x:Number = s.x + Math.cos(angle) * blastRadius;//get a position offset from the clicked state (blast centre) 
        var y:Number = s.y + Math.sin(angle) * blastRadius;//outwards at a random angle 
        TweenLite.to(s,1+Math.random() * 2,{x:x,y:y});//tween with different speeds for a bit of depth 
       } 
      } 
     } 
     private function restore():void{ 
      for(var i:int = 0 ; i < states.numChildren; i++){ 
       var s:DisplayObject = DisplayObject(states.getChildAt(i)); 
       TweenLite.to(s,.5+Math.random() * .5,{x:positions[s.name].x,y:positions[s.name].y});//tween states back into the original positions 
      } 
     } 
     private function listChildren(d:DisplayObjectContainer):String{//recursively traverse a display list and list children names 
      var result = 'parent: '+d.name+'\n\t'; 
      for(var i:int = 0 ; i < d.numChildren; i++){ 
       var c:DisplayObject = d.getChildAt(i); 
       result += '\tchild: '+c.name+'\n'; 
       if(c is DisplayObjectContainer) result += listChildren(DisplayObjectContainer(c)); 
      } 
      return result; 
     } 

    } 

}