5

I have the current set up here: fully functional fiddle example and I need to animate the point feature... make it pulse like a GPS location on Google etc. I have found this article: http://openlayers.org/en/master/examples/feature-animation.html but find it really confusing and have no idea how to apply it to my code.

This the the part of the fiddle that creates the point feature and applies it to the map...

function locate_me() {
    var locationPoint = new ol.Feature({
        geometry: new ol.geom.Point([0.3901863098144531, 52.803332200169166])
    });
    locationPoint.getGeometry().transform('EPSG:4326', 'EPSG:3857');

    // A vector layer to hold the location point
    var locationLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [
                locationPoint
            ]
        })
    });
    map.addLayer(locationLayer);
}
Helen Danger Burns
  • 421
  • 2
  • 9
  • 28

1 Answers1

5

Isolating and commenting the function which creates the flash effect to a feature:

/*
 * @param {ol.Feature}
 * @param {Number} Duration in milliseconds.
 */
function flash(feature, duration) {
  var start = +new Date();
  var listenerKey; // to remove the listener after the duration

  function animate(event) {
    // canvas context where the effect will be drawn
    var vectorContext = event.vectorContext;
    var frameState = event.frameState;

    // create a clone of the original ol.Feature
    // on each browser frame a new style will be applied
    var flashGeom = feature.getGeometry().clone();
    var elapsed = frameState.time - start;
    var elapsedRatio = elapsed / duration;
    // radius will be 5 at start and 30 at end.
    var radius = ol.easing.easeOut(elapsedRatio) * 25 + 5;
    var opacity = ol.easing.easeOut(1 - elapsedRatio);

    // you can customize here the style
    // like color, width
    var style = new ol.style.Style({
      image: new ol.style.Circle({
        radius: radius,
        snapToPixel: false,
        stroke: new ol.style.Stroke({
          color: [51, 51, 51, opacity],
          width: 0.25 + opacity
        })
      })
    });

    vectorContext.setStyle(style);
    vectorContext.drawGeometry(flashGeom);
    if (elapsed > duration) { // stop the effect
      ol.Observable.unByKey(listenerKey);
      return;
    }
    // tell OL3 to continue postcompose animation
    map.render();
  }

  listenerKey = map.on('postcompose', animate);
}

Usage:

var marker = new ol.Feature(new ol.geom.Point([0, 0]));
var vectorLayer = new ol.layer.Vector({
  source: new ol.source.Vector({
    features: [marker]
  })
});
map.addLayer(vectorLayer);

flash(marker, 2000);
Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
  • Thanks so much for this... I've applied it to the fiddle here... http://jsfiddle.net/littleninja/yd0tdxje/9/ but keep getting the error `vectorContext.setStyle is not a function`. Any ideas? Really appreciate your help!! – Helen Danger Burns Aug 23 '16 at 22:08
  • 1
    You are using an old OL version. Use the latest one. – Jonatas Walker Aug 24 '16 at 08:30
  • Amazing!!! Thank you! I can happily adjust the look of it from your code, but how would I get the animation to repeat over and over? Thank you so much!! – Helen Danger Burns Aug 24 '16 at 08:58
  • 1
    Use [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval). – Jonatas Walker Aug 24 '16 at 09:05
  • Of course. Sorry... got a bit Openlayery! So simple. Thanks so much again. – Helen Danger Burns Aug 24 '16 at 19:02
  • I simply cannot get this to work with setInterval. I have replaced `flash(marker, 2000);` with `var flash_location_point = setInterval(make_point_flash, 3000);` and in that function have it log out 'hello' and the execute `flash(marker, 2000);` but only the 'hello' logs... the point doesn't animate. I made sure 'marker' was global (well, in my example this is now called 'locationPoint' so the function has access to it, but to no avail. Would you mind taking a look? I will burn hours on this and I know it'll be something stupid I overlooked. http://jsfiddle.net/littleninja/yd0tdxje/14/ Thankyou – Helen Danger Burns Aug 24 '16 at 20:42
  • The way you put here is right - `setInterval(make_point_flash, 3000)` no quotes but that isn't how you put on fiddle. Another way to use it is this: `setInterval(function(){ console.log(...); flash(...); }, 3000)` – Jonatas Walker Aug 25 '16 at 09:57
  • Ok, I've got it working but the animation only triggers when you zoom in and out of the map??? See here... https://jsfiddle.net/littleninja/yd0tdxje/19/ I'm so sorry to keep pestering you! This is so incredibly helpful though! – Helen Danger Burns Aug 25 '16 at 14:29
  • 1
    Tell the map to render each function call - so `function make_point_flash() { map.render(); flash(locationPoint, 2000); }` – Jonatas Walker Aug 25 '16 at 16:25
  • @HelenDangerBurns At your service, glad to help. – Jonatas Walker Aug 25 '16 at 18:40