應用殼層與面板

片段時間軸

影音剪輯式多軌時間軸:片段可拖移與拉長、吸附格線、播放頭拖曳與播放、時間尺隨縮放換刻度、留言釘與音訊波形。

這是 WebberUI Pro 元件

下方的安裝指令需要授權才能執行,未授權時會回 401。

怎麼安裝 Pro 元件 →查看方案 →

剪輯軟體那種多軌時間軸,做成可以直接放進網頁的元件:左側是軌道標頭(名稱、靜音、鎖定),右側是可水平捲動的時間區。片段可以拖移、拉兩端改長度,放開時吸附到次刻度與其他片段邊緣;同軌重疊會被拒絕並以 spring 回彈。播放頭可拖曳或點時間尺 seek,按空白鍵以 rAF 播放;時間尺依縮放自動換主刻度間距。音訊片段內畫波形,留言以釘子顯示在時間尺下方,hover 展開。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add "https://webberui.com/r/clip-timeline.json?t=<安裝 token>"

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

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

1
500
編輯中的呼叫預設屬性
<ClipTimeline/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

安裝

npx webberui@latest add "https://webberui.com/r/clip-timeline.json?t=<安裝 token>"

或在 components.json 設定 registries 後,改用 @webberui/clip-timeline 安裝。

使用

import * as React from "react";
import {
  ClipTimeline,
  type TimelineTrack,
} from "@/components/ui/clip-timeline";

const initialTracks: TimelineTrack[] = [
  {
    id: "video",
    name: "影片",
    clips: [
      { id: "v1", start: 0, duration: 5, label: "開場鏡頭", kind: "video" },
      { id: "v2", start: 5, duration: 8, label: "店內環景", kind: "video" },
    ],
  },
  {
    id: "audio",
    name: "音訊",
    clips: [{ id: "a1", start: 0, duration: 12, label: "背景音樂", kind: "audio" }],
  },
  {
    id: "subtitle",
    name: "字幕",
    clips: [{ id: "t1", start: 2, duration: 4, label: "歡迎光臨", kind: "text" }],
  },
];

export function Editor() {
  const [tracks, setTracks] = React.useState(initialTracks);
  const [time, setTime] = React.useState(0);

  return (
    <ClipTimeline
      tracks={tracks}
      onTracksChange={setTracks}
      duration={30}
      currentTime={time}
      onTimeChange={setTime}
      comments={[{ id: "c1", t: 6, text: "這裡轉場太快" }]}
    />
  );
}

Props

Prop型別預設值說明
tracksTimelineTrack[]—受控的軌道資料;未提供時為非受控
defaultTracksTimelineTrack[][]非受控模式的初始軌道資料
onTracksChange(tracks: TimelineTrack[]) => void—拖移、改長度、刪除、靜音或鎖定後回呼
durationnumber30專案總長度(秒)
currentTimenumber—受控的播放頭時間(秒)
defaultCurrentTimenumber0非受控模式的初始播放頭時間
onTimeChange(time: number) => void—播放頭時間變動時回呼(播放、拖曳、點時間尺)
playingboolean—受控的播放狀態
defaultPlayingbooleanfalse非受控模式的初始播放狀態
onPlayingChange(playing: boolean) => void—播放狀態切換時回呼
zoomnumber—受控的縮放倍率(0.25–4),每秒寬度為 80px × zoom
defaultZoomnumber1非受控模式的初始縮放倍率
onZoomChange(zoom: number) => void—縮放倍率變動時回呼
snapbooleantrue拖移時吸附到次刻度、其他片段邊緣與播放頭(6px 內)
commentsTimelineComment[][]釘在時間尺下方的留言
showCommentsbooleantrue是否顯示留言釘
loopbooleanfalse播放到結尾時是否從頭循環
heightnumber—時間軸區域最大高度(px);超出時垂直捲動,時間尺固定在頂部
bounceStiffnessnumber500同軌重疊被拒絕時回彈 spring 的 stiffness(damping 固定 35)
classNamestring—併入最外層容器

TimelineTrack

欄位型別預設值說明
idstring—軌道唯一識別碼
namestring—軌道名稱,也是該列的無障礙名稱
clipsTimelineClip[]—軌道上的片段
mutedbooleanfalse靜音(片段淡化顯示)
lockedbooleanfalse鎖定(片段不可拖移、改長度或刪除)

TimelineClip

欄位型別預設值說明
idstring—片段唯一識別碼
startnumber—起點(秒)
durationnumber—長度(秒),最小 0.2
labelstring—顯示名稱
kind"video" | "audio" | "text" | "image"—片段種類,決定配色與圖示
peaksnumber[]—音訊波形峰值(0–1);未提供時以 id 產生確定性的假波形

TimelineComment

欄位型別預設值說明
idstring—留言唯一識別碼
tnumber—留言所在時間點(秒)
textstring—留言內容
authorstring—留言者名稱

另外具名匯出 formatTimecode(mm:ss.f 格式化)與 ClipKind、ClipTimelineProps 型別。

細節

  • 時間尺換刻度:每秒寬度為 80px × zoom。主刻度間距從 0.1/0.5/1/2/5/10/30/60 秒裡挑「間距至少 64px」的最小者,次刻度為主刻度的五等分;主刻度小於 1 秒時標籤改為 mm:ss.f
  • 吸附:拖移或拉長時,移動中的邊緣若距離次刻度、其他片段邊緣、專案起訖或播放頭在 6px 內,就對齊過去;snap 設為 false 可關閉
  • 換軌:片段可上下拖到同種類(或空的)且未鎖定的軌道;軌道種類以第一個片段為準
  • 重疊拒絕:放開時若與目標軌的其他片段重疊,變更不會送出,片段以 spring(stiffness 可調、damping 35)回彈到原位,拖曳中會先以紅框提示
  • 播放:以 requestAnimationFrame 搭配 performance.now 差值推進時間,掉幀不影響進度;到結尾停止,或在 loop 時從頭開始。播放頭超出可視範圍時自動水平捲動跟隨
  • 配色:四種片段顏色走 --wb-ct-video、--wb-ct-audio、--wb-ct-text、--wb-ct-image 變數,預設是降低彩度的藍、綠、紫、琥珀;影片片段另有斜紋
  • 波形:音訊片段內以 SVG 長條畫波形,資料取自 peaks;沒有提供時由 id 的雜湊產生確定性假峰值,SSR 與 client 一致

可及性

  • 軌道區為 role="grid"(aria-label 為「時間軸」),每軌是 role="row" 並以軌名為 aria-label,片段是 role="gridcell",aria-label 例如「影片 開場鏡頭,00:00 起,長 5 秒」,選取狀態以 aria-selected 表示
  • 片段採 roving tabindex:Tab 只進入一個片段,↑/↓ 切換到相鄰軌道上時間最接近的片段;←/→ 微移選取片段 0.1 秒(Shift 為 1 秒),Alt + ←/→ 改長度,Delete 刪除,Enter 切換選取(IME 組字中的 Enter 會被忽略)
  • 空白鍵播放/暫停(焦點在輸入框或按鈕時不攔截),+/- 縮放
  • 播放頭把手為 role="slider",aria-valuetext 為時間碼,可用方向鍵(Shift 加大步幅)、Home、End 操作
  • 留言釘是按鈕,hover 或 focus 都會展開氣泡(role="tooltip"),點擊跳到該時間點;移動或刪除結果會透過 aria-live 區域朗讀
  • 使用者系統開啟「減少動態效果」時,重疊拒絕的片段直接回位不做 spring 回彈、留言氣泡只淡入不縮放、播放頭跟隨改為立即捲動