下滑动画Angular 4

15

我正在尝试为我的页面添加动画效果,但遇到了以下问题:
我在页面上有一个内容div和一个按钮,点击该按钮会打开另一个div并将其放置在内容div的上方。我想让这个div淡入淡出和滑动,下面的div也相应地向下/向上滑动。我已经为点击后打开的上方div创建了期望的动画效果,但不知道如何处理内容div,以下是示例代码:

<div class="wrapper">
  <button (click)="animated = !animated"></button>
  <div *ngIf="animated" [@slideInOutAnimation] class="animated-div">
  THIS DIV IS ANIMATED</div>

  <div class="content">THIS IS CONTENT DIV</div>

</div>

TYPESCRIPT:
animations: [
trigger('slideInOutAnimation', [

  state('*', style({

  })),
  transition(':enter', [
    style({
      transform: 'translateY(-10%)',
      opacity: 0
    }),
    animate('.5s ease-in-out', style({
      transform: 'translateY(0)',
      opacity: 1
    }))
  ]),
  transition(':leave', [
    animate('.5s ease-in-out', style({
      transform: 'translateY(-10%)',
      opacity: 0
    }))
  ])
])
]

我应该创建其他触发器来移动我的内容div与动画div吗?

3个回答

45

首先,创建一个文件,在其中定义你的动画并将其导出。为了在app.component.ts中更加清晰明确。

在以下示例中,我使用了一个div的最大高度,从0px(隐藏时)到500px,但您可以根据需要进行更改。

此动画使用状态(in和out),当我们单击按钮时,它们将切换,并运行该动画。

animations.ts

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

export const SlideInOutAnimation = [
    trigger('slideInOut', [
        state('in', style({
            'max-height': '500px', 'opacity': '1', 'visibility': 'visible'
        })),
        state('out', style({
            'max-height': '0px', 'opacity': '0', 'visibility': 'hidden'
        })),
        transition('in => out', [group([
            animate('400ms ease-in-out', style({
                'opacity': '0'
            })),
            animate('600ms ease-in-out', style({
                'max-height': '0px'
            })),
            animate('700ms ease-in-out', style({
                'visibility': 'hidden'
            }))
        ]
        )]),
        transition('out => in', [group([
            animate('1ms ease-in-out', style({
                'visibility': 'visible'
            })),
            animate('600ms ease-in-out', style({
                'max-height': '500px'
            })),
            animate('800ms ease-in-out', style({
                'opacity': '1'
            }))
        ]
        )])
    ]),
]

然后在你的 app.component 中,我们导入动画并创建一个方法来切换动画状态。

app.component.ts

import { SlideInOutAnimation } from './animations';

@Component({
  ...
  animations: [SlideInOutAnimation]
})
export class AppComponent  {
  animationState = 'in';

  ...

  toggleShowDiv(divName: string) {
    if (divName === 'divA') {
      console.log(this.animationState);
      this.animationState = this.animationState === 'out' ? 'in' : 'out';
      console.log(this.animationState);
    }
  }
}

以下是您的 app.component.html 文件的样子:

<div class="wrapper">
  <button (click)="toggleShowDiv('divA')">TOGGLE DIV</button>
  <div [@slideInOut]="animationState" style="height: 100px; background-color: red;">
  THIS DIV IS ANIMATED</div>
  <div class="content">THIS IS CONTENT DIV</div>
</div>

slideInOut是在animations.ts中定义的动画触发器。

这里有一个我创建的StackBlitz示例:https://stackblitz.com/edit/angular-muvaqu

顺便提一下:如果出现错误并要求您添加BrowserAnimationsModule,只需在app.module.ts中导入它:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  imports: [ ..., BrowserAnimationsModule ],
  ...
})

1
请参见此处的其他解决方案。 - Felix
2
哇,这真的有助于我们通过网站共享一组常见的动画库。感谢您提供这个。我们最终制作了这些工厂函数,以便我们可以稍微不同地配置每个动画。 - crush
是的,实际上工厂函数使其可重用。你能展示一下你所说的库是哪个吗? - mozpider

20

当处理动态高度内容时,我更喜欢使用通配符运算符来进行高度转换。

// Bind to true/false states via 0 and 1 values

trigger('slideUpDown', [
  state('0', style({ 'max-height': '*', opacity: 1 })),
  state('1', style({ 'max-height': '0px', opacity: 0 })),
  transition(':enter', animate('400ms ease-in-out')),
  transition('* => *', animate('400ms ease-in-out')),
])

使用方法:

<div #someDiv [@slideUpDown]="someDiv.state"></div>

你可以在其他地方或模板中切换状态。

<button (click)="someDiv.state = !someDiv.state"></button>

8
这是在 Angular 2 及以上版本中实现下滑动画的一种简单干净的方式。 my-component.ts
import { animate, style, transition, trigger } from '@angular/animations';
@Component({
  animations: [
    trigger('slideDownUp', [
      transition(':enter', [style({ height: 0 }), animate(500)]),
      transition(':leave', [animate(500, style({ height: 0 }))]),
    ]),
  ],
})

my-component.html

<div @slideDownUp *ngIf="isShowing" class="box">
  I am the content of the div!
</div>

my-component.scss

.box {
  overflow: hidden;
}

1
非常好的解决方案。谢谢。 - danmc
1
谢谢,这是我试过的唯一有效的方法! - devmiles.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接