天天看點

了解一下全新的CSS動畫合成屬性 animation-composition

作者:閃念基因

介紹一個在Chrome 112上剛剛正式推出的 CSS 動畫合成屬性:animation-composition

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-composition[1]

日後非常有用的一個特性,快來了解一下吧

一、從 CSS 抛物線運動說起

衆所周知,抛物線運動是一個水準方向上勻速、垂直方向上勻加速的合成運動

了解一下全新的CSS動畫合成屬性 animation-composition

image-20230421153754886

這個其實用 CSS 動畫也很好實作,水準和垂直兩個方向的位移動畫分别用不同的動畫緩存函數

有興趣的可以參考張鑫旭的這篇文章:這回試試使用CSS實作抛物線運動效果[2]

這裡簡單介紹一下

實作這樣的效果需要一個嵌套結構

<div class="ball-x">
  <div class="ball-y"></div>
</div>
           

然後裡外設定不同的動畫緩沖函數

.ball-x { 
  animation-timing-function: linear; /*勻速直線運動*/
}
.ball-y { 
  animation-timing-function: cubic-bezier(.55, 0, .85, .36);  /*大緻勻加速運動*/
}
           

運動分解效果如下:

了解一下全新的CSS動畫合成屬性 animation-composition

Kapture 2023-04-21 at 17.26.05

那麼問題來了,為啥這裡需要用到兩層标簽呢?僅僅為了分解水準運動和垂直運動嗎?如果隻使用一層标簽會怎麼樣?

這個稍後再說

二、動畫合成屬性

現在來介紹今天的主角。首先看文法,還是非常簡單的

/* 單個值 */
animation-composition: replace; 
animation-composition: add;/*追加*/
animation-composition: accumulate;/*混合*/
/* 多個值,暫不讨論 */
animation-composition: replace, add;
animation-composition: add, accumulate;
animation-composition: replace, add, accumulate;
           

主要是這 3 個關鍵詞:

  • replace:覆寫(預設值)。動畫會覆寫原有屬性。
  • add:追加。動畫追加到原有屬性後面。
  • accumulate:累加。動畫會和原有屬性相同的部分進行累加。

光看文法和描述可能不知道是做什麼的,特别是add和accumulate,差異非常微妙,直接看一個例子。

假設有一個元素,預設有一些樣式

div{
  transform-origin: 50% 50%;
 transform: translateX(50px) rotate(45deg);
}
           

然後,給一個動畫,關鍵幀是這樣的

@keyframes adjust {
  to {
    transform: translateX(100px);
  }
}
           

下面是 3 個關鍵詞的效果對比

了解一下全新的CSS動畫合成屬性 animation-composition

Kapture 2023-04-21 at 18.58.23

demo參見 https://codepen.io/web-dot-dev/pen/VwGRBVX[3]

可以從動畫運作的終點看出這幾種合成的差異。

第一個replace,也就是預設效果。其實就是直接将transform中的translateX(50px) rotate(45deg)變成了translateX(100px)。

了解一下全新的CSS動畫合成屬性 animation-composition

image-20230421192925447

第二個add。可以了解成直接在transform後追加,也就是最後變成了translateX(50px) rotate(45deg) translateX(100px),等同于先向右移動50px,然後旋轉45deg,再向右移動100px。下面是拆解過程(注意旋轉軸)

了解一下全新的CSS動畫合成屬性 animation-composition

image-20230421192859456

第三個accumulate。可以了解成将已有的translateX(50px)累加,最後結果是translateX(150px) rotate(45deg)

了解一下全新的CSS動畫合成屬性 animation-composition

image-20230421194110419

怎麼樣,這幾種差異明白了嗎?

當然這些動畫合成都是針對于相同的屬性而言,對于不同的屬性,本來就沒有産生任何幹擾,自然不會用到這個特性。

三、再來看抛物線運動

現在回過頭來看前面那個例子。如果隻用一層标簽如何實作?

假設水準、垂直兩個方向的動畫關鍵幀是這樣的

@keyframes ballMoveX {
    100%{
        transform: translateX(300px) 
    }
}
@keyframes ballMoveY {
 100% { 
        transform: translateY(300px)
    } 
}
           

然後小球将這兩個動畫合起來

.ball{
    animation: 
    ballMoveX 1s linear infinite alternate, 
    ballMoveY 1s cubic-bezier(.55, 0, .85, .36) infinite alternate;
}
           

可以得到一個很奇怪的動畫

了解一下全新的CSS動畫合成屬性 animation-composition

Kapture 2023-04-21 at 19.44.49

原因其實是這兩個屬性沖突了,後面的動畫覆寫了前面的,導緻動畫的結束點其實是translateY(300px)

像這種情況下,用動畫合成屬性就非常合适了

.ball{
    ...
   animation-composition: add; /*accumulate也行*/
}
           

add和accumulate都行,因為translateX和translateY并不能累加,隻能追加。

效果如下

了解一下全新的CSS動畫合成屬性 animation-composition

Kapture 2023-04-21 at 19.49.14

這樣就得到了正常的抛物線運動了

完整代碼可以檢視以下任意連結:

  • CSS animation-composition (juejin.cn)[4]
  • CSS animation-composition (runjs.work)[5]
  • CSS animation-composition (codepen.io)[6]

四、相容性和總結

提一下相容性。這方面 Safari居然跑在了前頭,然後Chrome也是最近得到了正式支援,Firefox目前仍然是實驗支援,不過離正式支援也不遠了。也就是說這個特性以後一定會全相容,也不用擔心學着學着突然都放棄了。相容性清單如下:

了解一下全新的CSS動畫合成屬性 animation-composition

image-20230422113128869

相信大家已經對動畫合成有了一定的了解,下面總結一下要點:

可以用一杯水來做比方

  1. replace:替換。将這杯水倒掉,然後倒進一杯油
  2. add:追加(疊加)。在這杯水上倒入一些油,油覆寫在了水上
  3. accumulate:累加(混合)。在這杯水倒入奶茶,裡面都有水,混合在了一起

當然,最重要的一點是,隻有碰到一些有沖突的動畫時才需要考慮用這個特性,你學到了嗎?

作者:XboxYan

來源:微信公衆号:前端偵探

出處:https://mp.weixin.qq.com/s/Nq4i2cTW6ng1k_MXVPa4Qg

繼續閱讀