WebberUI

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.jsonfiles[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型別預設值說明
questionReact.ReactNode題目描述,顯示在最上方
answernumber真實答案數值
minnumber0量尺最小值
maxnumber100量尺最大值
stepnumber1拖曳與鍵盤步進
defaultGuessnumber量尺中點非受控初始猜測值
crowdnumber[]其他讀者的猜測;提供時揭曉後顯示分佈直方圖
format(value: number) => string千分位 + suffix數值格式化函式
suffixstring""數值後綴(如 %
onReveal(r: GuessGapResult) => void揭曉時觸發,回傳 { guess, answer, gap }
durationnumber0.9揭曉數字滾動時長(秒)

GuessTrendReveal Props

Prop型別預設值說明
knownGuessTrendDatum[]已知歷史資料點,折線由此段起始
unknownGuessTrendDatum[]待猜測資料點,含真實 value 作為答案
domain[number, number]依資料自動推算Y 軸範圍
heightnumber220SVG 高度(px,含底部標籤區)
format(v: number) => string千分位 + suffix數值格式化函式
suffixstring""數值後綴
onReveal(r: GuessTrendResult) => void揭曉時觸發,回傳 { guesses, answers, meanAbsError }
durationnumber1真實折線描繪時長(秒)

GuessTrendDatum{ label: string; value: number }

細節

  • 兩階段狀態機revealed 之前只更新猜測、之後鎖定輸入並播放揭曉動畫。按「再猜一次/再畫一次」可回到猜測階段重來。
  • 落差色塊:滑桿版在兩標記之間長出斜紋色塊;趨勢版以「猜測線去程 + 真實線回程」構成封閉多邊形填色,直觀呈現高估/低估的區域。
  • 群眾分佈:滑桿版的 crowd 會分箱成直方圖,揭曉時逐格生長,並將命中真實答案的分箱加深,方便對照「多數人猜哪裡、真相在哪」。
  • 純中性色:全元件僅用 neutral-*dark: 變體,靠實心/空心、實線/虛線與深淺區分「你的猜測」與「真實」,不依賴額外色票。

可及性

  • 猜測控點為 role="slider",具備 aria-valuemin/max/now/valuetext;支援方向鍵(滑桿版另有 PageUp/PageDownHome/End)微調,趨勢版每個控點可獨立聚焦與上下鍵調整。
  • 揭曉結果透過 aria-live="polite" 的狀態區朗讀,讓螢幕閱讀器使用者也能得知真實值與落差。
  • 開啟「減少動態效果」時,數字滾動、色塊生長與折線描繪皆改為即時呈現,功能與資訊完全不變。

On this page