banner
Jrenc

Jrenc

There’s a million things I haven’t done。
x
github
email
bilibili

CSS動畫實現

創建動畫的 API#

在 CSS 中創建動畫主要依賴於以下幾個關鍵的 API:

  1. @keyframes 規則

    • 用於定義動畫的中間步驟(關鍵幀)。在 @keyframes 規則中,可以設定在動畫過程中某個或某些時刻元素的樣式。
    @keyframes example {
      from {background-color: red;}
      to {background-color: yellow;}
    }
    

    或者使用百分比來指定多個關鍵幀:

    @keyframes example {
      0%   {background-color: red;}
      50%  {background-color: blue;}
      100% {background-color: yellow;}
    }
    

    @keyframes 規則什麼時候觸發?

    • 當元素綁定了 animation-name 屬性,並且動畫開始時,@keyframes 規則中定義的關鍵幀將按照指定的時間和速度曲線進行執行。
    • 例如,上面的 example 動畫在 animation-name 屬性中綁定到元素後,將按照 animation-durationanimation-timing-function 屬性的設置進行執行。
  2. animation-name 屬性

    • 指定需要綁定到選擇器的 @keyframes 名稱。
    .element {
      animation-name: example;
    }
    
  3. animation-duration 屬性

    • 定義動畫完成一個週期所花費的時間,例如秒或毫秒。
    .element {
      animation-duration: 2s;
    }
    
  4. animation-timing-function 屬性

    • 定義動畫的速度曲線,例如 linear, ease, ease-in, ease-out, ease-in-out, 或者 cubic-bezier 函數。
    .element {
      animation-timing-function: ease-in-out;
    }
    

    在 CSS 動畫中,可以通過指定動畫的速度曲線來控制動畫的變化速度。以下是一些常用的速度曲線:

    1. linear

      • 動畫從頭到尾的速度是相同的。這意味著動畫以恆定速度平滑地進行,沒有加速或減速的過程。
    2. ease

      • 預設的速度曲線。動畫以低速開始,然後加速,最後再減速。這使得動畫看起來更自然,因為它模擬了現實世界中物體的運動狀態。
    3. ease-in

      • 動畫以低速開始,隨著動畫的進行,速度逐漸增加,直到結束。這種曲線適用於需要強調動作開始階段的場景。
    4. ease-out

      • 動畫以全速開始,然後逐漸減速直到停止。這種曲線適用於需要強調動作結束階段的場景。
    5. ease-in-out

      • 動畫以低速開始和結束,中間部分以較快的速度運動。這種速度曲線是ease-inease-out的結合,適用於需要平滑過渡的場景。
    6. cubic-bezier(n,n,n,n)

      • 允許你自定義一個速度曲線。cubic-bezier函數接受四個參數,這些參數定義了一個三次貝塞爾曲線,可以精確控制動畫的加速和減速過程。CSS 提供了一個cubic-bezier工具,幫助你可視化和調整這四個參數。
        ease-n. 容易;舒適,自在
        v. 減輕,緩和,放鬆;緩緩移動;使容易;降低;使離職;熟悉
  5. animation-delay 屬性

    • 設置動畫在啟動前的延遲時間。
    .element {
      animation-delay: 1s;
    }
    
  6. animation-iteration-count 屬性

    • 定義動畫應該播放的次數,可以是數字或者 infinite 表示無限次重複。
    .element {
      animation-iteration-count: infinite;
    }
    
  7. animation-direction 屬性

    • 指定動畫是否應該輪流反向播放。常見值有 normal, reverse, alternate, alternate-reverse
    .element {
      animation-direction: alternate;
    }
    
  8. animation-fill-mode 屬性

    • 指定在動畫執行之前和之後如何為目標元素應用樣式。例如,forwards 保留最後一幀的樣式。
    .element {
      animation-fill-mode: forwards;
    }
    

    animation-fill-mode 屬性在 CSS 動畫中用來指定一個動畫在執行之前和之後如何將樣式應用到其目標元素上。簡而言之,它決定了動畫執行前後元素的樣式表現。animation-fill-mode 屬性接受以下幾個值:

    1. none
      • 預設值。不改變預設行為。動畫不會將任何樣式應用於目標元素,動畫結束後元素會回到動畫未執行時的狀態。
    2. forwards
      • 動畫完成後,元素將保留由動畫的最後一個關鍵幀計算值決定的樣式。即動畫結束後元素會保留動畫結束時的樣式。
    3. backwards
      • 動畫將在應用於元素的那一刻立即應用第一關鍵幀的樣式,即使動畫延遲開始。這意味著元素會立即獲得動畫初始狀態的樣式,直到動畫真正開始。
    4. both
      • 動畫遵循forwardsbackwards的規則,意味著動畫會在延遲期間應用第一關鍵幀的樣式,並在動畫結束後保留最後一個關鍵幀的樣式。

    例如,如果你有一個淡出動畫,你可能希望動畫結束後元素保持透明

  9. animation 簡寫屬性

    • 可以使用 animation 簡寫屬性同時設置所有動畫屬性。
    .element {
      animation: example 2s infinite ease-in-out;
    }
    
  10. animation-play-state 屬性

    • 控制動畫的播放狀態。可以設置為 paused 暫停動畫,或者 running 繼續播放動畫。
    .element {
      animation-play-state: paused;
    }
    
  11. 使用 CSS 變量控制動畫

    • CSS 變量(自定義屬性)可以與動畫結合使用,為動畫提供動態值或實現主題定製。
    :root {
       --animation-duration: 2s;
    }
    
    .element {
      animation-duration: var(--animation-duration);
    }
    
  12. 使用@media 查詢和動畫

    • 可以結合媒體查詢來應用不同的動畫效果,使動畫響應不同的螢幕尺寸或設備特性。
    @media (max-width: 600px) {
      .element {
        animation-name: exampleSmallScreen;
      }
    }
    
  13. will-change 屬性

    • 提前告知瀏覽器元素將要進行的變化,以優化性能。雖然不是直接控制動畫的屬性,但適當使用可以提高動畫的流暢度。
    .element {
      will-change: transform, opacity;
    }
    
  14. 利用 CSS 動畫實現性能優化

    • 在可能的情況下,使用 transform 和 opacity 動畫,因為它們可以通過硬體加速,提高動畫的性能。
  15. 動畫事件

    • 雖然 CSS 本身不直接提供事件監聽機制,但在 JavaScript 中,可以監聽動畫相關的事件,如 animationstart, animationend, 和 animationiteration,以在動畫的不同階段執行腳本。
    document.querySelector('.element').addEventListener('animationend', function() {
      console.log('動畫結束');
    });
    

動畫 API 的實踐#

1. keyframes 的使用#

.button {
  cursor: pointer;
  animation-duration: 3ms;
}
@keyframes button {
  0% {
    background-color: aqua;
  }
  100% {
    background-color: bisque;
  }
}

問題:它無法觸發,動畫一般何時觸發?

.button {
   cursor: pointer;
   animation-duration: 3s;
   animation-name: bgcolor;
   animation-delay: 0s;
   animation-timing-function: ease-in;
   background-color: aqua;
   animation-fill-mode: both;
   animation-iteration-count: infinite;
}
@keyframes bgcolor {
   0% {
      background-color: rgb(0, 140, 140);
   }
   100% {
      background-color: rgb(208, 127, 29);
   }
}

  • animation-name 屬性就是將 keyframes 的名字賦值給它,這樣就可以觸發動畫了。然後它是預設第一次加載的時候就會觸發一次的。如果你綁定上。
  • animation-duration 屬性是表示動畫持續時間;
  • animation-delay 屬性是表示動畫延遲時間;
  • animation-timing-function 是動畫時間函數,就是這個動畫它是以什麼函數執行的;linear,ease,ease-in,ease-in-out 等。而 ease 就是輕鬆,減輕的意思,ease-in 就是慢慢進。
  • animation-iteration-count 是動畫的次數,iteration 就是迭代重複的意思,count 就是次數的意思。所以這個屬性就是表示動畫的次數。然後它設置的參數可以是 1,2,3,4,5... 也可以是 infinite,表示無限次重複。
  • animation-play-state 是動畫的播放狀態,paused 就是暫停的意思,running 就是運行的意思。
  • animation-fill-mode 是動畫的填充模式,forwards 就是向前的意思,在這裡是應用最後一幀的設置,backwards 就是向後的意思在這裡是應用第一幀的設置,一般這個第一幀是它原來的設置而不是動畫幀的第一個 0%,both 就是兩者都有的意思,這裡差不多和 forwards 相似。

2. 實現一個 hover 屬性#

  • keyframers 懸停動畫的實現
.button {
   cursor: pointer;

   background-color: antiquewhite;
}
.button :hover {
   animation-name: bgcolor;
   animation-duration: 3s;
   background-color: antiquewhite;
}

@keyframes bgcolor {
   0% {
      background-color: rgb(0, 140, 140);
   }
   100% {
      background-color: rgb(208, 127, 29);
   }
}
  • 問題:為什麼懸停動畫沒有實現?
  • 解決:將 button 改為.button,因為問題出在.button :hover選擇器上。在 CSS 選擇器中,.button :hover表示選擇.button內部的任何元素在懸停時的狀態,而不是.button本身在懸停時的狀態。這是因為.button:hover之間有一個空格,這代表了一個後代選擇器,意味著它將選擇.button的子元素的懸停狀態,而不是.button本身。
.button {
  cursor: pointer;

  background-color: antiquewhite;
}
.button:hover {
  animation-name: bgcolor;
  animation-duration: 3s;
  background-color: antiquewhite;
  animation-iteration-count: infinite;
}

@keyframes bgcolor {
  0% {
    background-color: rgb(0, 140, 140);
  }
  50% {
    background-color: rgb(208, 127, 29);
  }
  100% {
    background-color: rgb(0, 140, 140);
  }
}

3. 實現一個點擊事件#

為什麼我點擊後沒有反饋?

.button {
  cursor: pointer;

  background-color: antiquewhite;
}
.button:checked {
  animation-name: bgcolor;
  animation-duration: 3s;
  background-color: antiquewhite;
  animation-iteration-count: infinite;
}

@keyframes bgcolor {
  0% {
    background-color: rgb(0, 140, 140);
  }
  50% {
    background-color: rgb(208, 127, 29);
  }
  100% {
    background-color: rgb(0, 140, 140);
  }
}

問題在於使用了 .button:checked 選擇器,這個選擇器通常用於表單元素(如複選框、單選按鈕等)的選中狀態,而不是用於常規的按鈕元素。如果你的 .button 是一個 <button><div> 元素,:checked 偽類選擇器是不適用的,因此點擊時不會有任何效果。

如果你想在點擊按鈕後觸發動畫,可以考慮以下幾種方法:

  1. 使用 JavaScript 在點擊事件發生時添加一個類,然後通過這個類來觸發動畫。
  2. 如果是希望有點擊(或觸摸)的即時反饋,可以考慮使用 :active 偽類。但請注意,:active 狀態僅在元素被激活(即鼠標按下期間)時生效,一旦鼠標松開,元素就會立刻回到正常狀態。
  3. 對於能夠切換狀態的按鈕(如開關按鈕),可以使用隱藏的複選框(checkbox)和標籤(label)來實現。用戶點擊標籤時會改變複選框的選中狀態,從而通過複選框的 :checked 偽類來控制動畫。

改為 active 之後是激活狀態,但是松開鼠標就會回到原來的狀態。也就是說你鼠標一直按著的時候它是執行動畫的,松開就不執行了。
這不應該是點擊事件,應該叫:按住事件

那如何實現點擊事件動畫呢?

.button {
   cursor: pointer;
   background-color: antiquewhite;
}

.animate {
   animation-name: bgcolor;
   animation-duration: 3s;
   animation-iteration-count: infinite;
}

@keyframes bgcolor {
   0% {
      background-color: rgb(0, 140, 140);
   }
   50% {
      background-color: rgb(208, 127, 29);
   }
   100% {
      background-color: rgb(0, 140, 140);
   }
}
document.getElementById('animatedButton').addEventListener('click', function() {
this.classList.add('animate');
});

4. 實現其他動畫效果,旋轉,放大縮小,移動等#

CSS 的transform屬性允許你對元素進行移動、縮放、旋轉、傾斜等變形操作。以下是一些常用的transform函數:

  1. 平移(Translate)

    • translate(x, y):沿 X 軸和 Y 軸移動元素。
    • translateX(x):只沿 X 軸移動元素。
    • translateY(y):只沿 Y 軸移動元素。
    .translate {
      transform: translate(50px, 100px); /* 向右移動50px,向下移動100px */
    }
    
  2. 縮放(Scale)

    • scale(x, y):沿 X 軸和 Y 軸縮放元素。
    • scaleX(x):只沿 X 軸縮放元素。
    • scaleY(y):只沿 Y 軸縮放元素。
    .scale {
      transform: scale(2, 3); /* 寬度放大2倍,高度放大3倍 */
    }
    
  3. 旋轉(Rotate)

    • rotate(angle):旋轉元素,angle是旋轉角度,單位可以是deg(度)、rad(弧度)等。
    .rotate {
      transform: rotate(45deg); /* 順時針旋轉45度 */
    }
    
  4. 傾斜(Skew)

    • skew(x-angle, y-angle):沿 X 軸和 Y 軸傾斜元素。
    • skewX(angle):只沿 X 軸傾斜元素。
    • skewY(angle):只沿 Y 軸傾斜元素。
    .skew {
      transform: skew(30deg, 20deg); /* 沿X軸傾斜30度,沿Y軸傾斜20度 */
    }
    
  5. 組合使用

    • transform屬性可以組合使用多個變形函數,按照指定的順序應用於元素。
    .combine {
      transform: rotate(30deg) translate(100px, 50px) scale(1.5);
    }
    

    這個例子中,.combine類的元素首先被旋轉 30 度,然後沿 X 軸和 Y 軸移動,最後整體放大 1.5 倍。

  6. matrix變換在 CSS 中是一個非常強大的變換工具,它可以通過一個 6 值的矩陣來組合所有的 2D 變換效果(平移、旋轉、縮放、傾斜)。這個矩陣是這樣的:

    • scaleX()scaleY()分別代表沿 X 軸和 Y 軸的縮放比例。
    • skewX()skewY()分別代表沿 X 軸和 Y 軸的傾斜角度。
    • translateX()translateY()分別代表沿 X 軸和 Y 軸的平移距離。
    • matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY())
      使用matrix變換可以實現包括平移、縮放、旋轉、傾斜在內的所有 2D 變換效果,但它不直觀,需要一定的數學知識來構造合適的矩陣值。
      但是,要注意的是,matrix變換本身只適用於 2D 變換,對於 3D 變換(如在 Z 軸的平移或旋轉),則需要使用matrix3d或其他 3D 變換相關的函數(如translateZ()rotateX()rotateY()rotateZ()perspective()等)。因此,如果你的問題是詢問matrix是否可以處理 3D 變換,那麼答案是不能。對於 3D 變換,你應該使用matrix3d或者組合使用其他 3D 變換函數。

使用transform屬性可以在不影響頁面佈局的情況下對元素進行視覺上的變形,是實現複雜動畫和佈局效果的強大工具。此外,transform通常配合transitionanimation屬性一起使用,以實現平滑的過渡效果。

.button {
  cursor: pointer;

  background-color: antiquewhite;
}
.button:active {
  animation-name: bgcolor;
  animation-duration: 3s;
  background-color: antiquewhite;
  animation-iteration-count: infinite;
}
.button:hover {
  animation-name: aaa;
  animation-duration: 3s;
  background-color: antiquewhite;
  animation-iteration-count: infinite;
}

@keyframes bgcolor {
  form {
    transform: rotate(32deg);
  }
  to {
    transform: rotate(90deg);
  }
}
@keyframes aaa2 {
  form {
    transform: scale(1);
  }
  to {
    transform: scale(2);
  }
}
@keyframes aa21a {
  form {
    transform: skew(2deg);
  }
  to {
    transform: skew(60deg);
  }
}
@keyframes aaa {
  form {
    transform: translate(0px, 0px);
  }
  to {
    transform: translate(0px, 250px);
  }
}

5. 漸變過渡動畫效果#

  • transition 實現漸變動畫
.button {
  width: 20px;
  cursor: pointer;
  transform: none;
  transition-property: transform width;
  transition-duration: 2s;
  background-color: antiquewhite;
}

.button:hover {
  width: 230px;
  transform: rotate(49deg);
}

  • transform 轉變動畫
.button {
  cursor: pointer;
  transform: none;
  transition: 2s;
  background-color: antiquewhite;
}

.button:hover {
  transform: rotate(49deg);
}

它們本質上都是通過 transition 實現的漸變動畫。transform 也是 css 的屬性一部分而已。

6. 構造@keyframes動畫:#

  • 使用 JavaScript 構造一個完整的@keyframes動畫,並將其插入到文檔的<style>標籤中。
  • 示例:
    var duration = '2s';
    var fromPosition = '-100%';
    var toPosition = '0';
    var styleSheet = document.createElement('style');
    styleSheet.type = 'text/css';
    styleSheet.innerHTML = `@keyframes dynamicSlideIn {
      from { transform: translateX(${fromPosition}); }
      to { transform: translateX(${toPosition}); }
    }`;
    document.head.appendChild(styleSheet);
    
    var elem = document.getElementById('myElement');
    elem.style.animationName = 'dynamicSlideIn';
    elem.style.animationDuration = duration;
    elem.style.animationFillMode = 'forwards';
    
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。