媒體

3D 裝置舞台

純 CSS 3D 手機/平板/筆電舞台,五種編排:游標傾斜、捲動環繞、Y 軸翻轉、三台扇形陣列、捲動微距拉回;螢幕是真 DOM。

這是 WebberUI Pro 元件

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

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

產品頁最常見的一幕:把 App 畫面裝進一台手機或筆電,讓它在頁面上動起來。這個元件的手機、平板、筆電外框全部用 CSS 畫成(圓角、邊框、動態島、側鍵、鍵盤底座),沒有任何圖片;螢幕裡放的是真 DOM,文字可選取、按鈕可點、螢幕閱讀器讀得到。五種編排可切換:游標傾斜、捲動環繞、Y 軸翻轉(背面可放第二個畫面或畫出背殼)、三台扇形陣列,以及捲動時從微距特寫拉回全景。

把這個效果裝進你的專案

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

npx webberui@latest add "https://webberui.com/r/device-stage-3d.json?t=<安裝 token>"

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

Playground

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

8
3
1400
120
編輯中的呼叫預設屬性
<DeviceStage3D/>

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

安裝

npx webberui@latest add "https://webberui.com/r/device-stage-3d.json?t=<安裝 token>"

或在 components.json 設定 registries 後,改用 @webberui/device-stage-3d 安裝。

使用

import { DeviceStage3D } from "@/components/ui/device-stage-3d";

<DeviceStage3D
  device="phone"
  mode="flip"
  screens={[<HomeScreen key="home" />, <SettingsScreen key="settings" />]}
  caption={<p>點擊手機看設定頁</p>}
  maxTilt={8}
/>;

orbit 與 macro 由捲動驅動;舞台放在可捲動的區塊裡時,把該區塊的 ref 傳給 container:

const scrollerRef = React.useRef<HTMLDivElement>(null);

<div ref={scrollerRef} className="h-[480px] overflow-y-auto">
  <div className="h-[320px]" />
  <DeviceStage3D mode="macro" container={scrollerRef} screens={[<HomeScreen key="home" />]} />
  <div className="h-[320px]" />
</div>;

Props

Prop型別預設值說明
screensReact.ReactNode[]—螢幕內容(1–3 個);flip 背面用第 2 個,lineup 依序填入三台、不足則重複
device"phone" | "tablet" | "laptop""phone"裝置外型
mode"tilt" | "orbit" | "flip" | "lineup" | "macro""tilt"編排模式
captionReact.ReactNode—側邊說明欄;flip 模式每次翻面都會延遲 120ms 重新滑入
flippedboolean—受控的翻面狀態
defaultFlippedbooleanfalse非受控模式的初始翻面狀態
onFlippedChange(flipped: boolean) => void—翻面狀態改變時回呼
clickToFlipbooleantrueflip 模式下點擊裝置即可翻面,並提供鍵盤用的翻面按鈕
perspectivenumber1400舞台透視距離(px)
maxTiltnumber8tilt 模式的最大傾斜角(度)
depthBlurnumber3macro 模式非聚焦層的起始模糊(px),建議 2–4
flipStiffnessnumber120翻面彈簧的 stiffness(damping 固定 20)
gyrobooleanfalse觸控裝置改用陀螺儀驅動 tilt
containerReact.RefObject<HTMLElement | null>—orbit/macro 捲動進度依據的捲動容器;未提供時以視窗為準
screenClassNamestring—透傳到每個螢幕區塊
classNamestring—透傳到最外層容器

另外具名匯出 DeviceStage3DDevice、DeviceStage3DMode 與 DeviceStage3DProps 型別。

CSS 變數

欄位型別預設值說明
--wb-ds3d-framecolor#171717(深色模式 #262626)外框與側鍵顏色
--wb-ds3d-highlightcolorrgba(255,255,255,0.14)外框 1px 內高光
--wb-ds3d-backcolor#e5e5e5(深色模式 #525252)背殼漸層起始色
--wb-ds3d-deckcolor#d4d4d4(深色模式 #404040)筆電鍵盤底座顏色
--wb-ds3d-glowcolorrgba(115,115,115,0.16)舞台背景柔光

細節

  • tilt:游標相對舞台中心換算成 −1 到 1,映射成 rotateY ±maxTilt、rotateX ∓maxTilt,經 stiffness 150/damping 18 的彈簧平滑,離開舞台回正。觸控裝置(pointer: coarse)預設不跟隨;開啟 gyro 後改讀 deviceorientation,iOS 會在使用者第一次觸控後請求權限
  • orbit:捲動進度 0 到 1 映射 rotateY −30° 到 30°,translateZ 在中段推到 40px 最靠前
  • flip:rotateY 0 到 180°,正面 screens[0]、背面 screens[1];只有一個畫面時背面畫成背殼(鏡頭模組與霧面)。點到螢幕裡的按鈕、連結時不會翻面
  • lineup:三台扇形排開,左右兩台往內轉 18°、往外移 60%、退後 80px、縮到 0.9;進入視口時每台間隔 0.12 秒從下方彈上來
  • macro:捲動到舞台中心對齊視窗中心的過程中,整組從 1.6 倍拉回 1 倍、位移 12% 歸零;背景裝飾與側機(screens 多於一個時)從 depthBlur 模糊到清晰
  • 筆電開蓋:螢幕面板以底邊為軸從 −90° 打開;一般模式在進入視口時以彈簧開蓋,orbit/macro 改綁捲動前 30%

可及性

  • 最外層為 role="group",aria-roledescription="裝置展示";外框、側鍵、鏡頭、鍵盤等裝飾都是 aria-hidden,螢幕內容保持可讀、可聚焦
  • flip 模式提供一顆鍵盤用的翻面按鈕(aria-pressed 表示是否顯示背面),平常隱藏、Tab 聚焦時浮現,可用 Enter/空白鍵觸發;沒朝向使用者的那一面會設為 inert,不會被 Tab 到
  • macro 的側機只是裝飾,設為 aria-hidden 與 inert
  • 使用者系統開啟「減少動態效果」時,所有模式固定正面、不跟隨游標與捲動,lineup 直接到位,筆電直接開蓋,flip 改為兩面原地交叉淡接