diff --git a/application/frontend/src/app/core/containers/app/app.component.ts b/application/frontend/src/app/core/containers/app/app.component.ts
index 2f85da7b..a588f1b1 100644
--- a/application/frontend/src/app/core/containers/app/app.component.ts
+++ b/application/frontend/src/app/core/containers/app/app.component.ts
@@ -79,7 +79,9 @@ export class AppComponent {
'navigate_before',
'navigate_next',
'open_in_new',
+ 'pause',
'pdf',
+ 'play',
'pickup',
'route',
'satellite',
diff --git a/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.html b/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.html
index 7d5015c7..1feef6af 100644
--- a/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.html
+++ b/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.html
@@ -1,30 +1,31 @@
-
+
Activate travel simulatorTravel simulator
-
{{ formatSecondsDate(timeDisplayed$ | async) }}
-
-
-
- Speed
-
- Slow
- Normal
- Fast
-
-
+
+
+
+
+
+
Speed:
+
+ 0.5x
+ 1x
+ 3x
+ 5x
+
+
+
diff --git a/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.scss b/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.scss
index 9ce9699f..55bf1c5b 100644
--- a/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.scss
+++ b/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.scss
@@ -1,17 +1,42 @@
+@import '../../../../styles/variables.scss';
+
:host {
position: absolute;
- top: 10px;
- left: 0;
- right: 0;
- display: flex;
- justify-content: center;
+ bottom: 10px;
+ left: 10px;
+ padding: 10px;
+}
+
+.simulator-toggle {
+ font-size: 16px;
+ line-height: 24px;
+}
+
+.simulator-contents {
+ margin-left: 20px;
+ gap: 20px;
}
-.container {
- width: 50%;
+.divider {
+ height: 24px;
}
-.time-value {
- text-align: center;
- padding-top: 8px;
+.play-button {
+ box-shadow: none;
+ height: 24px;
+ width: 24px;
+
+ .mat-button-wrapper {
+ position: relative;
+ top: -4px;
+ }
+}
+
+.speed-container {
+ gap: 10px;
+
+ mat-radio-group {
+ display: flex;
+ gap: 10px;
+ }
}
diff --git a/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.ts b/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.ts
index c991ba7f..6f6c0cef 100644
--- a/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.ts
+++ b/application/frontend/src/app/core/containers/travel-simulator/travel-simulator.component.ts
@@ -7,13 +7,13 @@
* https://opensource.org/licenses/MIT.
*/
-import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { ChangeDetectionStrategy, Component, HostBinding, OnDestroy, OnInit } from '@angular/core';
import { Store, select } from '@ngrx/store';
import Long from 'long';
import { Observable, Subject, Subscription, asyncScheduler, combineLatest, interval } from 'rxjs';
import ShipmentModelSelectors from '../../selectors/shipment-model.selectors';
import { map, throttleTime } from 'rxjs/operators';
-import { MatSlider, MatSliderChange } from '@angular/material/slider';
+import { MatSliderChange } from '@angular/material/slider';
import { setActive, setTime } from '../../actions/travel-simulator.actions';
import TravelSimulatorSelectors from '../../selectors/travel-simulator.selectors';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
@@ -27,17 +27,18 @@ import { formatSecondsDate } from 'src/app/util/time-translation';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TravelSimulatorComponent implements OnInit, OnDestroy {
- @ViewChild(MatSlider) timeSlider: MatSlider;
+ @HostBinding('class.app-map-panel') readonly mapPanel = true;
active$: Observable
;
- start$: Observable;
- end$: Observable;
- time$: Observable;
timeDisplayed$: Observable;
timezoneOffset: number;
valueChanged = new Subject();
animationTimer$: Subscription;
- animationSpeedMultiple = 3;
+ animationSpeedMultiple = 1;
+ end$: Subscription;
+ end: number;
+ time$: Subscription;
+ time: number;
formatSecondsDate = formatSecondsDate;
@@ -49,20 +50,19 @@ export class TravelSimulatorComponent implements OnInit, OnDestroy {
.pipe(map((value) => (this.timezoneOffset = value)))
.subscribe();
- this.start$ = this.store
- .select(ShipmentModelSelectors.selectGlobalStartTime)
- .pipe(map((value) => Long.fromValue(value).toNumber()));
-
this.end$ = this.store
.select(ShipmentModelSelectors.selectGlobalEndTime)
- .pipe(map((value) => Long.fromValue(value).toNumber()));
+ .pipe(map((value) => Long.fromValue(value).toNumber()))
+ .subscribe((end) => (this.end = end));
this.timeDisplayed$ = combineLatest([
this.store.select(TravelSimulatorSelectors.selectTime),
this.store.select(selectTimezoneOffset),
]).pipe(map(([value, tzOffset]) => value + tzOffset));
- this.time$ = this.store.select(TravelSimulatorSelectors.selectTime);
+ this.time$ = this.store
+ .select(TravelSimulatorSelectors.selectTime)
+ .subscribe((time) => (this.time = time));
this.active$ = this.store.pipe(select(TravelSimulatorSelectors.selectActive));
@@ -76,13 +76,14 @@ export class TravelSimulatorComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.onEndAnimate();
+ this.time$.unsubscribe();
+ this.end$.unsubscribe();
}
onBeginAnimate(): void {
- this.timeSlider.disabled = true;
- this.animationTimer$ = interval(100).subscribe((_value) => {
- const newTime = this.timeSlider.value + 60 * this.animationSpeedMultiple;
- if (newTime > this.timeSlider.max) {
+ this.animationTimer$ = interval(33).subscribe((_value) => {
+ const newTime = this.time + 60 * this.animationSpeedMultiple;
+ if (newTime > this.end) {
this.onEndAnimate();
return;
}
@@ -92,7 +93,6 @@ export class TravelSimulatorComponent implements OnInit, OnDestroy {
onEndAnimate(): void {
this.animationTimer$?.unsubscribe();
- this.timeSlider.disabled = false;
}
onToggleActive(event: MatSlideToggleChange): void {
diff --git a/application/frontend/src/assets/images/pause.svg b/application/frontend/src/assets/images/pause.svg
new file mode 100644
index 00000000..d477130b
--- /dev/null
+++ b/application/frontend/src/assets/images/pause.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/application/frontend/src/assets/images/play.svg b/application/frontend/src/assets/images/play.svg
new file mode 100644
index 00000000..5a9aa6ad
--- /dev/null
+++ b/application/frontend/src/assets/images/play.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/application/frontend/src/styles/main.scss b/application/frontend/src/styles/main.scss
index 4b69435a..2cb58e0c 100644
--- a/application/frontend/src/styles/main.scss
+++ b/application/frontend/src/styles/main.scss
@@ -985,3 +985,12 @@ app-post-solve-map-legend .legend-panel mat-checkbox label .mat-checkbox-label {
font-size: 16px;
line-height: 24px;
}
+
+.play-button .mat-button-wrapper {
+ position: relative;
+ top: -8px;
+
+ mat-icon svg {
+ height: 22px;
+ }
+}