Angular (4, 5, 6, 7) - Simple example of slide in out animation on ngIf

喜欢而已 提交于 2019-12-18 10:03:18

问题


What is the bare minimum and Angular4's native way to slide in and slide out a container element?

e.g.

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

Slide In Content (from top to down just like jQuery.slideDown()) when show turns to true.

Slide Out Content (suitably with ease-out effect) when show turns to false.


回答1:


First some code, then the explanaition. The official docs describing this are 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%)'}))
      ])
    ])
  ]
})

In your template:

<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>

I found the angular way a bit tricky to grasp, but once you understand it, it quite easy and powerful.

The animations part in human language:

  • We're naming this animation 'slideInOut'.
  • When the element is added (:enter), we do the following:
  • ->Immediately move the element 100% up (from itself), to appear off screen.
  • ->then animate the translateY value until we are at 0%, where the element would naturally be.

  • When the element is removed, animate the translateY value (currently 0), to -100% (off screen).

The easing function we're using is ease-in, in 200 milliseconds, you can change that to your liking.

Hope this helps!




回答2:


I answered a very similar question, and here is a way of doing this :

First, create a file where you would define your animations and export them. Just to make it more clear in your app.component.ts

In the following example, I used a max-height of the div that goes from 0px (when it's hidden), to 500px, but you would change that according to what you need.

This animation uses states (in and out), that will be toggle when we click on the button, which will run the animtion.

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'
            }))
        ]
        )])
    ]),
]

Then in your app.component, we import the animation and create the method that will toggle the animation state.

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);
    }
  }
}

And here is how your app.component.html would look like :

<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 refers to the animation trigger defined in animations.ts

Here is a StackBlitz example I have created : https://angular-muvaqu.stackblitz.io/

Side note : If an error ever occurs and asks you to add BrowserAnimationsModule, just import it in your app.module.ts:

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

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



回答3:


Actually the minimum amount of Angular to be used (as requested in the original question) is just adding a class to the DOM element when show variable is true, and perform the animation/transition via CSS.

So your minimum Angular code is this:

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

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

With this solution, you need to create CSS rules for the transition, something like this:

.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;
}

If you have retro-browser-compatibility issues, just remember to add the vendor prefixes in the transitions.

See the example here



来源:https://stackoverflow.com/questions/47248898/angular-4-5-6-7-simple-example-of-slide-in-out-animation-on-ngif

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!