This example shows how to use postrender and vectorContext to animate features. Here we choose to do a flash animation each time a feature is added to the layer.
main.js
import'ol/ol.css';import Feature from'ol/Feature';import Map from'ol/Map';import Point from'ol/geom/Point';import View from'ol/View';import{Circle as CircleStyle, Stroke, Style}from'ol/style';import{OSM, Vector as VectorSource}from'ol/source';import{Tile as TileLayer, Vector as VectorLayer}from'ol/layer';import{easeOut}from'ol/easing';import{fromLonLat}from'ol/proj';import{getVectorContext}from'ol/render';import{unByKey}from'ol/Observable';const tileLayer =newTileLayer({
source:newOSM({
wrapX:false,}),});const source =newVectorSource({
wrapX:false,});const vector =newVectorLayer({
source: source,});const map =newMap({
layers:[tileLayer, vector],
target:'map',
view:newView({
center:[0,0],
zoom:1,
multiWorld:true,}),});functionaddRandomFeature(){const x = Math.random()*360-180;const y = Math.random()*170-85;const geom =newPoint(fromLonLat([x, y]));const feature =newFeature(geom);
source.addFeature(feature);}const duration =3000;functionflash(feature){const start = Date.now();const flashGeom = feature.getGeometry().clone();const listenerKey = tileLayer.on('postrender', animate);functionanimate(event){const frameState = event.frameState;const elapsed = frameState.time - start;if(elapsed >= duration){unByKey(listenerKey);return;}const vectorContext =getVectorContext(event);const elapsedRatio = elapsed / duration;// radius will be 5 at start and 30 at end.const radius =easeOut(elapsedRatio)*25+5;const opacity =easeOut(1- elapsedRatio);const style =newStyle({
image:newCircleStyle({
radius: radius,
stroke:newStroke({
color:'rgba(255, 0, 0, '+ opacity +')',
width:0.25+ opacity,}),}),});
vectorContext.setStyle(style);
vectorContext.drawGeometry(flashGeom);// tell OpenLayers to continue postrender animation
map.render();}}
source.on('addfeature',function(e){flash(e.feature);});
window.setInterval(addRandomFeature,1000);
index.html
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Custom Animation</title><!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer --><scriptsrc="https://unpkg.com/elm-pep@1.0.6/dist/elm-pep.js"></script><!-- The lines below are only needed for old environments like Internet Explorer and Android 4.x --><scriptsrc="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,TextDecoder"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.18.3/minified.js"></script><style>.map{width: 100%;height:400px;}</style></head><body><divid="map"class="map"></div><scriptsrc="main.js"></script></body></html>