Анимация маршрутов по траекториям маршрута в угловом (v2+)

Вместо прикрепления анимации к каждому компоненту, который перенаправляется, например, в qaru.site/info/1006984/..., или как в первой части официальной документации. Пример:

В hero-detail.component.ts:

import { Component, OnInit } from '@angular/core';
import { fadeInOutAnimation } from "app/app-routing.animation";

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  animations: [
    fadeInOutAnimation(300)
  ]
})
export class HomeComponent{       

}

В app-routing.animation.ts:

import {
  trigger,
  state,
  style,
  animate,
  transition
} from '@angular/animations';

export const fadeInOutAnimation = function (fadeInTimeMS) {
  return trigger('fadeInOut', [
    transition(':enter', [   // :enter is alias to 'void => *'
      style({ opacity: 0 }),
      animate(fadeInTimeMS, style({ opacity: 1 }))
    ]),
    transition(':leave', [   // :leave is alias to '* => void'
      animate(fadeInTimeMS, style({ opacity: 0 }))
    ])
  ])
}

Я хочу анимировать маршруты по маршрутным маршрутам:

Применение анимации маршрута к отдельным компонентам работает для простой демонстрации, но в реальном приложении лучше анимировать маршруты, основанные на маршрутах маршрута.

как указано в конце "Добавление анимаций в маршрутизируемый компонент" в угловой документации. Однако он не расширяет, как это сделать.

Ответ 1

Здесь есть анимация, в которой вы можете видеть вид, сдвинутый влево и вправо, когда вы идете вперед и направо налево, когда идете назад, не добавляя анимацию к компонентам отдельно.

import {animate, AnimationMetadata, group, query, style, transition, trigger} from '@angular/animations';

const leftToRight: AnimationMetadata[] = [
    /* order */
    /* 1 */ query(':enter, :leave', style({position: 'fixed', width: '100%'})
        , {optional: true}),
    /* 2 */ group([  // block executes in parallel
        query(':enter', [
            style({transform: 'translateX(100%)'}),
            animate('0.5s ease-in-out', style({transform: 'translateX(0%)'}))
        ], {optional: true}),
        query(':leave', [
            style({transform: 'translateX(0%)'}),
            animate('0.5s ease-in-out', style({transform: 'translateX(-100%)'}))
        ], {optional: true}),
    ])
];
const rightToLeft: AnimationMetadata[] = [
    /* order */
    /* 1 */ query(':enter, :leave', style({position: 'fixed', width: '100%'})
        , {optional: true}),
    /* 2 */ group([  // block executes in parallel
        query(':enter', [
            style({transform: 'translateX(-100%)'}),
            animate('0.5s ease-in-out', style({transform: 'translateX(0%)'}))
        ], {optional: true}),
        query(':leave', [
            style({transform: 'translateX(0%)'}),
            animate('0.5s ease-in-out', style({transform: 'translateX(100%)'}))
        ], {optional: true}),
    ])
];

export const routerTransition = trigger('routerTransition', [
    transition('first_page => second_page', leftToRight),
    transition('second_page => first_page ', rightToLeft),
    transition('second_page => third_page', leftToRight),
    transition('third_page => second_page', rightToLeft),
]);

И импортируйте его в свой AppComponent и добавьте функцию, чтобы вернуть состояние маршрута. Не забывайте стили, которые я применил.

import {routerTransition} from "./router.animations";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styles: ['
        /deep/ router-outlet ~ * {
            position: absolute;
            width: 100%;
        }
    '],
    animations: [routerTransition]
})
export class AppComponent implements {
    getState(outlet) {
        return outlet.activatedRouteData.state;
    }

    onDeactivate() {
        // document.body.scrollTop = 0;
        // Alternatively, you can scroll to top by using this other call:
        window.scrollTo(0, 0);
    }
}

Применить его к основному тегу в качестве директивы

<main [@routerTransition]="getState(o)">
    <router-outlet #o="outlet" (deactivate)="onDeactivate()"></router-outlet>
</main>

Ответ 2

Здесь приведен пример изменения переходов на основе путей:

import {
    trigger,
    query,
    group,
    animate,
    transition,
    style
} from "@angular/animations";

const fade: any = [
    transition(':enter', [   // :enter is alias to 'void => *'
      style({ opacity: 0 }),
      animate(fadeInTimeMS, style({ opacity: 1 }))
    ]),
    transition(':leave', [   // :leave is alias to '* => void'
      animate(fadeInTimeMS, style({ opacity: 0 }))
    ])
];
const transition2: any = [
    //other transition
];

export const routerTransition = trigger('routerTransition', [
    transition('path1 => *', fade),
    transition('path2 => path3', fade),
    transition('path3 => path1', transition2),
    transition('* => path2', transition2),
]);

Затем в компонентах используется анимация:

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  animations: [
    routerTransition
  ]
})