路由组件的Angular 2“动画幻灯片”

Posted

技术标签:

【中文标题】路由组件的Angular 2“动画幻灯片”【英文标题】:Angular 2 "slide in animation" of a routed component 【发布时间】:2016-10-20 22:09:29 【问题描述】:

假设我在固定导航栏中有 2 个路由组件和两个 Routerlink 来路由它们。当我单击路由器链接时,我希望它们从右侧滑入。

我不想用 css 偏移组件并使用超时函数来更改 css 类以使其滑入(例如使用 ngStyle 或 ngClass)。

在 Angular 2 中有没有更优雅的方法来实现这一点?

谢谢!

【问题讨论】:

RC2中有新的动画API,你可以看看。 See this example。我还没有用路由器尝试过,但看起来很有趣(: 所以答案主要显示了在 TypeScript 中嵌入 CSS 的动画。是否有任何使用 ngClass 的示例,以便您可以将 CSS 样式应用于进入/离开或进入/退出效果? 【参考方案1】:

就滑动而言,它非常简单。

您可以参考Official Angular 2 Animate docs。

您也可以查看Plunker 我使用新路由器 v3 进行的简单展示

请记住,当触发的元素即将从视图中销毁时,我正在努力弄清楚如何实际进行离开/退出/无效转换。

我在Angular 2 Animate - No visible effect of the '* => void' transition when changing routes/components 中打开了另一个线程,试图弄清楚如何让路由器注意到离开动画/过渡时间。

@Component(
  selector: 'home',
  directives: [ROUTER_DIRECTIVES],
  template: `
  <div @flyInOut="'active'" class="radibre">
  </div>
  `,
  styles: ['.radibre  width: 200px; height: 100px; background: red; '],
  animations: [
    trigger('flyInOut', [
      state('in', style(transform: 'translateX(0)')),
      transition('void => *', [
        style(transform: 'translateX(-100%)'),
        animate(100)
      ]),
      transition('* => void', [
        animate(100, style(transform: 'translateX(100%)'))
      ])
    ])
  ]
)

export class Home 
  constructor()  

@Component(
  selector: 'page',
  template: `
  <div @testingBottom="'active'" class="page"></div>`,
  styles: ['.page  width: 300px; height: 50px; background: green; '],
  animations: [
    trigger('testingBottom', [
      state('active', style(transform: 'scale(1)')),
      transition('void => *', [
        style(transform: 'scale(0)'),
        animate(100)
      ]),
      transition('* => void', [
        animate(100, style(transform: 'scale(0)'))
      ])
    ])
  ]
)

【讨论】:

温馨提示,目前,Plunker 不会为过渡设置动画(可能是因为 angular2 从 rc_ 更新到 stable?) 【参考方案2】:

使用 Angular 4.1,现在可以创建特定的路线动画。这与在显示组件时触发动画不同,因为它可以让您同时为进入/离开组件设置动画以实现平滑过渡,并让您根据即将到来或离开的组件来修改过渡。这意味着您可以进行复杂的转换,例如,如果您要向下钻取内容,则从右侧滑入一个组件,如果您通过另一个组件的“后退”按钮输入它,则可以从左侧滑入。

    首先,像这样注释您的路由器插座(例如app.component.html):

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

    在对应的组件定义中实现prepareRouteTransition(outlet)函数(例如app.component.js)。

    prepareRouteTransition(outlet) 
        const animation = outlet.activatedRouteData['animation'] || ;
        return animation['value'] || null;
    
    

    定义你的动画(例如app.component.js):

      const slideLeft = [
        query(':leave', style( position: 'absolute', left: 0, right: 0 ,transform: 'translate3d(0%,0,0)' ), optional:true),
        query(':enter', style( position: 'absolute', left: 0, right: 0, transform: 'translate3d(-100%,0,0)' ), optional:true),
        group([
          query(':leave', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style( transform: 'translate3d(100%,0,0)' )), // y: '-100%'
          ]), optional:true),
          query(':enter', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style( transform: 'translate3d(0%,0,0)' )),
          ]), optional:true)
        ])
      ]
    
      const slideRight = [
        query(':leave', style( position: 'absolute', left: 0, right: 0 , transform: 'translate3d(0%,0,0)'), optional:true),
        query(':enter', style( position: 'absolute', left: 0, right: 0, transform: 'translate3d(100%,0,0)'), optional:true),
    
        group([
          query(':leave', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style( transform: 'translate3d(-100%,0,0)' )), // y: '-100%'
          ]), optional:true),
          query(':enter', group([
            animate('500ms cubic-bezier(.35,0,.25,1)', style( transform: 'translate3d(0%,0,0)' )),
          ]), optional:true)
        ])
      ]
    

    将动画元数据添加到您的路线定义中(例如app.routing.ts):

    const routes: Routes = [
      
        path: 'products',
        component: ProductsComponent,
        data: 
          animation: 
            value: 'products',
          
        
      ,
      
        path: 'products/:id',
        component: ProductDetailComponent,
        data: 
           animation: 
            value: 'product-detail',
          
        
      
    

    最后,使用您定义的动画和路由元数据在您的组件上注册一个“routerAnimations”动画触发器(例如app.component.js):

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

不要忘记针对旧浏览器添加 Web Animation API

Matias Niemela 在 ng-conf 上详细讨论路线动画(附演示):https://youtu.be/Oh9wj-1p2BM?t=12m21s

他的演示代码:https://github.com/matsko/ng4-animations-preview

【讨论】:

执行此操作后,我似乎无法构建我的 Angular 项目。看来 github 项目也根本无法开箱即用 嗯,只是能够在两台不同的笔记本电脑上开箱即用地克隆、构建和运行 github 项目。如果您仍然遇到问题,您可以创建一个新问题并发布一些代码或发布您的项目吗?很乐意提供帮助。 嘿,感谢您的回复,如果我运行ng build --aot --prod,这就是我的计算机上使用最新的角度 CLI 和节点时发生的情况。 i.imgur.com/kp8mrVo.jpg 这不适用于 --prod 构建。有一个修复,但我们必须等待发布:github.com/angular/angular/issues/17467 但是,如何在 "products/id1" 和 "products/id2" 之间进行动画转换?看起来没有为这种情况定义转换。

以上是关于路由组件的Angular 2“动画幻灯片”的主要内容,如果未能解决你的问题,请参考以下文章

android动画幻灯片下载

试图制作我在 CSS 中完成但失败的代码的动画幻灯片

SVG剪裁路径和遮罩jQuery幻灯片

使用 angular slick carousel 组件的分层幻灯片实现

Angular 2路由到同一组件

路由器导航幻灯片动画不起作用