iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
自我挑戰組

向網頁施點魔法粉 framer-motion 系列 第 8

#08 Everything in ... transition type

  • 分享至 

  • xImage
  •  


在第二天的時候有提到 transition 除了預設的 spring 彈簧效果,還有其他的種類,並且不同種類對應不同的設定數值,今天來認識這些值。除了 tween 以外,大多跟物理運動狀態有關,想要讓它看起來自然一點,了解現實的物理運動狀態是不可少的,但別擔心今天沒要上物理課,畢竟我本人的物理也不是很好...

目錄

  1. 腦補專家 : Tween 補間動畫
  2. 這個虎克不是船長 : Spring 彈性
  3. 靜者恆靜 動者恆動 : Inertia 慣性
  4. 下面一位 ! transitionEnd
  5. 補充 : 所以我說那個偽元素呢 ! 偽元素在 JSX 怎麼操作 ?

腦補專家 : Tween 補間動畫

如果有使用過 Adobe Flash (Animate) 就會知道要幫一段動畫打上關鍵影格,然後再中間加上補間動畫,電腦就會很聰明的把中間動畫補上,形成一連串完整動畫。

在 motion 元件動畫跟子元素交互編排 (Orchestration) 沒有設定 transition type 的情況下,transition type 預設值會變成 tween。

const parent = {
  show:{
    transition:{
      // 沒有 type 這裡預設會是 tween
      when : 'aftetChidren',
      staggerChildren: 0.3
    },
  },
}

其他屬性

  • duration : number 動畫持續時間
  • ease : 緩動函數 (Easing function),ease 的值可以是
    • string 已被定義的動畫函數字串
    • number[] 4 個值組成陣列的貝茲曲線 (x1,y1,x2,y2)
    • number 介於 0 到 1 的值
  • from : number | string 跟 CSS animation 一樣的 from,to,預設是目前的動畫狀態。
  • times : string[] 類似 CSS animation 的 keyframes 時間軸,每一個值介於 0 到 1 之間,對應 duration
<motion.div
  initial={{...}}
  animate={{
    x : [0,100,-100,0]
  }}
  transition={{
    type:"tween"
    ease : "easeInOut"
    from : 100
    times: []
  }}
/>

內部定義好的動畫函數

Framer 已經有定義好的字串,直接使用就能套上。 詳細的動態變化很推薦看 : 緩動函數 (Easing function) 小抄

  • "linear" : 線性
  • "easeIn", "easeOut", "easeInOut" : 最常使用的一組
  • "circIn", "circOut", "circInOut" : 激動版 ease
  • "backIn", "backOut", "backInOut" : 就像先往後拉在往前推
  • "anticipate" : 在動畫十二法則中描述動畫要有預期性。想像有一個動作是一個人要跳過檻,它需要先續力,再發力。

例如跑步這件事,動畫都會有一個預備的動作 ,2 就是觀眾預告心理,通常在動畫裡這裡的楨數會拉長一些。

(圖源來自網路)

拿關鍵影格大比喻概是這樣,後面會比較緊湊,因為能量用光了。

這個虎克不是船長 : Spring 彈性

同時也是發現細胞的那位。虎克定律(Hooke's law) 大家都在國中時碰過,定義是 :

當固體材料受力之後,材料中的應力與變形量(應變)之間成線性關係。

以數學表示 : https://chart.googleapis.com/chart?cht=tx&amp;chl=F%20%3D%20-kx

同時也讓我想起 簡諧運動 QoQ ,自從高中再也沒碰過的東西,腦中可以先浮現振幅的圖,在想像上會蠻有幫助的。

* 粗體為比較常設定值

  • duration : 持續時間,最大值是 10 秒。如果有同時設定 bounce 屬性,最大是 8 秒。
  • bounce : 如果設定 duration,預設值為 0.25,值越小越ㄉㄨㄞ。
  • damping : 阻尼(減震),預設值為 10 ,類似摩擦力,越大越不會震動。
  • mass : 質量,預設值為 1,越大越沉重,用在動畫表現上就像暈暈沉沉的。
  • stiffness : 剛性,抗形變的程度,預設值為 100,越大越快代表物體移動越快。
  • velocity : 初始速度 v0 ,預設是元素當下的速度 (距離/時間 = 速度)。

最後兩個很少用,我還在研究中。

如果在 bounce 跟 duration 存在的情況下,又設定 dampingmassstiffness,前者會被覆寫效果。概念是想讓物體越彈跳,你的阻尼 (減震) 就不能太大,質量太重也沒辦法彈,而剛性太大導致物體沒辦法做彈跳。

靜者恆靜 動者恆動 : Inertia 慣性

牛頓是不少人求學時的噩夢 QQ 。Inertia type 特別用再滾動 (scrolling) 動畫上,官方的範例展示了 文字滾動速度配合滾輪移動的距離

Inertia 主要根據初始速度對 進行減速 的動畫。除了應用在滾動的動畫上,還有拖曳的互動上 :

  • modifyTarget : 可以看做最後到達的終點,也可以用在 grid 上,會恰恰好貼到其邊緣
  • bounceStiffness : 如果有設定邊界值 (min、max) 預設值為 500,影響彈簧動畫的剛性
  • bounceDamping : 如果有設定邊界值 (min、max),影響彈簧動畫的阻尼 (damping),效果跟彈簧的阻尼一樣。
  • power : 作功,預設值為 0.8,越大距離越遠
  • timeConstant : 時間常數,預設為 700。改變減速的持續時間

下面一位 ! transitionEnd 事件

在 JavaScript 有 transitionEnd 事件可以讓我們知道目前 CSS transition 動畫結束的屬性 ,並且再進行其他的操作 :

element.addEventListener('transitionEnd',(e)=>{ ... })

而在 motion 元件中 transition 裡可以使用 transitionEnd 屬性在特定動畫序列的尾聲添加最後的 CSS 效果 :

const variants={
  show: {
    x : 100,
    transition:{ ... },
    transitionEnd:{
      display:'none' // 跑到定點後消失
    }
  }
}

總結

動畫屬性要認識的最好方式就是 動手玩玩,就會知道之間差別在哪裡。

下一篇進入 motion Component 的部份,在 layout 已經偷跑先介紹過 LayoutGroup 這個元件,還有兩個常見好用的元件。

上面都用比較淺的概念帶過,如果對數學上很有興趣,這兩篇會很有幫助 :

  1. 貝茲曲線 : Cubic Bézier: from math to motion - Maxime Heckel's Blog
  2. 彈簧動畫的背後原理 : The physics behind spring animations - Maxime Heckel's Blog

參考資料

  1. 官方文件 : Transition | Framer for Developers
  2. 時間函式 cheat Sheet : 緩動函數 (Easing function) 小抄

上一篇
#07 Magic is happening again - layout type & layoutGroup
下一篇
#09 Bye Bye Bye ! AnimatePresence Component
系列文
向網頁施點魔法粉 framer-motion 15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言