Angular 2 + 折騰記 :(10) 初步瞭解動畫,以及一步一步寫個動畫效果

CRPER發表於2017-04-13

前言

過渡動畫這東西,在現代開發中是必不可少的,死板和酷炫與之息息相關;

ng2.x動畫相關的api是併入@angular/core這個核心模組的,在angular4之後開始獨立

但是,寫法上差異不大,只是引入變了,引入方式請參考我的這篇文章的:
問題2: 動畫已經獨立出一個專門的模組


angular2+的過渡動畫簡介

Angular動畫是基於標準的Web動畫API(Web Animations API)構建的,
這API比較新,只有較新的瀏覽器才能支援(具體如下)

Can I Use : Web Animations API

用起來本質上還是css2.1&
3,只不過是放在api封裝好的物件內,也就是說,css3的基礎必須要好!!


過渡動畫的相關理論

大體的歸納一下有這麼幾點

  1. 動畫的過渡用於轉場之間,轉場的狀態可以自定義
  2. 預設的轉場包括如下(狀態樣式的生效可以通過傳遞對應的狀態值生效)
    • inactive =>
      active : 待啟用到啟用
    • void =>
      *
      : 進場,也可以寫成:enter , *是匹配任何動畫狀態,* =>
      *
      不會觸發轉場動畫
    • * =>
      void
      : 離場,也可以寫成:leave, void是代表元素還沒附加到檢視時候的特殊狀態

實戰

這裡拿一個最簡單的漸現過渡來演示,如圖


漸現程式碼

import { 
trigger, // 動畫封裝觸發,外部的觸發器 state, // 轉場狀態控制 style, // 用來書寫基本的樣式 transition, // 用來實現css3的 transition animate, // 用來實現css3的animations keyframes // 用來實現css3 keyframes的
} from '@angular/animations';
export const fadeIn = trigger('fadeIn', [ state('in', style({
display: 'none'
})), // 預設元素不展開 transition('void =>
*'
, [ // 進場動畫 animate(200, keyframes([ style({
height: '0', opacity: 0, offset: 0
}), // 元素高度0,元素隱藏(透明度為0),動畫幀在0% style({
height: '*', opacity: 1, offset: 1
}) // 200ms後高度自適應展開,元素展開(透明度為1),動畫幀在100% ])) ]), transition('* =>
void'
, [ animate(200, keyframes([ style({
height: '*', opacity: 1, offset: 0
}), // 與之對應,讓元素從顯示到隱藏一個過渡 style({
height: '0', opacity: 0, offset: 1
}) ])) ]),]);
複製程式碼

如何使用動畫?

用法非常簡單,在元件內呼叫即可;

具體有兩種;

  1. animations內直接寫實現動畫,animations接受的是一個陣列
  2. 封裝好引入 =》 推薦
  • components.ts
// 這是寫法2;
我是把動畫效果獨立封裝到對應的ts檔案內,方便複用
import {
fadeIn
} from '../../../../../animation/fadeIn';
import {
bounceIn
} from '../../../../../animation/bounceIn';
@Component({
selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.scss'], animations: [fadeIn, bounceIn]
})// 有人說為什麼不直接寫在程式碼內,比如下面這種寫法// 這種寫法推薦在獨立元件或者模組內,就是給第三方用,元件內部實現一個自己的過渡效果// 若是對應系統來說,降低耦合度更方便我們維護,也就是我推薦上面那種寫法的原因@Component({
selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.scss'], animations: [ trigger('fadeIn', [ state('in', style({
display: 'none'
})), // 預設元素不展開 transition('void =>
*'
, [ // 進場動畫 animate(200, keyframes([ style({
height: '0', opacity: 0, offset: 0
}), // 元素高度0,元素隱藏(透明度為0),動畫幀在0% style({
height: '*', opacity: 1, offset: 1
}) // 200ms後高度自適應展開,元素展開(透明度為1),動畫幀在100% ])) ]), transition('* =>
void'
, [ animate(200, keyframes([ style({
height: '*', opacity: 1, offset: 0
}), // 與之對應,讓元素從顯示到隱藏一個過渡 style({
height: '0', opacity: 0, offset: 1
}) ])) ]), ])]
})複製程式碼
  • html
<
!--不傳遞狀態直接呼叫, 用@符號來引用對應的動畫-->
<
h3 *ngIf="list &
&
list.length === 0"
class="text-center text-muted" @fadeIn>
暫無相關資料資訊!!!<
/h3>
<
/div>
<
!--傳遞狀態的,跟常規的繫結一致-->
<
h3 *ngIf="list &
&
list.length === 0"
class="text-center text-muted" [@bounceIn]="list.state">
暫無相關資料資訊!!!<
/h3>
複製程式碼

總結

  1. 動畫應該最大複用化,不然太多動畫,雖然效果挺炫的,那打包體積相對也大很多
  2. 對於不支援web-animationsAPI的瀏覽器,應當引入對應的polyfill來相容【web-animations】 , 當然相容也沒那麼逆天,也僅僅支援較新的瀏覽器,IE10+

來源:https://juejin.im/post/58ee487b8d6d810058125443

相關文章