HaxeMaps / Jednoduchá animace

V této ukázce vytvoříme mapu, která bude obsahovat vrstvu, jejíž obsah bude časově proměnný. Pro jednoduchost budeme postupně animovat průběh trasy zaznamenané z navigace.

1. Zdrojový kód

Struktura kódu je obdobou předchozích ukázek. Třída AnimLayer v konstruktoru načte jednotlivé body trasy ze serveru a jakmile jsou načteny, je aktivován časovač, který zajišťuje animaci (periodický update obsahu vektorové vrstvy). Animace je realizována tak, že je postupně vykreslováno více a více bodů trasy.

example07.hx

  1. import flash.display.Sprite;
  2. import flash.events.Event;
  3. import map.Canvas;
  4. import map.LngLat;
  5. import map.MapService;
  6. import com.Button;
  7. import com.ToolBar;
  8.  
  9. class Example07 extends Sprite {
  10.  
  11.     var canvas:Canvas;
  12.     var toolbar:ToolBar;
  13.  
  14.     static public function main()
  15.     {
  16.        flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
  17.        var t:Example07 = new Example07();
  18.        flash.Lib.current.stage.addEventListener(Event.RESIZE, t.stageResized);
  19.        flash.Lib.current.stage.addChildAt(t,0);
  20.     }
  21.  
  22.  
  23.     function new()
  24.     {
  25.         super();
  26.    
  27.         toolbar = new ToolBar();
  28.         canvas = new Canvas();
  29.  
  30.         toolbar.move(0, 0);
  31.         canvas.move(0, 0);
  32.         canvas.setCenter(new LngLat(16.6, 49.2));
  33.         canvas.addLayer(new map.TileLayer(new OpenStreetMapService(), 8));
  34.         canvas.addLayer(new VectorLayer(refresh));
  35.         canvas.setZoom(-2);
  36.         stageResized(null);
  37.  
  38.         initToolbar();
  39.  
  40.         addChild(canvas);
  41.         addChild(toolbar);
  42.  
  43.         canvas.initialize();
  44.     }
  45.  
  46.     public function stageResized(e:Event)
  47.     {
  48.         toolbar.setSize(flash.Lib.current.stage.stageWidth, 30);
  49.         canvas.setSize(flash.Lib.current.stage.stageWidth, flash.Lib.current.stage.stageHeight);
  50.     }
  51.  
  52.     function initToolbar()
  53.     {
  54.         var me = this;
  55.         toolbar.addButton(new ZoomOutButton(), "Zoom Out", function(b:CustomButton) { me.canvas.zoomOut(); });
  56.         toolbar.addButton(new ZoomInButton(), "Zoom In",  function(b:CustomButton) { me.canvas.zoomIn(); });
  57.     }
  58.  
  59.     function refresh(lng:Float, lat:Float, dist:Float)
  60.     {
  61.         canvas.panTo(new LngLat(lng, lat));
  62.         toolbar.setText("Total dist.: "+dist+" km");
  63.     }
  64. }
  65.  
  66. import flash.net.URLLoader;
  67. import flash.net.URLRequest;
  68. import flash.utils.ByteArray;
  69. import flash.geom.Point;
  70. import flash.utils.Timer;
  71. import flash.events.TimerEvent;
  72. import map.Layer;
  73.  
  74. typedef Refresh = Float -> Float -> Float -> Void;
  75.  
  76. class VectorLayer extends Layer
  77. {
  78.     static var URL:String = "http://localhost/path.bin";
  79.  
  80.     var plon:Array<Float>;
  81.     var plat:Array<Float>;
  82.     var colors:Array<Int>;
  83.     var maxlen:Int;
  84.     var timer:Timer;
  85.     var refresh:Refresh;
  86.  
  87.     public function new(refresh: Refresh)
  88.     {
  89.         super();
  90.  
  91.         this.refresh = refresh;
  92.         this.timer = new Timer(50, 0);
  93.         this.plon = new Array<Float>();
  94.         this.plat = new Array<Float>();
  95.  
  96.         var urlLoader:URLLoader = new URLLoader();
  97.         urlLoader.dataFormat = flash.net.URLLoaderDataFormat.BINARY;
  98.         urlLoader.addEventListener(Event.COMPLETE, processData);
  99.         urlLoader.addEventListener(flash.events.IOErrorEvent.IO_ERROR,
  100.                                     function(e) { trace("Can't load data");}
  101.                                    );
  102.         try {
  103.             var urlRequest:URLRequest = new URLRequest(URL);
  104.             urlLoader.load(urlRequest);
  105.         } catch (unknown : Dynamic)  {
  106.             trace("Error - Unable to load data");
  107.         }
  108.  
  109.         maxlen = 0;
  110.     }
  111.  
  112.     function processData(e:Event)
  113.     {
  114.         var loader:URLLoader = e.target;
  115.         loader.removeEventListener(Event.COMPLETE, processData);
  116.  
  117.         var b:ByteArray = loader.data;
  118.         try
  119.         {
  120.            b.uncompress();
  121.  
  122.            var len:Int =  b.readUnsignedShort();
  123.            for (i in 0...len)
  124.            {
  125.                plon.push(b.readDouble());
  126.                plat.push(b.readDouble());
  127.            }
  128.  
  129.            timer.addEventListener(TimerEvent.TIMER, animate);
  130.            timer.start();
  131.  
  132.            updateContent(true);
  133.  
  134.         }
  135.         catch (unknown : Dynamic)  
  136.         {
  137.             trace("Error - Unable to read data");
  138.         }
  139.     }
  140.  
  141.     function animate(e:TimerEvent)
  142.     {
  143.         if (maxlen < plon.length)
  144.         {
  145.            maxlen++;
  146.            if (maxlen % 20 == 0)
  147.            {
  148.  
  149.               //calc total distance
  150.               var dist:Float = 0;
  151.               for (i in 1...maxlen)
  152.                  dist += LngLat.distance(new LngLat(plon[i],plat[i]), new LngLat(plon[i-1],plat[i-1]));
  153.               dist = Std.int(dist / 100.0) / 10.0;
  154.  
  155.               //pan canvas to the last point, update info
  156.               refresh(plon[maxlen-1], plat[maxlen-1], dist);
  157.            }
  158.  
  159.            //redraw content
  160.            updateContent(true);
  161.         }
  162.         else
  163.         {
  164.            timer.stop();
  165.            timer.removeEventListener(TimerEvent.TIMER_COMPLETE, animate);
  166.         }
  167.     }
  168.  
  169.     override function updateContent(forceUpdate:Bool=false)
  170.     {
  171.         if (!forceUpdate) return;
  172.  
  173.         var z:Int = this.mapservice.zoom_def + this.zoom;
  174.         var l2pt = this.mapservice.lonlat2XY;
  175.         var cpt:Point = l2pt(center.lng, center.lat, z);
  176.         var pt:Point;
  177.  
  178.         //draw the path
  179.         graphics.clear();
  180.         graphics.lineStyle(4,0xFF0000);
  181.         for (i in 0...maxlen)
  182.         {
  183.             pt = l2pt(plon[i], plat[i], z);
  184.             if (i == 0)
  185.                graphics.moveTo((pt.x - cpt.x), (pt.y - cpt.y));
  186.             else
  187.                graphics.lineTo((pt.x - cpt.x), (pt.y - cpt.y));
  188.         }
  189.  
  190.     }
  191. }
  192.  

Poznámka: Z důvodu efektivnosti by bylo dostačující vykreslit pouze nový bod, vrstvu není nezbytně nutné překreslovat stále celou.

2. Výsledek

Pro správnou funkci je vyžadován Flash player
   


Deprecated: Function ereg() is deprecated in /home2/web/homes/vasicek/private/notes/web/data/map/examples.php on line 12

Zobrazeno: 997x Naposledy: 3.4.2024 12:24:29