Angular (4, 5, 6, 7) - простой пример слайд-анимации на ngIf
Каков минимум и родной способ Angular4 вставлять и выдвигать элемент контейнера?
например
<div ngIf="show">
<!-- Content -->
</div>
Вставьте содержимое (сверху вниз, точно так же, как jQuery. SlideDown ()), когда показ превратится в true.
Выдвиньте содержимое (соответственно с эффектом замедления), когда показ превратится в false.
3 ответа
Сначала некоторый код, затем объяснение. Официальные документы, описывающие это, находятся здесь.
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 миллисекунд вы можете изменить ее по своему вкусу.
Надеюсь это поможет!
Я ответил на очень похожий вопрос, и вот способ сделать это:
Сначала создайте файл, в котором вы будете определять свои анимации и экспортировать их. Просто чтобы сделать это более понятным в вашем 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, которое нужно использовать (как и требовалось в исходном вопросе), это просто добавление класса к элементу 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
s.
Смотрите пример здесь
Самый популярный ответ - не реализовать реальное скольжение внутрь / наружу (или вниз / вверх), как:
- Он не выполняет плавный переход по атрибуту высоты. В нулевой момент времени элемент уже имеет 100% своей высоты, что вызывает внезапный сбой в элементах под ним.
- При выдвижении / подъеме элемент совершает
translateY(-100%)
а затем внезапно исчезает, вызывая еще один сбой в элементах под ним.
Вы можете вставить и выдвинуть слайд следующим образом:
мой-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 }))]),
]),
],
})
мой-component.html
<div @slideDownUp *ngIf="isShowing" class="box">
I am the content of the div!
</div>
мой-component.scss
.box {
overflow: hidden;
}