【问题标题】:Route animation angular 4路线动画角度 4
【发布时间】:2017-09-07 17:37:45
【问题描述】:

我正在开发的应用程序需要能够在路线中来回导航,因此当您以一种方式在应用程序中以一个方向导航时,组件会从左到右进行动画处理,而当您向后导航时,它们会从右导航到离开了。

即

component1 -> component2 =  left -> right animation
component2 -> component1 = right -> left animation

我可以在 NG4 中轻松实现这一点,但问题是它不能同时导航退出和进入组件。退出组件消失,进入组件动画。

我也可以在 NG2 中实现这一点 - 但是当你有条件动画时就会出现复杂情况。即。

component2 -> component3 = left -> right animation
component2 -> component1 = right -> left animation

这里的问题是根据下一条或上一条路线触发不同的动画。

是否有人在 NG2 或 4 中提供解决方案来解决在任一方向上同时为两个视图设置动画的问题?

我没有把它放在 plunkr 中,因为我不知道如何在其中设置 NG4 应用程序。道歉。

我的 NG4 解决方案基于 this demo app https://github.com/matsko/ng4-animations-preview

但基本上在我的 app.component.ts 中,我有以下动画:

animations: [
    trigger('routerAnimations',[
        transition('page1 => page2',[
            style({transform: 'translateX(100%)'}),
            animate('500ms')
        ]),
        transition('page2 => page1', [
            style({transform: 'translateX(-100%)'}),
            animate('500ms')
        ]),
        transition('page2 => page3',[
            style({transform: 'translateX(100%)'}),
            animate('500ms')
        ]),
        transition('page3 => page2',[
            style({transform: 'translateX(-100%)'}),
            animate('500ms')
        ]),
        transition('page3 => page4',[
            style({transform: 'translateX(100%)'}),
            animate('500ms')
        ]),
        transition('page4 => page3',[
            style({transform: 'translateX(-100%)'}),
            animate('500ms')
        ])
    ])
]

还有一个函数,它从每个路由中获取动画值并将其绑定(?)到<router-outlet> in app.component.html 上的出口变量:

export class AppComponent {
    prepareRouteTransition(outlet) {
        let routeData: any;
        try {
            routeData = outlet['_activatedRoute'].snapshot.routeConfig['animation'];
       } catch(e) {
           return '';
       }
       return routeData.value;
    }
}

上面的函数抓取动画中的动画值,用于定义过渡开始和结束值:

export const APP_ROUTES = [{
    path: '',
    component: Page1Component,
    animation: {
      value: 'page1',
    }
  }, 
  {
    path: 'page2',
    component: Page2Component,
    animation: {
      value: 'page2',
    }
  },
  {
    path: 'page3',
    component: Page3Component,
    animation: {
        value: 'page3'
    }
  },
  {
      path: 'page4',
      component: Page4Component,
      animation: {
          value: 'page4'
      }
  }
];

app.component.html:

<div class="page" [@routerAnimations]="prepareRouteTransition(outlet)">
  <router-outlet #outlet="outlet"></router-outlet>
</div>

【问题讨论】:

  • 同样的问题,我到达了同一个路障。你发现了吗?
  • 谢谢@Clay,我已经测试过了,效果很好:) 但是我要等到 4.1.0,因为实现更干净,但这应该是现在可以接受的答案

标签: angular angular-animations


【解决方案1】:

您可以通过将动画放在要设置动画的路由器插座周围而不是视图本身来实现这一点。

您还想在一个组([])中制作动画,这将使两个动画同时运行。

<!-- app.html -->
<div [@routeAnimation]="prepRouteState(routerOutlet)">
 <!-- make sure to keep the ="outlet" part -->
 <router-outlet #routerOutlet="outlet"></div>

 class AppComponent {
 prepRouteState(outlet: any) {
     return outlet.activatedRouteData['animation'] || 'firstPage'; 
   } 
 }

<!-- app.ts -->
const ROUTES = [
   { path: '',
     component: HomePageComponent,
     data: {
       animation: 'homePage'
     }
   },
   { path: 'support',
     component: SupportPageComponent,
     data: {
       animation: 'supportPage'
     }
   }
 ]

// the animation itself
trigger('routeAnimation', [
  //...
  transition('homePage => supportPage', [
    group([
      query(':enter', [
        style({ opacity: 0 }),
        animate('0.5s', style({ opacity: 1 })),
        animateChild()
      ]),
      query(':leave', [
        animate('0.5s', style({ opacity: 0 })),
        animateChild()
      ])
    ])
  ]),
  //...
])

如YearofMoo Routable Animations所见

【讨论】:

  • 函数prepRouterState,而不是返回出口,你可以做任何你想做的事情,一个程序级别并返回你的动画状态。从那里您可以根据返回的内容制作动画,例如从 3 到 1 左或 1 到 3 右或 3 到 2 左等。您必须构建一个函数,为您提供所需的正确状态和动画将从那里开始工作
【解决方案2】:

您现在可以通过定义查询:enter 和:leave 元素的动画来实现这一点。

此示例将动画出退出路线并平滑地在进入路线中进行动画处理:

const slideLeft = [
  query(':leave', style({ position: 'absolute', left: 0, right: 0 ,transform: 'translate3d(0%,0,0)' })),
  query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(-100%,0,0)' })),
  group([
    query(':leave',
      animate('1s', style({ transform: 'translate3d(100%,0,0)' }))),
    query(':enter',
      animate('1s', style({ transform: 'translate3d(0%,0,0)' })))
  ])
]

const slideRight = [
  query(':leave', style({ position: 'absolute', left: 0, right: 0 , transform: 'translate3d(0%,0,0)'})),
  query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(100%,0,0)'})),

  group([
    query(':leave',
      animate('1s', style({ transform: 'translate3d(-100%,0,0)' }))),
    query(':enter', 
      animate('1s', style({ transform: 'translate3d(0%,0,0)' })))
  ])
]

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [
    trigger('routerAnimations', [
      transition('products => product-details', slideRight),
      transition('product-details => products', slideLeft)
    ])
  ]
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-06
    • 2017-09-03
    • 2018-05-03
    • 2018-01-27
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多