Hacker News Digest

08 сентября 2025 г. в 21:32 • kube.io • ⭐ 449 • 💬 111

OriginalHN

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 шага

  1. Растровая карта высот
    SVG-фильтр feDisplacementMap смещает пиксели фона пропорционально высоте.

  2. Координаты преломлённого луча
    По нормали и закону Снеллиуса считаем угол выхода, переводим в смещение Δu, Δv.

  3. Блик
    Белый градиент, умноженный на маску и 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