typescript - Angular (4、5、6、7) - ngIf 上進出滑動動畫的簡單範例
用最基本的方法以及 Angular4 原生的方式,如何讓容器元素 滑入 和 滑出?
例如
<div ngIf="show">
<!-- Content -->
</div>
當 show 變為 true 時,Slide In 內容(從上到下,就像 jQuery.slideDown() 一樣)。
當 show 變為 false 時,滑出 內容(適當地帶有 ease-out 效果)。
答案#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』。
當元素被添加時(:enter),我們執行以下操作:
->立即將元素向上移動100%(相對於自身),以顯示在螢幕之外。
->然後動畫化 translateY 值,直到到達 0%,此時元素將自然處於該位置。
當元素被移除時,將 translateY 的值(目前為 0)動畫化至 -100%(螢幕之外)。
我們使用的緩動函數是 ease-in,時間為 200 毫秒,你可以根據自己的喜好更改它。
答案#2
我回答過一個非常相似的問題,這裡有一種做法:
首先,創建一個文件,在那裡定義你的動畫並導出它們。只是為了在你的 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 ],
...
})
答案#3
實際上,所需使用的最少 Angular(如原問題所要求的)只是當 show 變數為 true 時向 DOM 元素添加一個 class,並通過 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;
}
如果你有舊版瀏覽器相容性問題,只要記得在 transition 中加入廠商前綴即可。
在這裡查看範例
