Angular路由组件推送in/out动画

Angular routing component push in/out animation

我正在尝试为组件设置动画以“将自身推入” 和“被推出”视图。目前,单个容器元素承载一个组件,该组件占据 100% space.

动画将触发第二个组件(位于路由器出口内)将自己从右侧推入,并与 space 共享 50% 的 space第一个组件(收缩时需要有流畅的动画)。

反之亦然,退出动画看起来像是第一个组件“推动”第二个组件离开视野。

下面是这个场景的模板文件(假设组件文件中已经正确导入了动画)

<div class="container">
  <div class="component-1"
    [@triggerComponent1]="outlet.isActivated ? 'shrink' : 'stretch'">
    <component-1></component-1>
  </div>

  <div class="component-2 col-6"
    [@triggerComponent2]="outlet.isActivated ? 'open' : 'close'">
    <router-outlet #outlet="outlet"></router-outlet>
  </div>
</div>

下面是各自的动画触发函数

export const animation1 = trigger('triggerComponent1', [
  state('stretch', style({
    flex: '0 0 auto',
    width: '100%'
  })),
  state('shrink', style({
    flex: '0 0 auto',
    width: '50%'
  })),
  transition('* => stretch', animate('400ms cubic-bezier(0.35, 0, 0.25, 1)')
  ),
  transition('* => shrink', animate('400ms cubic-bezier(0.35, 0, 0.25, 1)'))
]);

export const animation2 = trigger('triggerComponent2', [
  state('open', style({
    transform: 'translateX(0%)'
  })),
  state('close', style({
    transform: 'translateX(100%)'
  })),
  transition('* => open', animate('400ms cubic-bezier(0.35, 0, 0.25, 1)')
  ),
  transition('* => close', animate('400ms cubic-bezier(0.35, 0, 0.25, 1)'))
]);

这种方法的问题是动画不是并行发生的。组件 1 将平滑收缩,将白色 space 暴露在其 右侧 。然后,当 slide 动画完成时,组件 2 就“出现”了。

理想情况下,我需要将动画与 group() 相结合,但我不确定如何编写触发器,也不确定如何将其包含在模板中。

这是给你的堆栈闪电战

https://stackblitz.com/edit/expanding-drawer-animation?file=src/app/animations.ts

我是这样做的。

<div class="container">
   <div class="component-1">
     <div class="content">
          <button (click)="toggle()">expand</button>
          <h1>{{ isExpanded }}</h1>
     </div>
   </div>
   <div class="component-2" [@slideIn]="isExpanded ? 'open' : 'close'">
         <div class="content">
         <h1>Bender?! You stole the atom.</h1>
     </div>
   </div>
 </div>

然后一些 CSS.

 .container {
   width: 100%;
   max-width: 100%;
   background: red;
   display: flex;
   flex-direction: row;
 }

 .content {
   padding: 10px;
 }

 .component-1 {
   flex: 1;
   background: rgb(161, 161, 255);
 }

 .component-2 {
   flex: 1;
   background: green;
   max-width: 50%;
   overflow: hidden;
 }

parent 是一个 div flex,而 2 children 是 50 / 50 flex:1。然后你可以溢出隐藏右边的div并根据变量设置max-width为50%:0。我们将使用它来触发动画。

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

export class Animations {
  static page = [
    trigger('slideIn', [
      state('close', style({ maxWidth: '0%', visibility: 'hidden' })),
      state('open', style({ maxWidth: '50%', visibility: 'visible' })),
      transition('close <=> open', [animate('.6s ease-in-out')]),
      transition(':enter', [
        style({ opacity: 1 }),
        animate('.6s 1.2s ease-in-out'),
      ]),
    ]),
  ];
}

希望对您有所帮助!

我还在 stackblitz 中为您做了第二个,使用绝对位置并使用填充滑动超过 50%,就像我在下面的评论中所说的那样。