Guess Gap Reveal
猜測落差揭曉:先拖曳滑桿或畫出趨勢線猜答案,放手揭曉後真實數據以動畫浮現,並用色塊標示「你的猜測 vs 真實」的落差與其他讀者的猜測分佈。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
72
0.9
1
<GuessGapReveal />
安裝
npx shadcn@latest add https://webberui.com/r/guess-gap-reveal.json或在 components.json 設定 registries 後,改用 @webberui/guess-gap-reveal 安裝。
安裝依賴後,從 registry JSON(/r/guess-gap-reveal.json 的 files[0].content)複製 guess-gap-reveal.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
「先猜、再揭曉」是資料視覺敘事的經典手法:讓讀者先投入一個猜測,親手體會與真相的落差,記憶會更深刻。本元件提供兩款輸入方式,各為獨立 named export。
滑桿猜值(GuessGapReveal)
適合猜測「單一數值」的題目(比例、金額、票數⋯⋯)。拖曳圓點或用方向鍵選擇猜測值,按下揭曉後真實答案的標記浮現,兩者之間以斜紋色塊標示落差。傳入 crowd 時,會在揭曉時長出其他讀者的猜測分佈直方圖。
import { GuessGapReveal } from "@/components/ui/guess-gap-reveal";
<GuessGapReveal
question="你覺得有多少比例的人每天喝咖啡?"
answer={64}
min={0}
max={100}
suffix="%"
defaultGuess={40}
crowd={[24, 27, 30, 31, 33, 35, 40, 45]}
onReveal={({ gap }) => console.log("落差", gap)}
/>畫趨勢線(GuessTrendReveal)
適合猜測「一段走勢」的題目。給定已知的歷史區段 known 與待猜的未來區段 unknown(含真實 value),讀者拖曳每個控點畫出預期走勢;揭曉後真實折線以描邊動畫繪出,兩線之間的區域以色塊標示落差,並回報平均絕對誤差。
import { GuessTrendReveal } from "@/components/ui/guess-gap-reveal";
<GuessTrendReveal
known={[
{ label: "'19", value: 42 },
{ label: "'20", value: 39 },
{ label: "'21", value: 47 },
{ label: "'22", value: 58 },
]}
unknown={[
{ label: "'23", value: 71 },
{ label: "'24", value: 66 },
{ label: "'25", value: 88 },
]}
suffix="k"
/>GuessGapReveal Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
question | React.ReactNode | — | 題目描述,顯示在最上方 |
answer | number | — | 真實答案數值 |
min | number | 0 | 量尺最小值 |
max | number | 100 | 量尺最大值 |
step | number | 1 | 拖曳與鍵盤步進 |
defaultGuess | number | 量尺中點 | 非受控初始猜測值 |
crowd | number[] | — | 其他讀者的猜測;提供時揭曉後顯示分佈直方圖 |
format | (value: number) => string | 千分位 + suffix | 數值格式化函式 |
suffix | string | "" | 數值後綴(如 %、人) |
onReveal | (r: GuessGapResult) => void | — | 揭曉時觸發,回傳 { guess, answer, gap } |
duration | number | 0.9 | 揭曉數字滾動時長(秒) |
GuessTrendReveal Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
known | GuessTrendDatum[] | — | 已知歷史資料點,折線由此段起始 |
unknown | GuessTrendDatum[] | — | 待猜測資料點,含真實 value 作為答案 |
domain | [number, number] | 依資料自動推算 | Y 軸範圍 |
height | number | 220 | SVG 高度(px,含底部標籤區) |
format | (v: number) => string | 千分位 + suffix | 數值格式化函式 |
suffix | string | "" | 數值後綴 |
onReveal | (r: GuessTrendResult) => void | — | 揭曉時觸發,回傳 { guesses, answers, meanAbsError } |
duration | number | 1 | 真實折線描繪時長(秒) |
GuessTrendDatum 為 { label: string; value: number }。
細節
- 兩階段狀態機:
revealed之前只更新猜測、之後鎖定輸入並播放揭曉動畫。按「再猜一次/再畫一次」可回到猜測階段重來。 - 落差色塊:滑桿版在兩標記之間長出斜紋色塊;趨勢版以「猜測線去程 + 真實線回程」構成封閉多邊形填色,直觀呈現高估/低估的區域。
- 群眾分佈:滑桿版的
crowd會分箱成直方圖,揭曉時逐格生長,並將命中真實答案的分箱加深,方便對照「多數人猜哪裡、真相在哪」。 - 純中性色:全元件僅用
neutral-*與dark:變體,靠實心/空心、實線/虛線與深淺區分「你的猜測」與「真實」,不依賴額外色票。
可及性
- 猜測控點為
role="slider",具備aria-valuemin/max/now/valuetext;支援方向鍵(滑桿版另有PageUp/PageDown、Home/End)微調,趨勢版每個控點可獨立聚焦與上下鍵調整。 - 揭曉結果透過
aria-live="polite"的狀態區朗讀,讓螢幕閱讀器使用者也能得知真實值與落差。 - 開啟「減少動態效果」時,數字滾動、色塊生長與折線描繪皆改為即時呈現,功能與資訊完全不變。