<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.5.0/ol.css" type="text/css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="map" tabindex="0"></div>
    <div id="geo-marker"></div>
    
    <script src="//cdnjs.cloudflare.com/ajax/libs/ol3/3.5.0/ol.min.js" type="text/javascript"></script>
    <script src="script.js"></script>
  </body>
</html>
var olview = new ol.View({
    center: [-5483805.05941004,-1884105.3933610613],
    zoom: 16,
    minZoom: 2,
    maxZoom: 20
});

var osm = new ol.source.OSM();

var sourceFeatures = new ol.source.Vector(),
    layerFeatures = new ol.layer.Vector({source: sourceFeatures});
    
    
var lineString = new ol.geom.LineString([]);

var layerRoute =  new ol.layer.Vector({
    source: new ol.source.Vector({
        features: [
            new ol.Feature({ geometry: lineString })
        ]
    }),
    style: [
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                width: 3, color: 'rgba(0, 0, 0, 1)',
                lineDash: [.1, 5]
            }),
            zIndex: 2
        })
    ],
    updateWhileAnimating: true
});


var map = new ol.Map({
    target: 'map',
    view: olview,
    renderer: 'canvas',
    layers: [
      new ol.layer.Tile({ 
          source: osm,
          opacity: 0.6
      }),
      layerRoute, layerFeatures
    ]
});

var markerEl = document.getElementById('geo-marker');
var marker = new ol.Overlay({
    positioning: 'center-center',
    offset: [0, 0],
    element: markerEl,
    stopEvent: false
});
map.addOverlay(marker);


var fill = new ol.style.Fill({color:'rgba(255,255,255,1)'}),
    stroke = new ol.style.Stroke({color:'rgba(0,0,0,1)'}),
    style1 = [
        new ol.style.Style({
            image: new ol.style.Icon(({
                scale: .7, opacity: 1,
                rotateWithView: false, anchor: [0.5, 1],
                anchorXUnits: 'fraction', anchorYUnits: 'fraction',
                src: '//raw.githubusercontent.com/jonataswalker/map-utils/master/images/marker.png'
            })),
            zIndex: 5
        }),
        new ol.style.Style({
            image: new ol.style.Circle({
                radius: 6, fill: fill, stroke: stroke
            }),
            zIndex: 4
        })
    ];


//a simulated path
var path = [
    [-5484116.753984261,-1884416.14606312],
    [-5484122.765236764,-1884331.5428025876],
    [-5484104.954118238,-1884303.7679013235],
    [-5484051.409443166,-1884282.2685246097],
    [-5483805.05941004,-1884105.3933610613],
    [-5483669.249631273,-1884063.0922822598],
    [-5483599.118352073,-1883979.3038447134],
    [-5483475.553717293,-1883769.6598181103]
];


var feature1 = new ol.Feature({
        geometry: new ol.geom.Point(path[0])
    }),
    feature2 = new ol.Feature({
        geometry: new ol.geom.Point(path[path.length - 1])
    });
    
feature1.setStyle(style1);
feature2.setStyle(style1);
sourceFeatures.addFeatures([feature1, feature2]);

lineString.setCoordinates(path);


//fire the animation
map.once('postcompose', function(event) {
    console.info('postcompose');
    interval = setInterval(animation, 500);
});

var i = 0, interval;
var animation = function(){
    
    if(i == path.length){
        i = 0;
    }

    marker.setPosition(path[i]);
    i++;
};
html, body, #map{
    width: 100%;
    height: 100%;
}
#map{
    position:absolute;
    z-index:1;
    top:0; bottom:0;
}
#geo-marker{
    width: 10px; height: 10px;
    border: 1px solid #088;
    border-radius: 5px;
    background-color: #0b968f;
    opacity: 0.8;
}