azure-maps-animations wont animate marker in Angular 17
Hello. I’m trying to replicate this Azure Maps example, and I have everything working except the marker arrow, which isn’t moving. When I provide a map, the camera animates correctly, but the arrow icon remains stationary.
The Atlas library and atlas.animations are present in the browser on runtime, and I am not receiving any console errors from the libraries. Any assistance would be appreciated.
The azure-maps-animations.js used is from the last official release. (I changed azmaps to atlas, but that’s beside the point because animation librari is working and present in browser console).
Here it is the HTML code:
<div #myMap style=”position:relative;width:100%;min-width:290px;height:600px;”></div>
<div style=”position:absolute;top:15px;left:15px;border-radius:5px;padding:5px;background-color:white;”>
<button (click)=”play()”>Play</button>
<button (click)=”pause()”>Pause</button>
<button (click)=”stop()”>Stop</button>
<button (click)=”reset()”>Reset</button>
<br/><br/>
Follow: <input type=”checkbox” (click)=”toggleFollow()” title=”Follow” checked/><br/>
Follow offset: <input type=”checkbox” (click)=”toggleFollowOffset()” title=”Follow offset”/><br/>
Loop: <input type=”checkbox” (click)=”toggleLooping()” title=”Loop”/><br/>
Reverse: <input type=”checkbox” (click)=”toggleReverse()” title=”Reverse”/>
</div>
<fieldset style=”width:calc(100% – 30px);min-width:290px;margin-top:10px;”>
<legend>Animate along a route path</legend>
This sample shows how to smoothly animate a symbol along a route path taking into consideration timestamps for each point in the route path.
This sample also includes controls and options for the animation.
This sample uses the open source <a href=”https://github.com/Azure-Samples/azure-maps-animations” target=”_blank” title=”Azure Maps Animation module”>Azure Maps Animation module</a>
</fieldset>
And the typescript code (it’s an angular component):
import { Component, ElementRef, ViewChild } from ‘@angular/core’;
import { RouterOutlet } from ‘@angular/router’;
import atlas from ‘azure-maps-control’;
@Component({
selector: ‘app-root’,
standalone: true,
imports: [RouterOutlet],
templateUrl: ‘./app.component.html’,
styleUrl: ‘./app.component.scss’,
})
export class AppComponent {
@ViewChild(‘myMap’, { static: true }) myMap!: ElementRef;
map!: atlas.Map;
pin!: atlas.Shape;
lineSource!: atlas.source.DataSource;
pinSource!: atlas.source.DataSource;
animation!: any;
routePoints = [
new atlas.data.Feature(new atlas.data.Point([-122.34758, 47.62155]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:53:53 GMT’).getTime() }),
new atlas.data.Feature(new atlas.data.Point([-122.34764, 47.61859]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:54:53 GMT’).getTime() }),
new atlas.data.Feature(new atlas.data.Point([-122.33787, 47.61295]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:56:53 GMT’).getTime() }),
new atlas.data.Feature(new atlas.data.Point([-122.34217, 47.60964]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:59:53 GMT’).getTime() })
];
constructor() { }
ngOnInit() {
this.initializeMap();
}
initializeMap() {
this.map = new atlas.Map(this.myMap.nativeElement, {
center: [-122.345, 47.615],
zoom: 14,
view: ‘Auto’,
authOptions: {
authType: atlas.AuthenticationType.subscriptionKey,
subscriptionKey: ‘API_KEY’,
},
});
this.map.events.add(‘ready’, () => this.onMapReady());
}
onMapReady() {
this.map.imageSprite.createFromTemplate(‘arrow-icon’, ‘marker-arrow’, ‘teal’, ‘#fff’).then(() => {
this.initializeSourcesAndLayers();
this.initializePin();
this.initializeAnimation();
});
}
initializeSourcesAndLayers() {
this.lineSource = new atlas.source.DataSource();
this.pinSource = new atlas.source.DataSource();
this.map.sources.add([this.lineSource, this.pinSource]);
const path = this.routePoints.map(f => f.geometry.coordinates);
this.lineSource.add(new atlas.data.LineString(path));
this.map.layers.add(new atlas.layer.LineLayer(this.lineSource, null, {
strokeColor: ‘DodgerBlue’,
strokeWidth: 3
}));
this.map.layers.add(new atlas.layer.SymbolLayer(this.pinSource, null, {
iconOptions: {
image: ‘arrow-icon’,
anchor: ‘center’,
rotation: [‘+’, 180, [‘get’, ‘heading’]],
rotationAlignment: ‘map’,
ignorePlacement: true,
allowOverlap: true
},
textOptions: {
ignorePlacement: true,
allowOverlap: true
}
}));
}
initializePin() {
this.pin = new atlas.Shape(this.routePoints[0]);
this.pinSource.add(this.pin);
}
initializeAnimation() {
this.animation = (window as any).atlas.animations.moveAlongRoute(this.routePoints, this.pin, {
timestampProperty: ‘timestamp’,
captureMetadata: true,
loop: false,
reverse: false,
rotationOffset: 0,
speedMultiplier: 60,
map: this.map,
zoom: 15,
pitch: 45,
rotate: true
});
}
toggleAnimationOption(option: string, value?: any) {
const options = this.animation.getOptions();
this.animation.setOptions({
[option]: value !== undefined ? value : !options[option]
});
}
play() { this.animation.play(); }
pause() { this.animation.pause(); }
stop() { this.animation.stop(); }
reset() { this.animation.reset(); }
toggleFollow() { this.toggleAnimationOption(‘map’, this.map); }
toggleFollowOffset() { this.toggleAnimationOption(‘rotationOffset’, this.animation.getOptions().rotationOffset === 0 ? 90 : 0);}
toggleLooping() { this.toggleAnimationOption(‘loop’); }
toggleReverse() { this.toggleAnimationOption(‘reverse’); }
}
Hello. I’m trying to replicate this Azure Maps example, and I have everything working except the marker arrow, which isn’t moving. When I provide a map, the camera animates correctly, but the arrow icon remains stationary.The Atlas library and atlas.animations are present in the browser on runtime, and I am not receiving any console errors from the libraries. Any assistance would be appreciated.The azure-maps-animations.js used is from the last official release. (I changed azmaps to atlas, but that’s beside the point because animation librari is working and present in browser console).Here it is the HTML code: <div #myMap style=”position:relative;width:100%;min-width:290px;height:600px;”></div>
<div style=”position:absolute;top:15px;left:15px;border-radius:5px;padding:5px;background-color:white;”>
<button (click)=”play()”>Play</button>
<button (click)=”pause()”>Pause</button>
<button (click)=”stop()”>Stop</button>
<button (click)=”reset()”>Reset</button>
<br/><br/>
Follow: <input type=”checkbox” (click)=”toggleFollow()” title=”Follow” checked/><br/>
Follow offset: <input type=”checkbox” (click)=”toggleFollowOffset()” title=”Follow offset”/><br/>
Loop: <input type=”checkbox” (click)=”toggleLooping()” title=”Loop”/><br/>
Reverse: <input type=”checkbox” (click)=”toggleReverse()” title=”Reverse”/>
</div>
<fieldset style=”width:calc(100% – 30px);min-width:290px;margin-top:10px;”>
<legend>Animate along a route path</legend>
This sample shows how to smoothly animate a symbol along a route path taking into consideration timestamps for each point in the route path.
This sample also includes controls and options for the animation.
This sample uses the open source <a href=”https://github.com/Azure-Samples/azure-maps-animations” target=”_blank” title=”Azure Maps Animation module”>Azure Maps Animation module</a>
</fieldset> And the typescript code (it’s an angular component): import { Component, ElementRef, ViewChild } from ‘@angular/core’;
import { RouterOutlet } from ‘@angular/router’;
import atlas from ‘azure-maps-control’;
@Component({
selector: ‘app-root’,
standalone: true,
imports: [RouterOutlet],
templateUrl: ‘./app.component.html’,
styleUrl: ‘./app.component.scss’,
})
export class AppComponent {
@ViewChild(‘myMap’, { static: true }) myMap!: ElementRef;
map!: atlas.Map;
pin!: atlas.Shape;
lineSource!: atlas.source.DataSource;
pinSource!: atlas.source.DataSource;
animation!: any;
routePoints = [
new atlas.data.Feature(new atlas.data.Point([-122.34758, 47.62155]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:53:53 GMT’).getTime() }),
new atlas.data.Feature(new atlas.data.Point([-122.34764, 47.61859]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:54:53 GMT’).getTime() }),
new atlas.data.Feature(new atlas.data.Point([-122.33787, 47.61295]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:56:53 GMT’).getTime() }),
new atlas.data.Feature(new atlas.data.Point([-122.34217, 47.60964]), { _timestamp: new Date(‘Tue, 18 Aug 2020 00:59:53 GMT’).getTime() })
];
constructor() { }
ngOnInit() {
this.initializeMap();
}
initializeMap() {
this.map = new atlas.Map(this.myMap.nativeElement, {
center: [-122.345, 47.615],
zoom: 14,
view: ‘Auto’,
authOptions: {
authType: atlas.AuthenticationType.subscriptionKey,
subscriptionKey: ‘API_KEY’,
},
});
this.map.events.add(‘ready’, () => this.onMapReady());
}
onMapReady() {
this.map.imageSprite.createFromTemplate(‘arrow-icon’, ‘marker-arrow’, ‘teal’, ‘#fff’).then(() => {
this.initializeSourcesAndLayers();
this.initializePin();
this.initializeAnimation();
});
}
initializeSourcesAndLayers() {
this.lineSource = new atlas.source.DataSource();
this.pinSource = new atlas.source.DataSource();
this.map.sources.add([this.lineSource, this.pinSource]);
const path = this.routePoints.map(f => f.geometry.coordinates);
this.lineSource.add(new atlas.data.LineString(path));
this.map.layers.add(new atlas.layer.LineLayer(this.lineSource, null, {
strokeColor: ‘DodgerBlue’,
strokeWidth: 3
}));
this.map.layers.add(new atlas.layer.SymbolLayer(this.pinSource, null, {
iconOptions: {
image: ‘arrow-icon’,
anchor: ‘center’,
rotation: [‘+’, 180, [‘get’, ‘heading’]],
rotationAlignment: ‘map’,
ignorePlacement: true,
allowOverlap: true
},
textOptions: {
ignorePlacement: true,
allowOverlap: true
}
}));
}
initializePin() {
this.pin = new atlas.Shape(this.routePoints[0]);
this.pinSource.add(this.pin);
}
initializeAnimation() {
this.animation = (window as any).atlas.animations.moveAlongRoute(this.routePoints, this.pin, {
timestampProperty: ‘timestamp’,
captureMetadata: true,
loop: false,
reverse: false,
rotationOffset: 0,
speedMultiplier: 60,
map: this.map,
zoom: 15,
pitch: 45,
rotate: true
});
}
toggleAnimationOption(option: string, value?: any) {
const options = this.animation.getOptions();
this.animation.setOptions({
[option]: value !== undefined ? value : !options[option]
});
}
play() { this.animation.play(); }
pause() { this.animation.pause(); }
stop() { this.animation.stop(); }
reset() { this.animation.reset(); }
toggleFollow() { this.toggleAnimationOption(‘map’, this.map); }
toggleFollowOffset() { this.toggleAnimationOption(‘rotationOffset’, this.animation.getOptions().rotationOffset === 0 ? 90 : 0);}
toggleLooping() { this.toggleAnimationOption(‘loop’); }
toggleReverse() { this.toggleAnimationOption(‘reverse’); }
} Read More