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