WebberUI

Play/Pause Morph

播放三角形與暫停長條之間平順變形的圖形按鈕,支援受控/非受控雙模式與選填進度環。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

0.4
<PlayPauseMorph />

安裝

npx shadcn@latest add https://webberui.com/r/play-pause-morph.json

或在 components.json 設定 registries 後,改用 @webberui/play-pause-morph 安裝。

安裝依賴後,從 registry JSON(/r/play-pause-morph.jsonfiles[0].content)複製 play-pause-morph.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion clsx tailwind-merge

使用

import { PlayPauseMorph } from "@/components/ui/play-pause-morph";

<PlayPauseMorph defaultPlaying={false} onPlayingChange={(p) => console.log(p)} />

受控模式與進度環

const [playing, setPlaying] = React.useState(false);

<PlayPauseMorph
  size="lg"
  playing={playing}
  onPlayingChange={setPlaying}
  progress={0.42}
/>

傳入 playing 即進入受控模式,內建狀態停用,開關完全由你的 state 主導。傳入 progress(0–1)時,按鈕外圈會多出一圈進度環。

Props

Prop型別預設值說明
playingboolean受控播放狀態;提供時由外部主導
defaultPlayingbooleanfalse非受控模式的初始播放狀態
onPlayingChange(playing: boolean) => void切換時觸發,回傳切換後的狀態
variant"solid" | "soft" | "ghost""solid"視覺變體
size"sm" | "md" | "lg""md"尺寸(32 / 40 / 48px)
progressnumber選填 0–1 進度;提供時顯示外圈進度環
playLabelstring"播放"暫停中的 aria-label(按下會播放)
pauseLabelstring"暫停"播放中的 aria-label(按下會暫停)

其餘 <button> 原生屬性(disabledonClickclassName…)皆可透傳。在 onClick 中呼叫 preventDefault() 可攔下該次切換(適合先做非同步授權)。

細節

  • 播放三角形沿中線切成左右兩塊四邊形,與暫停的兩根長條採用相同的四點路徑結構,因此可逐點內插 SVG 的 d 屬性,讓圖形真正「變形」而非淡入淡出。
  • morph 採用彈簧過場,收放帶有自然的回彈手感。
  • 進度環以 pathLength 正規化為 1,用 strokeDashoffset 表示已播放比例,數值變動時平順補間。

可及性

  • 以原生 <button> 實作,EnterSpace 皆可觸發,焦點有清晰的 focus-visible 外框。
  • aria-label 隨狀態切換:播放中為「暫停」、暫停中為「播放」,明確描述按下後的動作。
  • 圖形以 aria-hidden 對輔助科技隱藏,避免朗讀無意義的向量內容。
  • 使用者系統開啟「減少動態效果」時,morph 與縮放回饋直接定格切換,不影響功能。

On this page