Communitygithub.com

roolzksd/droidglass

在任何平台上建構 Apple 風格的 Liquid Glass UI(iOS 26 / macOS 26 外觀)。支援 Web、Android WebView、Electron、Capacitor 與 Cordova,提供現成且經過測試的引擎,具備真實折射、光譜邊緣、融合水滴效果,以及 iOS 風格的彈性按鈕、切換開關、滑桿與標籤列。Jetpack Compose 使用 Kyant 的 Backdrop 函式庫;SwiftUI、UIKit 與 AppKit 則使用系統的 glassEffect。每當使用者要求 Liquid Glass、Apple 或 iOS 26 玻璃、玻璃態(glassmorphism)、磨砂玻璃、玻璃標籤列、玻璃按鈕、切換開關或滑桿,或要求「讓它看起來像 Apple」時(即使未明確說出 Liquid Glass),都可使用此技能。

droidglass 是什麼?

DroidGlass 是一款跨平台技能,讓開發者能在非 Apple 平台上重現 Apple iOS 26 與 macOS 26 的 Liquid Glass 使用者介面。它不僅僅是簡單的毛玻璃效果(glassmorphism),而是透過折射、光譜邊緣、高光線條與按壓彈性動畫,模擬真實液體玻璃的視覺與互動特性。此技能針對不同平台提供專屬實作方式:在 SwiftUI、UIKit 與 AppKit 上直接使用 Apple 系統 API;在 Jetpack Compose 上推薦使用 Kyant 的 Backdrop 函式庫;在 Web 環境(包括 Electron、Android WebView、Capacitor、Cordova)則提供自訂的 `assets/` 引擎,內含 JavaScript、CSS 與 UI 元件。技能核心嚴格遵循 Apple 人機介面指南,強調玻璃僅用於導航與控制層、透明為主、僅在必要時加入表面材質、並使用彈簧動畫而非線性過渡。開發者需根據平台選擇正確的參考文件,並使用提供的配方表(如按鈕、切換開關、滑桿、標籤列等)設定參數,最後須通過詳盡的檢查清單(包括靜態、按壓、拖曳、深色模式、回退機制等)驗證,確保效果正確。此技能非常適合需要為 Web、Android 或跨平台應用程式添加高品質 Apple 風格 Liquid Glass 介面的開發者。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/roolzksd/DroidGlass/tree/HEAD

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

DroidGlass:適用於任何平台的 Liquid Glass

Liquid Glass 是 Apple 的一種材質,能夠折射其下方的內容。在邊緣附近,背景會像厚透鏡一樣向中心拉動,邊緣會出現柔和的彩虹色,一條極細的高光線沿著邊緣運行,觸碰時玻璃會膨脹、向手指方向拉伸,然後彈回。普通的玻璃態(glassmorphism)只會在白色薄霧下模糊背景,因此看起來廉價且無光澤。

品味的主要規則:**玻璃是透明的。**如果你無法閱讀其後方的內容,那就是 iOS 7 的磨砂玻璃,而不是 Liquid Glass。僅在文字位於玻璃之上時才添加模糊和表面效果。

誠實告知使用者限制所在。真正的材質僅存在於 iOS、iPadOS 和 macOS 26 及更新版本;其他一切皆為模仿。在 Android 上,Backdrop 提供了完整的模仿(透鏡效果需要 Android 13)。在 Web 上,折射僅在 Chromium(Chrome、Edge、Samsung Internet、Android WebView、Electron)中有效。Safari、Firefox 以及 iOS 上的所有瀏覽器會獲得帶有相同高光、陰影和彈簧效果的輕微模糊,但沒有彎曲效果。

工作流程

  1. 識別平台。
    • SwiftUI、UIKit、AppKit、WidgetKit(iOS/macOS 26):系統 API,請參閱 references/apple.md。不要模仿任何東西。
    • Jetpack Compose 或 Compose Multiplatform:references/android-compose.md。不要從頭編寫著色器,使用函式庫。
    • Web、Electron、Android WebView、Capacitor、Cordova、Tauri(Windows/Android):位於 assets/ 的引擎,請參閱 references/web.md。在 WebView 和 Electron 中,折射始終有效。
    • React Native、Flutter:沒有系統等效方案。對於 React Native,建議使用 WebView 層或基於 Backdrop 的原生模組;對於 Flutter,使用 BackdropFilter 作為回退方案,並使用包含 references/math-and-motion.md 中公式的 FragmentProgram。自行檢查當前套件,此技能不列出它們。
  2. 選擇控制層的 1 到 3 個元素: 標籤列、浮動按鈕、頂部欄、表單、選單、切換開關或滑桿的拇指(觸碰時)。不要讓內容變成玻璃。
  3. 從下表選擇一個配方。 不要發明參數:這些數值來自 Kyant 的目錄並已在螢幕上驗證過。
  4. 檢查玻璃下方的背景。 玻璃僅在豐富的內容上可見:照片、顏色、圖表、滾動時的文字。在純白頁面上,透明玻璃幾乎會消失:在其後方放置顏色、添加一個遮罩層,或者移除玻璃。
  5. 根據正確的參考文件建構,並使用最後的檢查清單親眼驗證。沒有提供靜止、按壓和拖曳狀態的螢幕截圖之前,不要提交。

Apple 的規則

來自人機介面指南、WWDC25「Meet Liquid Glass」以及流行的社群技能。違反任何一條都會立即暴露其偽造性質。

  • 僅用於浮動於內容之上的導航和控制層。 列表、行、卡片和頁面背景並非玻璃。例外:切換開關和滑桿的拇指在觸碰時會變成玻璃。
  • 玻璃上不疊玻璃。 位於玻璃之上的元素透過填充和不透明度來區分。Backdrop 的例外:在玻璃表單上的滑桿拇指會折射該表單(exportedBackdrop):一個透鏡疊在另一個之上,而不是兩個霧面平板。
  • 少量使用。 僅用於最重要的控制項。
  • 玻璃是無色的。 顏色和亮度來自背景:亮色背景上為亮色,暗色背景上為暗色,高光線條會根據背景色調進行著色。沒有自身的白色或灰色表面。
  • 兩種模式,不要混用。 清晰模式(按鈕、拇指、放大鏡、與按鈕分組的標籤列):模糊度 0 到 4,無表面。常規模式(包含長文字的表單、對話框):模糊度 8 到 16;僅在文字在沒有表面時無法閱讀時,才添加 40% 到 60% 的表面效果。
  • 僅對主要操作進行著色。
  • 形狀。 膠囊形:半徑等於高度的一半。同心圓角:內圓角半徑等於容器半徑減去內邊距。
  • 越大表示越厚: 較大的元素會獲得較寬的彎曲邊緣和較深的折射。
  • 永遠不要讓內容一半留在玻璃下方。
  • 液體運動。 按下時,玻璃會增長幾個像素,並以阻尼效果向手指方向傾斜;拇指會放大 1.5 倍,並以速度拉伸成水滴狀。所有動畫都使用彈簧效果,沒有線性過渡。

配方(數值來自 Kyant 的目錄)

元素效果高光與陰影觸碰
按鈕,48 dp 膠囊形活力感,模糊 2,透鏡(12, 24)預設,預設陰影發光;高度增加 4 dp;偏移量 min × tanh(0.05 × offset / min);向手指方向拉伸最多 4 dp
著色按鈕同上 + 著色同上同上
帶表面按鈕同上 + 白色 30%同上同上
切換開關拇指 40×24,軌道 64×28靜止時:白色 100%,模糊 8;按下時(p):模糊 8(1−p),透鏡(5p, 10p, 色散),白色 (1−p)環境光,寬度 /1.5,透明度 p;陰影半徑 4,5%;內部陰影半徑 4p,透明度 p縮放到 1.5;軌道透過透鏡可見,縮小到 0.75
滑桿拇指 40×24,軌道 6 dp類似切換開關,透鏡(10p, 14p)類似切換開關縮放到 1.5;點擊軌道會跳轉到該點
標籤列 64 dp活力感,模糊 8,透鏡(24, 24),表面 #FAFAFA 40%(深色主題 #121212 40%)預設按下時,整個面板寬度增加 16 dp(標籤隨之增加),並在手指之後最多傾斜 4 dp
隱藏行副本 56 dp(tabsBackdrop)相同面板使用強調色,alpha(0):活力感,模糊 8,透鏡(24p, 24p),面板表面預設透明度 p,InteractiveHighlight按下時圖標和標籤 ×1.2(LocalLiquidBottomTabScale 僅在此行設定)
標籤列拇指 56 dp靜止時:灰色 10%;按下時:透鏡(10p, 14p, 色散) 作用於背景和行副本(rememberCombinedBackdrop(backdrop, tabsBackdrop))預設,陰影和內部陰影 8p 透明度 p縮放 78/56;水滴內部有一個「欄中欄」:其自身項目為強調色並放大,邊緣可見相鄰項目
對話框,半徑 48亮度 0.2(亮色主題),飽和度 1.5,模糊 16(深色主題 8),透鏡(24, 48, 深度)平面使背景變暗 #29293A 23%(深色主題 #121212 56%)
控制中心磁貼活力感,透鏡(24, 48, 深度)預設,角度來自裝置傾斜,衰減 2進入時:48 dp 偏移和透明度
放大鏡 128×96透鏡(8, 24, 深度, 色散),背景縮放 1.5 倍內部陰影 16拖曳

彈簧、手勢以及每個平台共享的數學原理位於 references/math-and-motion.md。

一分鐘搞定 Web 與 Android WebView

將 assets/ 中的三個檔案原封不動地複製到專案中,並使用選項進行設定。不要重寫引擎。

<link rel="stylesheet" href="liquid-glass.css">
<button id="buy">購買</button>
<div id="wifi" aria-label="Wi-Fi"></div>
<div id="volume" style="width: 280px"></div>
<nav id="tabs" style="position: fixed; left: 16px; right: 16px; bottom: 16px"></nav>
<script src="liquid-glass.js"></script>
<script src="liquid-ui.js"></script>
<script>
  LiquidUI.button(document.getElementById('buy'), { tint: '#0088FF', onClick: () => {} });
  LiquidUI.toggle(document.getElementById('wifi'), { checked: true, onChange: (on) => {} });
  LiquidUI.slider(document.getElementById('volume'), { value: 0.4, onInput: (v) => {}, label: '音量' });
  const tabs = LiquidUI.tabs(document.getElementById('tabs'), {
    items: [{ label: '首頁', icon: '<svg>…</svg>' }, { label: '搜尋', icon: '<svg>…</svg>' }],
    index: 0, onChange: (i) => {},
  });
  // 融合:一個工具列和一個相鄰的按鈕會融合成一個水滴;相鄰的彈性按鈕會自動融合
  // LiquidUI.blob([tabs.panel, fab], { blur: 3.5 }); LiquidUI.autoMerge(document.body); 螢幕切換後執行 LiquidUI.sweep()
  // 為您自己的標記使用裸玻璃
  const g = LiquidGlass.attach(document.getElementById('panel'), { radius: 28, blur: 8, refractionHeight: 24, refractionAmount: 24, surface: 'rgb(250 250 250 / .4)' });
  // g.set({ lens: 0..1, blur, surface, highlightAlpha, angle, shadowAlpha, innerShadow, press: { p, x, y }, tx, ty, sx, sy, sleep })
</script>
檔案說明
assets/liquid-glass.js玻璃引擎:折射貼圖、色散、高光、陰影、融合群組(LiquidGlass)
assets/liquid-glass.css基礎樣式、無障礙回退、組件樣式
assets/liquid-ui.js彈簧、手勢和元件:按鈕、切換開關、滑桿、標籤列、放大鏡、blob、autoMerge(LiquidUI)
assets/demo.html所有元件集中在一個頁面;打開它以查看正確效果

在進行任何更改或將其接入應用程式之前,請先閱讀 references/web.md:它列出了幾乎會破壞所有實作的 Chromium 相關知識(背景根元素、position: fixed、touch-action、body 背景)以及所有選項。當某些東西看起來不對勁時,請查閱 references/troubleshooting.md;當有任何卡頓問題時,請查閱 references/performance.md。

Web 上五個絕對不能搞錯的事項:

  • 背景必須是真實的元素。設定在 body 上並傳播到根元素的背景不會被 backdrop-filter 偵測到。
  • 永遠不要在玻璃的上層元素上對 opacity、filter、mask 或 clip-path 進行動畫處理(例如螢幕淡入):這會使它成為一個背景根元素,導致玻璃失去其背景並變暗。使用 transform 移動螢幕,並使用上層的遮罩層來顯示它們。
  • 不要在玻璃元素上設定自己的 transform;請將基礎偏移量寫入 --lg-base。
  • 彈性按鈕需要 touch-action: none(預設值)。使用 pan-y 時,瀏覽器會劫持拖曳並發送 pointercancel。
  • 在 Android WebView 中,停用長按和觸覺回饋:setOnLongClickListener(v -> true) 和 setHapticFeedbackEnabled(false)。

無障礙與易讀性

  • Web 引擎會遵從 prefers-reduced-transparency: reduce(關閉玻璃效果,使用近乎不透明的表面;Chrome 和 Edge 119+,Safari 或 Firefox 尚不支援)、prefers-contrast: more(實心表面和邊框)以及 prefers-reduced-motion(彈簧效果變成即時完成)。
  • 元件會獲得角色和鍵盤支援:按鈕(Enter, Space)、switch(Enter, Space)、slider(方向鍵)、tablist(左、右方向鍵)。使用 aria-label 或 aria-labelledby 為它們添加標籤。
  • 在 Android 上,如 Kyant 的目錄所述,設定 semantics { role = Role.Switch } 和標籤;在舊版 Android 上,檢查 onDrawSurface 顏色在沒有效果的情況下是否可讀。
  • 檢查文字與最終可能位於面板下方的最亮、最雜亂的內容之間的對比度:主體文字需達到 4.5:1。如果失敗,請增加模糊和表面效果,或移動內容。文字陰影無法解決此問題。

禁止事項

  • 在按鈕上使用白色半透明表面加上 blur(10px):那是磨砂玻璃,不是 Liquid Glass。只有包含文字的標籤列、表單和對話框可以適度使用表面密度。
  • 玻璃內容卡片和玻璃頁面背景。
  • 在大面板上使用色散效果:成本高且俗豔。
  • 使用粗白色邊框代替極細高光線。
  • 每個按鈕使用相同的著色。
  • 使用線性 transition 代替彈簧效果來處理按下和拖曳。
  • 在 Web 上對玻璃的 width 和 height 進行動畫處理:每幀都會重建貼圖。請對 scale 進行動畫處理。
  • 在結果需要多個步驟讀取的情況下使用重濾鏡步驟(模糊、位移、卷積、形態學):Chrome 會為每個分支計算一次,導致手機卡死。
  • 「為了美觀」而使用自己的表面繪製玻璃。只有包含文字的密集面板才能獲得表面效果。
  • 在 Backdrop 適用時編寫自己的 Compose 著色器。
  • 在 Apple 平台之外使用 SF Symbols 和 Apple 標誌:它們的授權禁止這樣做。請使用開源圖標集。
  • 將 Web 或 Android 的結果稱為「官方 Liquid Glass」。它是風格上的模仿。

提交前的檢查清單

在 2 倍縮放下檢視螢幕截圖,並親自檢查:

  1. 在網格或文字上的靜止狀態: 線條可透過透明玻璃看到,在邊緣處向中心拉動,高光線條很細。在白色背景上,玻璃透過邊緣陰影和陰影與頁面區分開來;在深色背景上,透過亮面的一條亮線區分。
  2. 按下: 按鈕增大並向手指方向傾斜;拇指膨脹且透明,軌道可透過它看到,彩虹柔和,沒有彩色空洞。
  3. 拖曳: 拇指以速度拉伸,只有在到達後才縮小;標籤列傾斜並返回。邊緣標籤和靠近螢幕底部邊緣的標籤列水滴:其自身項目在內部,邊緣有相鄰項目,無黑色區域、條帶或鏡像碎片。
  4. 拉動: 按鈕像橡皮筋一樣跟隨手指並反彈回來;一個工具列向相鄰按鈕拉動時會與之融合,橋樑隨著它們靠近而增長,沒有接縫或雙重邊緣;在靜止和簡單按下時它們保持分離;正常點擊有效,將按鈕拉遠後鬆開不會觸發。
  5. 在照片上和白色背景上: 玻璃下的色彩豐富,文字可讀。
  6. 深色主題。
  7. 回退機制: 偽造引擎(Safari 使用者代理和空的 navigator.userAgentData),檢查元素是否沒有變成空洞,以及標籤列拇指下的圖標是否沒有模糊。
  8. 調整大小和旋轉: 貼圖被重建,邊緣沒有階梯狀瑕疵。
  9. 螢幕切換: 在螢幕進入時捕獲多個連續幀;玻璃按鈕絕不會比靜止時更暗,合併層在動畫後精確地位於其按鈕下方。
  10. 無控制台錯誤且無卡死:在一連串點擊後,頁面回應速度依然很快。一個動畫循環,沒有多餘的 requestAnimationFrame。
  11. 手機螢幕上不超過 3 個大型玻璃元素,沒有玻璃疊玻璃,沒有玻璃內容。

如果某項失敗,請先修復,然後再向使用者展示。

來源

  • Kyant0/AndroidLiquidGlass, Backdrop library and catalog (Apache-2.0):透鏡、色散、高光和陰影公式、元件配方、彈簧和手勢常數。Web 引擎是此方案的移植。
  • Apple:人機介面指南「材質」、「採用 Liquid Glass」、WWDC25「Meet Liquid Glass」。
  • kube.io,「瀏覽器中的 Liquid Glass」:透過 backdrop-filter 內部的 feDisplacementMap 實現折射。
  • iyinchao/liquid-glass-studio (MIT):透過 smin 融合形狀、Snell 折射、具有高對比玻璃的無色玻璃。

相關技能