讓咱們來寫一個卡片彈出動畫

準備工做

挖槽 好牛逼

爲了能更容易理解,在開始以前,咱們要先達成4個共識。javascript

4個共識css

唱 跳 rap 打籃球html

... 咳咳咳 很差意思,跑題了java

下面 真的開始了 :git

1. transition 和 animation

讓咱們回憶下是怎麼用使用動畫的:github

(1)transitionweb

.foo { width: 100px; trantions:  1s; }

.foo:hover { width: 120px;}
複製代碼

設置元素 兩個不一樣的狀態 和 過渡的時間。編程

當咱們觸發變化,瀏覽器看到樣式變化以後,爲咱們建立動畫api

(2)animation瀏覽器

@keyframes cardaniIn {
   0%,
   39%,
   100% {
    -webkit-animation-timing-function: cubic-bezier(1, 0, 0.47, 1);
    animation-timing-function: cubic-bezier(1, 0, 0.47, 1);
   }
   
   0% {
    -webkit-transform: rotateY(0deg) scale(0.8) translate3d(0, 0, 0);
    transform: rotateY(0deg) scale(0.8) translate3d(0, 0, 0);
  }
  
  39% {
    -webkit-transform: rotateY(0deg) scale(0.8) translate3d(0, -50px, 0);
    transform: rotateY(0deg) scale(0.8) translate3d(0, -50px, 0);
   }
   
   100% {
    -webkit-transform: rotateY(180deg) scale(1) translate3d(0, 0, 0);
    transform: rotateY(180deg) scale(1) translate3d(0, 0, 0);
   }
 }
複製代碼

animation

animation 容許咱們寫多個狀態值,爲咱們解鎖了一次告訴瀏覽器多個狀態變化的能力。

共同點就是,

告訴瀏覽器咱們想要的樣式,並讓瀏覽器看到樣式的變化

瀏覽器看東西的方式和咱們不太同樣,

瀏覽器一秒有不少幀,每一幀瀏覽器都會作不少事情,

其中包括計算style的變化,

2個幀之間

由於咱們的修改 致使 元素的樣式不同的時候,瀏覽器就看到了樣式的變化,並建立動畫。

咱們要達成的第 1 個共識就是:

咱們建立動畫,實際是在告訴瀏覽器 不一樣幀之間 元素樣式的變化。

2. 動畫儘可能只用 transform 和 opacity

瀏覽器1s有不少幀,每一幀瀏覽器都會作大量的工做。

其中 layout 從新佈局 paint 繪製 是最耗時的兩個工做。

transformopacity 的只會觸發 composite合成的這一個步驟,

瞭解這一點 是咱們建立流暢動畫的關鍵

咱們要達成的第 2 個共識就是:

動畫儘可能只用 transform 和 opacity

3. display 和 visibility

display:none;visibility: hidden;都會讓元素不可見,

(1)display:none; 不可見,不佔據空間,更完全,會把元素從render tree移走,發生一次重排。

(2)visibility: hidden;讓元素視覺上不可見,而且不可點擊交互。可是仍然佔據空間,能夠得到位置等相關信息,切換visibility不會發生重排。

因此在特定的狀況下,好比咱們將要寫的動畫中(下面會說,須要元素不可見,可是須要位置信息),能夠用visibility: hidden;來隱藏元素。

咱們要達成的第 3 個共識就是:

能夠考慮用visibility控制元素的顯隱

6. 996 的壓力會讓人數學和記憶能力變差

禿然

FLIP

讓咱們開始吧

咱們把動畫分紅2個部分,第一個部分,總體的位置和大小變化

總體變化

還記得咱們的第 1 條共識嗎,

咱們建立動畫,實際是在告訴瀏覽器 不一樣幀之間 元素樣式的變化。

如今同樣,這個動畫包括寬高和位置變化,咱們須要告訴瀏覽器2個幀的 width offsetTop offsetLeft

2個幀

FISRT

獲取第一幀的樣式

var fisrtDom = params.fisrtDom;
var fisrtReact = fisrtDom.getBoundingClientRect();
console.log( fisrtReact )
複製代碼

第一幀

LAST

獲取最後一幀的樣式

var lastDom = params.lastDom;
var lastReact = lastDom.getBoundingClientRect();
console.log( lastReact );
複製代碼

Invert

如今讓咱們計算兩個狀態的差值,並把差值應用在要動畫的元素上。

還記得咱們的第 2 和 第 3 條共識嗎,

動畫用 transform ,元素的顯隱用visibility

因此這裏咱們用的是 transform 和 元素的顯隱用visibility。

play

最後,讓它動起來吧。

當咱們 取消 transform 的值的時候,元素的transform將會變回 默認的 translate3d(0,0,0) scalce(1),

瀏覽器看到樣式的變化 和 transtion 就會爲咱們建立動畫了。

實際上,這是一種叫作 FLIP 的技術。

first (第一幀) L (最後一幀) I (倒轉) P (播放)

專門用於建立這種動畫

第二部分動畫比較簡單,留給你們自由發揮。

web Animations Api

有一個叫作 web Animations Api 的api, 對咱們建立動畫有很大的幫助,

讓咱們能用編程的方式建立動畫。

像咱們的例子中,能夠這樣用

web Animations Api 最棒的地方在於, 能把動畫實例保存起來,

咱們在作卡片收起動畫的時候,不用再次計算。

直接 animateInstance.reverse() 就能夠反轉播放動畫。

web Animations Api 不是本文的重點,能夠自行去了解一下 它 和 它的 poyFill 低版本兼容的插件。


參考資料

性能優化 developers.google.cn/web/fundame…

CSS動畫你應該知道的10件事 www.yuque.com/cssconf/5th…

FLIP相關 www.w3cplus.com/animation/h…

FLIP相關 www.w3cplus.com/javascript/…


... ...

動畫雖然完成了,可是因爲 我的能力 和 項目的進度,

已經不容許我,去解決路由和分享頁面的問題了,很遺憾,沒上到正式環境

心塞,爲了避免拖項目進度,天天起早一個小時寫這個東西,仍是流產了。之後閒下來能夠會再撿起來

... ...

這不是一篇嚴謹的教程,更多的是我我的的總結和分享,

文中可能會有錯誤遺漏的地方,請多多見諒,權當拋磚引玉。

加 coco 的qq羣 418766876,一塊兒交流鴨...

. . . 蘋果的動畫好細膩精緻 . . .

相關文章
相關標籤/搜索