【Angular】angular-animations 動畫 BrowserAnimationsModule 詳解
為了弄懂angular的動畫自己也是花了一番功夫,不客觀的說,angular的動畫寫起來是比較復雜的,但又必須掌握。
下面是我結合官方文檔的資料,自己通過實踐寫出來的一篇博客,希望可以幫到有需求的小伙伴,當然,如果文章有地方寫的錯誤,歡迎指正。
好了,廢話不多說,開始正文吧。
1:angular動畫的使用需要先引入一些與動畫有關的函數。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
組件里引用:(:暫時先在組件里寫動畫相關的代碼,文末會把它單獨抽離出來
import { Component } from '@angular/core';
import {trigger, state, style, animate, transition} from '@angular/animations';
注:有些小伙伴的項目開始的時候可能沒有動畫相應的資源包,請暫時允許我這么說。此時你就需要在項目依賴包里先加入這個資源。
如何加入呢?定位到你的項目上,命令行輸入:
npm install @angular/animations --save
當你檢查到你的package.json里出現:
此時說明動畫資源已經被成功下載了。ok,現在我們開始動畫吧:
**:開始第一個動畫(交通信號燈..):
1:請首先在你的組件.ts代碼里的@Component裝飾器里添加如下代碼:
animations: [
trigger('signal', [
state('go', style({
'background-color': 'green'
}))
])
]
模板(html)里添加:
<div class="traffic-light" [@signal]="'go'"></div>
css里樣式:
.traffic-light{ width: 100px; height: 100px; background-color: black; }
本來div定義的樣式背景色是黑色,但是div在頁面中卻呈現的是綠色,見圖:
現在問題來了,綠色怎么來的呢 ? 見圖:
因為div元素此時處于動畫里的go狀態。所以div具有go狀態里被描述的動畫樣式。
如果你不懂為什么要這樣定義動畫,暫時你只需要知道這樣寫就行了。
2:讓我們加入兩個按鈕,此時兩個按鈕要做的是:讓div元素切換不同的背景色。
此時可能有的小伙伴會覺得我直接用js寫不就好了嗎?(下面用原生js僅為提供意思,
btn1.onclick = function(){
div.style.background = 'xxx';
}
btn2.onclick = function(){
div.style.background = 'xxx';
}
請先務著急,不妨先看看利用動畫是如何制作呢。見模板:圖
見ts:圖
這個切換div不同背景顏色樣式上,實質的就是通過按鈕事件切換div的兩種動畫狀態。
3:讓我們來點復雜一點的:(: 見圖:
這個具備時間過渡的動畫的怎么來的呢?我們先見代碼:
在ts代碼里我只加了三句代碼,其中兩句是描述狀態中高度的變化,相信小伙伴們都懂,著重看看這個 ‘* => *’
問題來了,這個 * = >* 是個什么東西呢?
答:它是一個狀態遷移表達式,* 表示任意狀態,所以這個表達式告訴我們,只要有狀態的變化就會激發后面的動畫效果,使得元素做500毫秒的動畫。
也可以粗暴的這么講:*號匹配任意狀態,由 transition 關鍵字定義 何種狀態過渡到何種狀態。 只要狀態發生變化,就會執行 transition 里的anmate函數。
它類似于:
但不同的是,當第一次點擊的是stop的按鈕時,這么div是沒有出現時間過渡的。那是因為go狀態在stop之前定義,
先點擊stop時,不走transition這條定義。當點了go按鈕觸發go狀態時,stop的過渡才會生效。
4:然后介紹下一個特殊的狀態void, 何為void狀態呢,我們先添加一段代碼,見下圖:
我們會看見當頁面刷新的時候,div元素從頁面上方進入頁面。這個動畫如何產生的呢?再重復看這兩段代碼:
會發現,在class里我并沒有給signal成員變量賦初始值,這就意味著一開始trigger的狀態就是void。
void狀態就是描述沒有狀態值時的狀態,我們往往在實現進場或離場動畫時需要這個void狀態。
當然,void狀態也是一種任意狀態。所以:
transition('*=> *', animate(500))
//在這里等同于
transition('void => *', animate(500))
注:void狀態的動畫只是拿來“過渡”用的,它描述的樣式不是最終的樣式,而是過渡過程中產生的樣式,在規定的時間內完成后它是被“清除掉的”。
所以,這個動畫會在我規定的500毫秒里完成一個按Y軸做的-100%的位移。
5:當你看到,transition里的animate時會不會覺得似曾相識呢?沒錯,它和css3里的animation幾乎是一樣的
所以當然我們可以使用延遲,緩動函數,關鍵幀等來定義我們的動畫:
我們來見一個詳細的例子。
模板:
<div class="traffic-light" [@signal]="signal"></div>
<button (click)="go()">go</button>
<button (click)="stop()">stop</button>
ts:
import { Component } from '@angular/core';
import {trigger, state, style, animate, transition,keyframes} from '@angular/animations';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('signal', [
state('void', style({
'transform':'translateX(-100%)'
})),
state('go', style({
'background-color': 'green',
'height':'100px'
})),
state('stop', style({
'background-color':'red',
'height':'50px'
})),
transition('void => *', animate(5000, keyframes([
style({'transform': 'scale(0)'}),
style({'transform': 'scale(0.1)'}),
style({'transform': 'scale(0.3)'}),
style({'transform': 'scale(0.6)'}),
style({'transform': 'scale(0.8)'}),
style({'transform': 'scale(1)'})
]))),
transition('* => *', animate('.5s 1s cubic-bezier(0.2, 0.8, 0.3, 1.8)'))
])
]
})
export class AppComponent {
signal:string;
stop(){
this.signal = 'stop';
}
go(){
this.signal = 'go';
}
}
這個動畫是怎么產生的呢?
先見
在這個transition定義里,動畫共持續了五秒,對應的是每一個style,共分為:0s,1s,2s,3s,4s和5s
也就是當瀏覽器刷新時,入場動畫 void=>*的過程。
**我們有看見當我點擊go or stop按鈕時,按鈕等待了一點時間才執行動畫,是怎么回事呢?我們看這個transition的定義:
transition('* => *', animate('.5s 1s cubic-bezier(0.2, 0.8, 0.3, 1.8)'))
這個狀態定義表示任意狀態到任意狀態的過程,也就是我們點擊按鈕div當前的狀態到go or stop的狀態,表現為動畫1秒延遲后div以0.5秒的時間完成這個動畫。
這種在組件里寫動畫的方式是不夠優雅的,我們可以把這個動畫單獨提取出來,如何提取呢?
1:新創建一個動畫的ts文件,如animate.ts:
import {trigger, state, style, animate, transition,keyframes} from '@angular/animations';
export const SingalAnimate = trigger('signal', [
state('void', style({
'transform':'translateX(-100%)'
})),
state('go', style({
'background-color': 'green',
'height':'100px'
})),
state('stop', style({
'background-color':'red',
'height':'50px'
})),
transition('void => *', animate(5000, keyframes([
style({'transform': 'scale(0)'}),
style({'transform': 'scale(0.1)'}),
style({'transform': 'scale(0.3)'}),
style({'transform': 'scale(0.6)'}),
style({'transform': 'scale(0.8)'}),
style({'transform': 'scale(1)'})
]))),
transition('* => *', animate('.5s 1s cubic-bezier(0.2, 0.8, 0.3, 1.8)'))
]);
2:而后,在組件ts里引入:
import { SingalAnimate } from './animate';
3:最后,在元數據animation 里添加:
animations: [ SingalAnimate ]
npm start, 看看效果吧~
angular、spring cloud 開源實戰項目源碼:https://gitee.com/xfdm/FCat
QQ群:549141844代碼持續更新…
智能推薦
Android 動畫詳解
Android 動畫:你真的會使用插值器與估值器嗎?(含詳細實例教學) Carson_Ho 關注 2017.05.31 08:55* 字數 2591 閱讀 2049評論 8喜歡 54 前言 動畫的使用 是 Android 開發中常用的知識 可是動畫的種類繁多、使用復雜,每當需要 采用自定義動畫 實現 復雜的動畫效...
matlab動畫制作詳解
眾所周知,MATLAB的繪圖能力十分強大。有時,我們不僅需要繪圖,還需要制作一些動態視頻和動畫,下面就來介紹一些matlab里制作動畫和視頻常用的函數,并舉出一些實例。 一.animatedline animatedline函數可以幫助對線條動畫進行優化,允許用戶在不重新定義現有點的情況下,添加新的點。源代碼如下 運行結果 本段代碼參考自:https://cn.mathworks.com/help...
Animation動畫詳解
Unity的Animation動畫 Animation動畫制作 創建Animation Animation組件 調用Animation需要進行的操作 Animation代碼調用 如何Animation內部添加回調函數 Animation常用的方法 Animation動畫制作 目前的animation大多使用于前端的部分效果動畫,比如界面打開關閉界面的效果。 創建Animation 選中待提添加動畫...
詳解Canvas動畫部分
基礎篇: Html5中Canvas繪制、樣式詳解(不包含動畫部分) 此篇為后續 目錄 1. 狀態的保存和恢復 2. translate移動 3. 旋轉Rotating 4. 縮放Scaling? 5. 圖形相互交叉顯示規則 6. 裁切路徑 7. 動畫基本步驟 8. canvas相關的動畫js框架 1.狀態的保存和恢復 save() 保存畫布(canvas)的所有狀態 ...
猜你喜歡
屬性動畫詳解
1. 動畫分類 Android 中動畫分為 3 種:View 動畫(視圖動畫)、幀動畫、屬性動畫。 (1)幀動畫:將一系列的圖片按照順序播放,每一張圖片就是動畫中的一幀,連續播放后就形成了動畫,使用起來比較簡單,缺點是當圖片過多或者過大時,容易導致 OOM。 (2)View 動畫:動畫變化分為 4 種,平移、縮放、旋轉、透明度,通過這 4 種動畫其中的一種變換或者組合變換,使視圖完成一種漸進式的動...
Android動畫實現詳解
安卓中我們經常會使用動畫來渲染我們的APP,使其“動”起來,對于常用的動畫通常分為兩類:View Animation(視圖動畫)和Property Animation(屬性),當然View Animation又分為Frame Animation(幀動畫)和Tween Animation(補間動畫),因此常常會將動畫分為三種:Frame Animation,Tween Ani...
骨骼動畫詳解-Spine
轉自:https://blog.csdn.net/u012278016/article/details/79758967 游戲中人物的走動,跑動,攻擊等動作是必不可少,實現它們的方法一般采用幀動畫或者骨骼動畫。 幀動畫與骨骼動畫的區別在于:幀動畫的每一幀都是角色特定姿勢的一個快照,動畫的流暢性和平滑效果都取決于幀數的多少。而骨骼動畫則是把角色的各部分身體部件圖片綁定到一根根互相作用連接的&ldqu...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...