首页 > 解决方案 > 如何为组件设置动画以在 [方向] 上滑动?

问题描述

我正在制作一个个人网站,其中不同的部分(即主页、关于、投资组合、联系人)实际上是组件。

当我单击部分链接(即联系人)时,我不想简单地重定向到组件,而是希望现有组件使用:exitwith@slide和新组件使用:enterwith @slide。需要注意的是,我希望任何中间组件都做同样的事情。例如:

  1. 用户从“主页”开始,但单击“联系”。
  2. :leave
  3. 关于:enter, 关于:leave
  4. 投资:enter组合:leave
  5. 接触:enter

根据当前pageIndex和目的地,组件应向左或向右滑动pageIndex

我知道轮播有 jQuery 和 Angular API,但自己编写代码会更酷。它也不是一个传统的旋转木马。我要求太多了吗?

我当前策略的问题是中间组件没有动画。使用console.log(componentRef)insideloadComponent()表明正在创建中间组件,并且我最终确实到达了正确的页面,该页面: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)
    ]),
]);

标签: angular

解决方案


您可以用作动画: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' } },

分叉了 angular 的 stackblitz


推荐阅读