Frontend Lab
← 回到所有效果
F05A012framer-motion

Number Count Up

數字滾動

難度 ★★★★★標籤 數字 · animate · useInView2 min read

效果簡述

數字從 0 跳到目標值,常用在 KPI / 訂閱數 / 轉換率展示。用 framer-motion 的 animate() 函式驅動 + useInView 觸發即可,不用裝額外套件。

0

累計數字(示意)· 1.8s

預設|0 → 12450, 1.6s

Claude Code Prompt

💬 Claude Code Prompt
參考:A012 number count up
技術:framer-motion animate() + useInView

具體行為:
- ref 綁 span,useInView(ref, { once: true, amount: 0.5 })
- inView 時呼叫 animate(0, target, { duration: 1.8, ease: [0.2,0.8,0.2,1], onUpdate: v => setN(Math.round(v)) })
- 顯示用 toLocaleString() 加千分位
- cleanup: controls.stop() in unmount

限制:
- duration 1.5~2 秒
- 大數字才有戲(小於 20 沒感)
- 不要每個都加,一頁 1~3 個夠

完整程式碼

NumberCountUp.tsx
'use client'

import { animate, useInView } from 'framer-motion'
import { useEffect, useRef, useState } from 'react'

export function NumberCountUp({ target = 12450 }: { target?: number }) {
const ref = useRef<HTMLSpanElement>(null)
const inView = useInView(ref, { once: true, amount: 0.5 })
const [n, setN] = useState(0)

useEffect(() => {
  if (!inView) return
  const controls = animate(0, target, {
    duration: 1.8,
    ease: [0.2, 0.8, 0.2, 1],
    onUpdate: (v) => setN(Math.round(v)),
  })
  return () => controls.stop()
}, [inView, target])

return <span ref={ref}>{n.toLocaleString()}</span>
}

何時用

  • ✅ Landing page KPI 展示
  • ✅ Dashboard 數字進場
  • ✅ 成就解鎖 / 統計總結

何時別用

  • ❌ 數字頻繁變動的場景(每次都跳一遍很煩)
  • ❌ 表格 / 列表內的多個數字(會閃成一片)
  • ❌ 小數字(< 20 沒戲劇感)

我踩過的坑

  1. 沒 cleanup 切頁會 warning:unmount 時不 stop(),React 會抱怨 setState on unmounted。return () => controls.stop() 一定要。

  2. Math.round(v) 不能漏:不取整會看到 12449.7382 那種抖動。

  3. 大數字加 toLocaleString():12450 → 12,450 才好讀。

相關效果

搜尋

按 ⌘K 隨時開啟