Angular (4, 5, 6, 7) - Простой пример слайд-анимации на ngIf

Каков минимальный и родной способ Angular4 вставлять и выдвигать элемент контейнера?

например

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

Вставьте содержимое (сверху вниз, как jQuery. SlideDown()), когда шоу превратится в true.

Выдвиньте содержимое (соответственно с эффектом замедления), когда показ превратится в false

Ответ 1

Сначала немного кода, затем объяснения. Официальные документы, описывающие это, здесь.

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>

Я нашел способ angular немного сложнее понять, но как только вы это понимаете, он довольно прост и эффективен.

Часть анимаций в человеческом языке:

  • Мы назовем эту анимацию "slideInOut".
  • Когда элемент добавлен (: введите), мы делаем следующее:
  • → Сразу же перемещайте элемент на 100% вверх (от себя), чтобы отобразиться на экране.
  • - > анимируйте значение translateY до тех пор, пока мы не достигнем 0%, где, естественно, будет элемент.

  • Когда элемент удален, анимируйте значение translateY (в настоящее время 0), -100% (за пределами экрана).

Функция ослабления, которую мы используем, облегчается, через 200 миллисекунд вы можете изменить это по своему вкусу.

Надеюсь, это поможет!

Ответ 2

Я ответил на очень похожий вопрос, и вот способ сделать это:

Сначала создайте файл, в котором вы определяете свои анимации и экспортируете их. Чтобы сделать это более ясным в вашем app.component.ts

В следующем примере я использовал максимальную высоту div, которая идет от 0px (когда она скрыта), до 500 пикселей, но вы измените ее в соответствии с тем, что вам нужно.

Эта анимация использует состояния (в и из), которые будут переключаться, когда мы нажимаем на кнопку, которая будет запускать анимацию.

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

Ответ 3

На самом деле минимальное количество Angular, которое нужно использовать (как было запрошено в исходном вопросе), это просто добавление класса к элементу DOM, когда переменная show равна true, и выполнение анимации/перехода с помощью CSS.

Итак, ваш минимальный угловой код:

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

Если у вас есть проблемы с ретро-браузерной совместимостью, просто не забудьте добавить префиксы вендора в transition.

Смотрите пример здесь

Ответ 4

Анимация:

animations: [
    trigger('openClose', [
        state('open', style({
            height: '*',
            opacity: '1'
        })),
        state('closed', style({
            height: '0px',
            opacity: '0'
        })),
        transition('open => closed', [
            animate('0.5s')
        ]),
        transition('closed => open', [
            animate('0.5s')
        ]),
    ]),
],

Узел для анимации в шаблоне:

<whatever [@openClose]="show ? 'open' : 'closed'"></whatever>

Кнопка переключения в шаблоне:

<button (click)="toggleShow()">
    <span *ngIf="show; else hideNode">Hide</span>
    <ng-template #hideNode>Show</ng-template>
</button>

Код компонента:

export class ShowHideComponent {
    show = false;

    toggleShow() {
        this.show = !this.show;
    }
}