通過CSS Animation進行前端動效

來源:互聯網
上載者:User
這篇文章主要介紹了關於通過CSS Animation進行前端動效,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

前言

對於簡單的補間動畫,我們可以通過transition實現。那到底多簡單的動畫適合用transtion來實現呢?答案就是——我們只需定義動畫起始和結束幀的狀態的動畫。一旦主要畫面格數大於2時,我們必須轉向CSS Animation了。本文為這段時間學習的記錄,歡迎拍磚。

簡單粗暴介紹CSS Animation 規則和屬性

定義主要畫面格動畫

文法:

@keyframes <Animation Name> {  [<Animation Time Offset> {    /* CSS Properties */  }]*}

樣本:

@keyframes rotate {  from { transform: rotate(0deg); }  to { transform: rotate(360deg); }}

注意項:
1.<Animation Name>的命名規範

// 命名需要遵循以下規則const rIsInvalid = /^--|^[0-9]+-|^(?:unset|initial|inherit|none)$/    , rIsValid = /^[0-9a-z-_\\]+$/ifunction isValidAnimationName(animationName: string): boolean{  return !rIsInvalid.test(animationName) && rIsValid(animationName)}

2.<Animation Time Offset>取值
0-100%from,等價與0%to,等價與100%
3.<Animation Name>重複怎麼辦
@keyframes CSS規則不支援層疊樣式,因此當出現多個同名keyframes,那麼僅最後出現的那個有效。

/* 無效 */@keyframes rotate {  from { transform: rotate(0deg); }  to { transform: rotate(360deg); }}/* 生效 */@keyframes rotate {  from { transform: rotate(90deg); }  to { transform: rotate(-360deg); }}

4.<Animation Time Offset>重複怎麼辦
與@keyframes CSS規則一樣,標準規定相同的主要畫面格不產生層疊,僅最後出現的認定為有效。
但實際上FireFox14+和Chrome均將主要畫面格設計為可層疊的。

@keyframes rotate {  from { transform: rotate(0deg); }  from { background: red; }  /* 上述兩條time offset實際上等價於   * from { transform: rotate(0deg); background: red; }   */  to {    transform: rotate(360deg);    background: yellow;  }}

5.!important導致屬性失效
一般情況下使用!important會讓CSS屬性獲得最高權重,但在@keyframes下卻會導致該CSS屬性失效。

@keyframes rotate {  from {    transform: rotate(90deg);    background: red!important; /* background屬性無效 */  }  to { transform: rotate(-360deg); }}

6.必須提供至少兩個主要畫面格

/* 不會根據easing 函式產生動畫效果,而是在動畫期間的最後瞬間移動過去 */@keyframes move-left{   to {       left: 100px;   }}

使用動畫

<css-selector> {  animation: <animation-name>             <animation-duration>             <animation-timing-function>             <animation-delay>             <animation-iteration-count>             <animation-direction>             <animation-fill-mode>             <animation-play-state>;}

樣本:

.box.rotate {  animation: rotate 10s infinite alternate;}

子屬性介紹

<animation-name>,指定通過@keyframes定義的補間動畫名稱。
<animation-duration>,動畫持續時間長度,預設為0s。單位為s和ms。
<animation-delay>,動畫播放延遲,預設為0s。單位為s和ms。
<animation-iteration-count>,動畫重複播放次數,預設為1,infinite表示無限迴圈。動畫播放總時間長度為<animation-duration>*<animation-iteration-count>
<animation-direction>,可選值為normal | reverse | alternate | alternate-reverse,分別表示動畫播放順序是從from到to從to到from從from到to再從to到from從to到from再從from到to注意:設定alternate|alternate-reverse時,animation-iteration-count必須大於1才能看到效果
<animation-fill-mode>,可選值為none | forwards | backwards | both,用於設定動畫開始前和結束後是否應用0%100%的樣式對元素上。分別表示不應用應用100%的樣式延遲播放期間應用0%的樣式0%和100%的樣式均應用
注意:

  1. 預設情況下(none),動畫結束後會恢複動畫前的樣式;

  2. 設定backwards時,<animation-delay>值大於0才能看到效果。

<animation-play-state>,可選值running | paused,擷取和設定播放狀態。注意:通過這個屬性,我們僅能實現暫停和繼續播放的效果,無法實現重播,更別說回放了
<animation-timing-function>,用於設定easing 函式類型,值為ease | ease-in | ease-out | ease-in-out | linear | step-start | step-end | steps(<integer>, <flag>) | frames(<integer>) | cubic-bezier(<number>,<number>,<number>,<number>)
其中ease | ease-in | ease-out | ease-in-out | linear | cubic-bezier(<number>,<number>,<number>,<number>)的效果均為連續漸層的,而step-start | step-end | steps(<integer>, <flag>) | frames(<integer>)則為突變效果。下面我們深入理解後者吧。

easing 函式-step解疑專題

step-start實際上等價於steps(10, start),而step-end則等價於steps(10),所以我們只要理解好steps(<integer>, <flag>)即可。

/* 通過設定在一個動畫周期內(<animation-duration>)的平均重新整理幀數,實現突變動效。具體應用有:遊戲精靈行走、打字效果等 * <number_of_steps> - 兩個主要畫面格間的重新整理次數 * <direction> - 方向,可選值為 end | start。 *               end為預設值,表示動畫一結束,動畫效果就結束; *               start表示動畫一開始就馬上執行完第一個主要畫面格的效果。 */steps(<number_of_steps>, <direction>)

從張旭鑫那偷來的解釋:
start:表示直接開始。也就是時間才開始,就已經執行了一個距離段。於是,動畫執行的5個分段點是下面這5個,起始點被忽略,因為時間一開始直接就到了第二個點:
end:表示戛然而止。也就是時間一結束,當前距離位移就停止。於是,動畫執行的5個分段點是下面這5個,結束點被忽略,因為等要執行結束點的時候已經沒時間了:

另外通過將<animation-fill-mode>設定為forwards,那麼當<direciton>設定為end時,也會顯示(保持)動畫最後一個主要畫面格的樣式。

事件

const target = document.getElementById("target")target.addEventListener("animationstart", e => {  // 動畫開始時觸發})target.addEventListener("animationiteration", e => {  // 每次重複執行動畫時觸發  // 當<animation-iteration-count>為1時,不會觸發。})target.addEventListener("animationend", e => {  // 當動畫結束時觸發})

搞盡腦汁實現重播效果

到這裡我們已經可以通過@keyframes定義和應用CSS Animation了,但我們能否擷取對動畫效果更多的控制權呢?如開始、暫停、繼續、重播。通過<animation-play-state>我們能輕易實現開始、暫停和繼續的效果,但重播卻沒那麼容易。

function pause (target: HTMLElement):boolean {  const isRunning = target.style.animationPlayState == "running"  if (isRunning) {    target.style.animationPlayState = "paused"  }    return isRunning}function play (target: HTMLElement):boolean {  const isStop = target.style.animationPlayState == "paused"  if (isStop) {    target.style.animationPlayState = "running"  }    return isStop}function replay (target: HTMLElement, animationClassName: string):void {  // 先移除動畫效果  target.classList.remove(animationName)  // requestAnimationFrame的回呼函數會在下一次介面渲染前執行  requestAnimationFrame(_ => {    // 這時動畫的影響還在,所以要等介面渲染完後再重新啟用動畫效果,才能實現重播    requestAnimationFrame(_ => {      target.classList.add(animationName)    })  })}

總結

CSS3為我們提供了動畫效果,除了提供比Transition更豐富的可控性,比JavaScript更簡易的API,還讓我們可以使用GPU來加速呢^_^

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.