Angular (4, 5, 6, 7) - ngIf 上滑入滑出动画的简单示例

Posted

技术标签:

【中文标题】Angular (4, 5, 6, 7) - ngIf 上滑入滑出动画的简单示例【英文标题】:Angular (4, 5, 6, 7) - Simple example of slide in out animation on ngIf 【发布时间】:2018-04-25 05:23:08 【问题描述】:

滑入滑出容器元素的最低限度和Angular4的原生方式是什么?

例如

<div ngIf="show">
    <!-- Content -->
</div>

Slide Inshow 变为 true 时,内容(从上到下就像 jQuery.slideDown())。 p>

Slide Out show 变为 false 时的内容(适合带有缓出效果)。

【问题讨论】:

【参考方案1】:

首先是一些代码,然后是解释。描述这个的官方文档是here。

import  trigger, transition, animate, style  from '@angular/animations'

@Component(
  ...
  animations: [
    trigger('slideInOut', [
      transition(':enter', [
        style(transform: 'translateY(-100%)'),
        animate('200ms ease-in', style(transform: 'translateY(0%)'))
      ]),
      transition(':leave', [
        animate('200ms ease-in', style(transform: 'translateY(-100%)'))
      ])
    ])
  ]
)

在您的模板中:

<div *ngIf="visible" [@slideInOut]>This element will slide up and down when the value of 'visible' changes from true to false and vice versa.</div>

我发现角度方式有点难以掌握,但是一旦你理解了它,它就会变得非常简单和强大。

人类语言中的动画部分:

我们将此动画命名为“slideInOut”。

添加元素时(:enter),我们执行以下操作:

->立即将元素向上移动 100%(从其自身),以显示在屏幕外。

->然后为 translateY 值设置动画,直到我们达到 0%,即元素自然所在的位置。

当元素被移除时,将 translateY 值(当前为 0)设置为 -100%(屏幕外)。

我们使用的缓动功能是缓入,在 200 毫秒内,您可以根据自己的喜好进行更改。

希望这会有所帮助!

【讨论】:

这个工作,这是我最关心的:D 对于 Angular 5,我还必须将 BrowserAnimationsModule 添加到 app.module.ts 中的导入列表中。 我很难理解为什么 Angular 的样本喜欢定义一个默认的 'in' 状态,如 state('in', style(transform: 'translateX(0)')),,而正如您所展示的,*ngIf 确实没有必要。 我很久以前就赞成这个答案......终于可以使用它了!!上帝!你太棒了 @Simon_Weaver 我认为他们这样做是为了定义设计的“状态”,例如,您可以过渡到。所以“In”是你可以告诉你正在做的动画的东西。或者对于更清晰的示例“hasNoData”与“hasData”或“isLoadedFromPage”与“isLoadedFromModal”。定义了这些状态后,您可以定义它们之间的转换。 “进”和“出”很容易理解。 “hasData”到“hasNoData”也许你淡出某些东西/淡入其他东西。等:)【参考方案2】:

最受欢迎的答案是没有实现真正的滑入/滑出(或向下/向上),因为:

    它没有对高度属性进行软过渡。在时间为零时,元素已经达到其 100% 的高度,这会在其下方的元素上产生突然的故障。 当滑出/上滑时,元素执行translateY(-100%) 然后突然消失,导致其下方元素再次出现故障。

您可以像这样实现滑入和滑出:

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;

【讨论】:

缓和怎么样?【参考方案3】:

实际上,最少需要使用 Angular(如原始问题中所要求的)只是在 show 变量为 true 时向 DOM 元素添加一个类,并通过 CSS 执行动画/过渡。

所以你的 最小 Angular 代码是这样的:

<div class="box-opener" (click)="show = !show">
    Open/close the box
</div>

<div class="box" [class.opened]="show">
    <!-- Content -->
</div>

使用此解决方案,您需要为过渡创建 CSS 规则,如下所示:

.box 
    background-color: #FFCC55;
    max-height: 0px;
    overflow-y: hidden;
    transition: ease-in-out 400ms max-height;


.box.opened 
    max-height: 500px;
    transition: ease-in-out 600ms max-height;

如果您有复古浏览器兼容性问题,请记住在 transitions 中添加供应商前缀。

见the example here

【讨论】:

简单,干净,对我来说效果很好。谢谢!注意:适用于具有“块”显示而不是 td、tr 的元素。【参考方案4】:

我回答了一个非常相似的问题,这是一种方法:

首先,创建一个文件,您将在其中定义动画并导出它们。只是为了让你的 app.component.ts 更清楚

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

此动画使用状态(进出),当我们单击按钮时将切换状态,这将运行动画。

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://angular-muvaqu.stackblitz.io/

旁注:如果发生错误并要求您添加 BrowserAnimationsModule,只需将其导入您的 app.module.ts:

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

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

【讨论】:

以上是关于Angular (4, 5, 6, 7) - ngIf 上滑入滑出动画的简单示例的主要内容,如果未能解决你的问题,请参考以下文章

Angular (4, 5, 6, 7) - ngIf 上滑入滑出动画的简单示例

angular 双向绑定demo

Angular 6 ng lint combineLatest 已弃用

运行离子服务时出错:[ng] 错误:Angular 编译器需要 TypeScript >=4.4.2 和 <4.5.0,但找到了 4.5.2

ng2-dnd 与 Angular 4

angularjs--------ng-bind绑定