Как я могу анимировать компоненты для скольжения в [направлении]? - PullRequest
0 голосов
/ 05 мая 2020

Я создаю личный веб-сайт, где различные разделы (например, «Главная», «О нас», «Портфолио», «Контакты») фактически являются компонентами.

Когда я нажимаю на ссылку раздела (например, «Контакт»), вместо простого перенаправления к компоненту я хочу, чтобы существующий компонент был :exit с @slide, а новый компонент - :enter с @slide. Предостережение: я хочу, чтобы все промежуточные компоненты выполняли то же самое. Например:

  1. Пользователь начинает с «Дома», но нажимает «Контакт».
  2. Дом :leave
  3. О :enter, О :leave
  4. Портфель :enter, Портфель :leave
  5. Контакт :enter

Компоненты должны сдвигаться влево или вправо в зависимости от текущего pageIndex и пункт назначения pageIndex.

Я знаю, что существуют API-интерфейсы jQuery и Angular для каруселей, но было бы намного круче просто написать его самому. Это тоже не совсем традиционная карусель. Я прошу слишком многого?

Проблема с моей текущей стратегией в том, что промежуточные компоненты не анимируются. Использование console.log(componentRef) внутри loadComponent() показывает, что создаются промежуточные компоненты, и в конечном итоге я попадаю на нужную страницу, которая :enter содержит анимацию. Я также использую простую анимацию затухания для тестирования, потому что у меня тоже проблемы с анимацией слайдов.

[- Моя текущая стратегия -]:

    panels: PanelItem[]; 
    pageIndex = 0;
    @ViewChild(PanelDirective, {static: true}) panelHost: PanelDirective;

    loadComponent(index) {

        let panelItem = this.panels[index];

        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(panelItem.component);
        let viewContainerRef = this.panelHost.viewContainerRef;
        viewContainerRef.clear();

        let componentRef = viewContainerRef.createComponent(componentFactory);
        console.log(componentRef);
      }

    changePanel(pageNum) {
        let dest = pageNum;
        let diff = dest-this.pageIndex;
        let curr = this.pageIndex;

        if(diff > 0) {
            for(let i=curr+1; i<dest+1; i++) {
                this.loadComponent(i);
            }
        }
        else if(diff < 0) {
            for (let i=curr-1; i>dest-1; i--) {
                this.loadComponent(i);
            }
        }

        this.pageIndex = pageNum;
        console.log(this.pageIndex);
      }

Анимация:

export let fade = trigger('fade', [
    state('void', style({opacity:0})),
    state('*', style({})),
    transition(':enter, :leave', [
        animate(6000)
    ]),
]);

1 Ответ

1 голос
/ 07 мая 2020

Можно использовать в качестве анимации :increment и :decrement. Да, есть немного кода. Представьте, что у вас есть в .ts анимация

export const slideInAnimation =
    trigger('routeAnimations', [

        transition(':increment', [
            style({ position: 'relative' }),
            query(':enter, :leave', [
                style({
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    width: '100%'
                })
            ], { optional: true }),
            query(':enter', [
                style({ left: '100%' })
            ], { optional: true }),
            query(':leave', animateChild(), { optional: true }),
            group([
                query(':leave', [
                    animate('300ms ease-out', style({ left: '-100%' }))
                ], { optional: true }),
                query(':enter', [
                    animate('300ms ease-out', style({ left: '0%' }))
                ], { optional: true })
            ]),
            query(':enter', animateChild(), { optional: true }),
        ]),
        transition(':decrement', [
            style({ position: 'relative' }),
            query(':enter, :leave', [
                style({
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    width: '100%'
                })
            ], { optional: true }),
            query(':enter', [
                style({ left: '-100%' })
            ], { optional: true }),
            query(':leave', animateChild(), { optional: true }),
            group([
                query(':leave', [
                    animate('300ms ease-out', style({ left: '100%' }))
                ], { optional: true }),
                query(':enter', [
                    animate('300ms ease-out', style({ left: '0%' }))
                ], { optional: true })
            ]),
            query(':enter', animateChild(), { optional: true }),
        ])

    ]);

, если вы пишете в своем main.app. html

<div [@routeAnimations]="prepareRoute(outlet)">
  <router-outlet #outlet="outlet"></router-outlet>
</div>

и PrepateOutlet

prepareRoute(outlet: RouterOutlet) {
    return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
  }

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

{ path: 'Page1', component: Page1Component, data: { animation: '1' } },
{ path: 'Page2', component: Page2Component, data: { animation: '2' } },
{ path: 'Page3', component: Page3Component, data: { animation: '3' } },
{ path: 'Page4', component: Page4Component, data: { animation: '4' } },

I разветвил stackblitz из angular

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...