Liquid Glass in the Browser: Refraction with CSS and SVG
Жидкое стекло в браузере: преломление CSS и SVG
Apple показала «жидкое стекло» на WWDC 2025 — эффект, будто кнопки сделаны из изогнутого стекла. Повторим упрощённую версию: однократное преломление + блик. Работает пока только в Chrome (SVG-фильтр как backdrop-filter
).
Преломление за 15 сек
Закон Снеллиуса:
n₁ sin θ₁ = n₂ sin θ₂
- Воздух
n₁ = 1
, стеклоn₂ ≈ 1.5
- Падающий луч всегда перпендикулярен фону (упрощение)
- Учитываем только первое преломление, второе границы нет
Профиль стеклянной «линзы»
Поверхность задаётся функцией высоты h(x)
от края (x = 0
) до плоской середины (x = 1
). Нормаль = производная, повёрнутая на –90°.
Используемые профили:
Название | Формула | Особенность |
---|---|---|
Выпуклая окружность | h = √(1 − (1−x)²) |
резкий переход, заметные границы |
Выпуклый скругл-квадрат | h = ⁴√(1 − (1−x)⁴) |
плавный переход, тонкий ободок |
Вогнутая линза | h = 1 − convex(x) |
линза «внутрь» |
Алгоритм за 3 шага
-
Растровая карта высот
SVG-фильтрfeDisplacementMap
смещает пиксели фона пропорционально высоте. -
Координаты преломлённого луча
По нормали и закону Снеллиуса считаем угол выхода, переводим в смещениеΔu, Δv
. -
Блик
Белый градиент, умноженный на маску иmix-blend-mode: screen
.
Код-заготовка
.glass {
backdrop-filter: url(#disp); /* Chrome-only */
mask: url(#shape); /* форма скруглённого прямоугольника */
}
<filter id="disp">
<feImage href="heightmap.png" result="h"/>
<feDisplacementMap in="SourceGraphic" in2="h" scale="20"/>
</filter>
Живой пример
Демо-страница — тяните ползунок «Refractive index» и переключайте профиль. На слабых GPU снижайте scale
, чтобы не терять FPS.
Что дальше
- Поддержка Firefox/Safari: ждём
backdrop-filter: url()
или fallback на canvas - 3D-выход: добавить вторую границу, считать двойное преломление
- Произвольные формы: строить карту высот на лету через
Canvas2D