I have been attempting to animate the transition between two components in my app component. Ideally this is what I would like to happen:
- currently showing the first component slides off of the page
- switches to second component
- now showing second component slides back onto the page
I can get each component to animate into the display when refreshing on each respective URL.
However, when routing from one to the other the first component's leaving animation doesn't happen and also the second component's entering animation doesn't happen.
I've looked around stackoverflow and a few other sites but couldn't find anything that helped me out.
I've added all of the code that I believe is relevant to the issue. (Specifically, I think it is due to the routing from component 1 to 2 since the intro animation happens when I refresh either component)
AppComponent .ts
import { slider } from "./route-animations";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
animations: [slider]
})
export class AppComponent {
prepareRoute(outlet: RouterOutlet) {
return (
outlet &&
outlet.activatedRouteData &&
outlet.activatedRouteData["animation"]
);
}
}
AppComponent html
<main class="row">
<section class="col-sm-6 col-md-6 col-lg-6">Left Part</section>
<section
[@routeAnimations]="prepareRoute(outlet)"
class="col-sm-6 col-md-6 col-lg-6 justify-content-center"
>
<router-outlet #outlet="outlet"></router-outlet>
</section>
</main>
Route-Animation .ts
export const slider = trigger("routeAnimations", [
transition("* => isLeft", slideTo("right")),
transition("* => isRight", slideTo("right")),
transition("isRight => *", slideTo("right")),
transition("isLeft => *", slideTo("right"))
]);
function slideTo(direction) {
const optional = { optional: true };
return [
query(
":enter, :leave",
[
style({
position: "absolute",
[direction]: 0,
width: "100%"
})
],
optional
),
query(":enter", [style({ [direction]: "-100%" })]),
group([
query(
":leave",
[animate("600ms ease", style({ [direction]: "100%" }))],
optional
),
query(":enter", [animate("600ms ease", style({ [direction]: "0%" }))])
])
];
}
FirstComponent .ts
@Component({
selector: "app-first-component",
templateUrl: "./first-component.component.html",
styleUrls: ["./first-component.component.css"]
})
export class FirstComponentComponent implements OnInit {
personForm: FormGroup;
constructor(private formBuilder: FormBuilder, private router: Router) {}
ngOnInit() {
localStorage.removeItem("firstName");
localStorage.removeItem("lastName");
this.personForm = this.formBuilder.group({
firstName: ["", [Validators.required]],
lastName: ["", [Validators.required]]
});
}
addPerson(person: FormGroup) {
localStorage.setItem("names", JSON.stringify(person));
this.router.navigate(["/second-component"]);
}
}
FirstComponent html
<div>
<form [formGroup]="personForm" (ngSubmit)="addPerson(personForm.value)">
<div class="form-group">
<label>First Name</label>
<input
type="text"
class="form-control shadow"
formControlName="firstName"
/>
</div>
<div class="form-group">
<label>Last Name</label>
<input
type="text"
class="form-control shadow"
formControlName="lastName"
/>
</div>
<div>
<button type="submit">
Submit
</button>
</div>
</form>
</div>
SecondComponent .ts
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-second-component",
templateUrl: "./second-component.component.html",
styleUrls: ["./second-component.component.css"]
})
export class SecondComponentComponent implements OnInit {
firstName: string = "";
lastName: string = "";
constructor() {}
ngOnInit(): void {
this.firstName = JSON.parse(localStorage.getItem("names")).firstName;
this.lastName = JSON.parse(localStorage.getItem("names")).lastName;
}
}
SecondComponent .html
<p>Hello, {{ firstName }} {{ lastName }}</p>