1
votes

I want to make "camera follow" effect on feature while its moves along path. The feature is moved using requestAnimationFrame, here is the example code:

var lastFrame = +new Date;
var updateSlider = function () {
    var now = +new Date, deltaTime = now - lastFrame;
    trackValue += deltaTime;
    self.move(trackValue);
    lastFrame = now;
    self.Timer = requestAnimationFrame(updateSlider);
};
updateSlider();

.move = function (timestamp) {
 var point = LineString.getCoordinateAtM(timestamp);
 if(point) Feature.setCoordinate(point);
 this.followCamera();
};

I tried a few options of centering the view. And it works, but the problem is that the map jitters. Need help on getting rid of the jitter.

See this OL example - http://openlayers.org/en/latest/examples/geolocation-orientation.html, to see map jitters, press "Simulate"

.followCamera = function() {
 var extent = Feature.getGeometry().getExtent();
 A) view.set('center', ol.extent.getCenter(extent);
 B) view.setCenter(ol.extent.getCenter(extent); 
 C) view.animate({center: ol.extent.getCenter(extent)});
 D) view.fit(extent) <- Not usable in my case, because i want to zoom in/out manually
};

Also you can try this example (taken from ol examples) - https://jsfiddle.net/32z45kLo/5/ - try with and without setCenter part at moveFeature function (line 152)

Here is the video - https://youtu.be/L96HgWZi6Lo

2
I think it depends of the specs of the client machine because for me there is no jitters, that's look fluid enough - Below the Radar
hmm, interesting, can you please tell me your specs? i'm currently running on i3, intel hd graphics 4600 with 512 mb and 16 gb RAM - line88
Ok after looking more carefully I think I see what you are talking about... it's more the pinpoint that jitter right? Maybe something is debounced in the code? Here i7, integrated 1gb hd graphics, 16gb ram - Below the Radar
Map rotation, is really fluid for me, when the pinpoint is not moving, - Below the Radar
yes, map jitters a little bit less than a pinpoint but it does. can be seen at the edge of the screen. it's not about specs i guess. When its animated without centering it's smooth - line88

2 Answers

3
votes

I think the problem is that you are creating and drawing a new feature to vectorContext at each frame animation.

Instead you should create a feature and add it into a vectorLayer once, and then modify its geometry at each frame animation.

  //here you define the pinpoint feature and add it to the vectorLayer
  var feature = new ol.Feature();
  feature.setStyle(styles.geoMarker);
  vectorLayer.getSource().addFeature(feature);

  var moveFeature = function(event) {
    var vectorContext = event.vectorContext;
    var frameState = event.frameState;

    if (animating) {
      var elapsedTime = frameState.time - now;
      // here the trick to increase speed is to jump some indexes
      // on lineString coordinates
      var index = Math.round(speed * elapsedTime / 1000);

      if (index >= routeLength) {
        stopAnimation(true);
        return;
      }

      var currentPoint = new ol.geom.Point(routeCoords[index]);
      //here you modify the feature geometry instead of creating a new feature
      feature.setGeometry(currentPoint);
      map.getView().setCenter(routeCoords[index]);
    }
    // tell OpenLayers to continue the postcompose animation
    map.render();
  };

working demo without jitter: https://jsfiddle.net/32z45kLo/80/

2
votes

The problem is that points on the lines are not equidistant thus the position jump from one to another but nothing inbeetween.

Look at this example to calculate points on the line: http://viglino.github.io/ol-ext/examples/animation/map.featureanimation.path.html

Using a ol.featureAnimation.Path, if you have to move the map on position change, just listen to the change event on the animated feature to get its current position:

geoMarker.on('change', function() {
  map.getView().setCenter(geoMarker.getGeometry().getCoordinates());
});

You can see a working example with your code here: https://jsfiddle.net/Viglino/nhrwynzs/