iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
自我挑戰組

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

#14 Move & Bounce Again - useTranfrom & useSpring

  • 分享至 

  • xImage
  •  

前一篇有提到 motion value 是可以搭配 useTransform 串聯多個值一起用的,可以根據一個/組數值產生一連串新的 motion value,而 useSpring 是可以針對彈簧動畫的值進行手動操作。

目錄

  1. 南北菜蟲一起串聯 : useTransform
  2. 複雜的計算 : useTransform function
  3. 混在一起算 : 結合多個值
  4. 再談彈簧動畫 : useSpring

南北菜蟲一起串聯 : useTransform

useTransform 是以一個 motion value 為基準,並根據 motion value 的輸入值的範圍,產生另一個 motion value,具有映射 (Mapping) 的特色。

useTransform(value, input, output, options)
  • value : motion value

  • input : value 的變化範圍,必須是線性的,正負數都可以,這樣才可以使 output 被推算出來

  • output : 其他別於 value 屬性的值,比如說 value 是 x ,output 可以是 opacity 等其他屬性 。作用是當 x 變化會對應到特定的 opacity 值,另外 output 也可以是數字、顏色、陰影 (shadow)。不過要注意 陣列長度要跟 input 一樣。例 : useTransform(x,[0,0,100,100],[0,1,1,0]) ,input 與 output 定義的範圍陣列長度要一樣。

  • options : 關於轉換區間的值可以有不同的計算方式,有兩種

    1. clamp : 布林值 (Boolean) 。true 是預設,允許從最大、最小以及區間值做變化,超過就以兩端值為極限。false 是超過範圍的依然會計算出值給你。
    2. ease : 緩動函式,根據 ease function 的數值變化。
    3. mixer : (from: T, to: T) => (p: number) 。簡單來說是透過自定義的函式計算變化值。數組前後兩兩一組根據 p 的 ease 緩動值 0 到 1 來決定從 from 到 to 的混和程度。
  • 最簡單的使用 useTransform

const opacity = useTransform(
  x,
  // x 的範圍值
  [0, 100],
  // 對應 opacity 的值 
  [1, 0]
)
  • 有 clamp 與沒 clamp 差別 :
const opacity = useTransform(x,[0, 100],[1, 0],{clamp: false})

以旋轉為例 :

clamp 被取消後超過最大值還是會自己推理算出 rotate 的值

  • 透過範圍可以做到滑鼠跟蹤轉向效果 :

    motion value 與 useTransform 搭配 :
const x = useMotionValue(0);
const y = useMotionValue(0);

const rotateX = useTransform(y, [0, 400], [45, -45]);
const rotateY = useTransform(x, [0, 400], [-45, 45]);

複雜的計算 : useTransform function

除了放入一個固定的範圍值,也可以用函式來計算

export const MyComponent = () => {
  const x = useMotionValue(10)
  // 按照 cos 圖形上下擺動,第二個參數是 function ,其函式的參數是最新的 x 值
  const y = useTransform(x, value => Math.cos(value / 10) * 50)

  return <motion.div style={{ x, y }} />
}
  • 效果 :

混在一起算 : 結合多個值

輸入值除了一個之外,也可以使用陣列相關性的一組,透過兩個數值

export const MyComponent = () => {
  const x = useMotionValue(0)
  const y = useSpring(0)
  
  const z = useTransform(
    [x, y],
    ([latestX, latestY]) => latestX * latestY
  )
  return <motion.div style={{ x, y, z }} />
}

再談彈簧動畫 : useSpring

跟彈簧運動有關的值,可以接收來自別的 motion value ,也可以創造一個 motion value。

// 創造
const spring = useSpring(0)

// 使用 useMotionValue 的值
const x = useMotionValue(0)
const spring = useSpring(x)

第二個參數是一個物件,接收跟 transition type = spring 一樣的內容 :

useSpring(x, { stiffness: 1000, damping: 10 })

這樣可以控制在不同時刻的動畫數值呈現不同的動畫效果。

要注意的是操作 motion value 是副作用,相關的操作最好要在 useEffect 裡面。

const x = useSpring(0)

useEffect(() => {
  x.set(target)
}, [target])

return <motion.div style={{ x }} />

可以參考 官方範例

總結

官方的範例展示起來都好酷,也有一點難度 QQ ,最近正在收集一些動畫特效,我在想想看要怎麼搭進去範例中。明天會講到有關卷軸事件相關的 useScrolluseInView

參考資料

  1. 官方文件 ─ useTransform : useTransform | Framer for Developers
  2. 官方文件 ─ useSpring : useSpring | Framer for Developers
  3. Framer Books : The Framer book » Animation » Example Animations » 26. Tracking the cursor

上一篇
#13 The New Style - useMotionValue & useMotionTemplate
下一篇
#15 Bump in to you - useScroll & useInView
系列文
向網頁施點魔法粉 framer-motion 15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言