Мне всегда нравились UI-эффекты, которые не просто красивы, а ещё и физически обоснованы. Недавно наткнулся на Meniscus — React-библиотеку, которая рисует стеклянные поверхности с преломлением контента за ними по закону Снеллиуса. Не размытие и светлая кайма, а реальное bending содержимого под стеклом с учётом угла падения света и индекса преломления.
Это не «еще один blur-фильтр», а попытка сделать glassmorphism с настоящей оптикой на фронте. В статье разберу, как это реализовано, какие ограничения и где Meniscus реально полезен.
Преломление вместо размытия: почему это важно
Большинство эффектов стекла на вебе — это размытие фона (backdrop-filter: blur) плюс светлая кайма. Вроде бы неплохо, но визуально это больше похоже на мутное стекло, чем на реально искривляющую свет поверхность. Особенно если хочешь сделать что-то вроде линзы или выпуклого стекла, где картинка за ней искажается.
Meniscus идёт дальше и вычисляет, как преломляются лучи света через «стекло» с некоторой толщиной и кривизной, используя закон Снеллиуса (Snell’s law). В итоге содержимое за компонентом как бы искривляется — это по-настоящему «жидкое стекло».
На практике это выглядит органично, особенно в интерфейсах с 3D-эффектами, интерактивными линзами — например, чтобы выделять часть страницы искажающимся «луповым» эффектом.
Как устроен Meniscus: кратко по коду
Основной компонент — <Glass> из пакета meniscus. В простом случае выглядит так:
import { Glass } from 'meniscus';
<Glass radius="capsule" interactive>
<button>Search</button>
</Glass>
radius задаёт форму рамки (capsule — овальная), а interactive позволяет взаимодействовать с вложенным элементом. Внутри можно рендерить кнопки, табы, формы — библиотека поддерживает нативные controls и кастомные UI-элементы.
За визуал отвечает WebGL-шейдер, который:
- вычисляет высоту «бортов» стекла (bezel height profile);
- трассирует лучи через стекло с учётом индекса преломления (refractive index);
- смещает пиксели фона за стеклом по результатам преломления.
В демо можно менять профиль линзы, угол падения света, индекс преломления, накладывать слои с текстом или видео — всё живо реагирует.
Поддержка браузеров и fallback
Meniscus честно заявляет, что пока полноценное преломление работает только в Chromium-подобных браузерах (Chrome, Edge). Там WebGL и современные API позволяют делать real-time преломление живого DOM-содержимого.
Safari и Firefox пока не могут так же свободно работать с DOM за стеклом, поэтому для них есть fallback:
- простой frosted glass (blur + полупрозрачный слой);
- либо WebGL-преломление, если фон — картинка, видео или canvas.
Это сделано через SSR: при серверном рендере компонент показывает frosted glass, а после гидратации в браузере переключается на сложный вариант, если браузер поддерживает. При этом стили импортировать не нужно — всё self-contained.
Такой подход честен и полезен, т.к. не ломает UX в неподдерживаемых браузерах, но и не теряет эффекта там, где можно.
Где Meniscus круче привычных решений
- Интерактивные линзы и искажения: если хочется сделать, например, увеличительное стекло на странице, Meniscus даёт не просто зум, а реалистичное преломление с искажением пикселей по физике.
- Сложные UI с несколькими слоями: библиотека умеет работать с разными слоями контента, даже с видео и canvas, что редко встречается в подобных решениях.
- Нативные формы и кнопки: не нужно выдумывать кастомные контролы, можно просто обернуть существующий UI.
- Отличный playground: можно менять параметры преломления, профиля линзы, угла света — быстро увидеть, как это влияет.
Ограничения и подводные камни
- Производительность: WebGL-шейдеры и realtime ray-tracing — не самые дешёвые операции. На слабых устройствах или при сложных сценах может подтормаживать.
- Браузерная совместимость: пока только Chromium умеет преломлять живой DOM. Safari и Firefox — fallback, а это значит, что эффект будет разным у пользователей.
- SEO и SSR: frosted glass при SSR — норм, но если для вас критичен именно эффект преломления, то на первой загрузке его не будет.
- API ещё молодой: разработчик просит фидбек по API. Пока это не библиотека уровня MUI или Chakra, стоит готовиться к возможным breaking changes.
- Сложность кастомизации: если нужно сильно менять поведение преломления или добавить свои шейдеры — придётся копать исходники.
Пример: интерактивная линза с изменяемым индексом преломления
Я попробовал сделать на базе Meniscus простую линзу, которая меняет коэффициент преломления при наведении мыши — чтобы визуально выделять часть страницы.
import React, { useState } from 'react';
import { Glass } from 'meniscus';
export default function InteractiveLens() {
const [refrIndex, setRefrIndex] = useState(1.5);
return (
<Glass
radius="capsule"
interactive
indexOfRefraction={refrIndex}
style={{ width: 200, height: 100 }}
onMouseEnter={() => setRefrIndex(2)}
onMouseLeave={() => setRefrIndex(1.5)}
>
<button>Search</button>
</Glass>
);
}
Такое поведение даёт subtle, но заметный эффект усиления искажения. При этом кнопка остаётся интерактивной.
Итоги и рекомендации
Meniscus — отличный эксперимент для тех, кто хочет вывести UI-эффекты стекла на новый уровень, с реальной физикой преломления. Это не просто красивый фильтр, а попытка сделать glassmorphism с оптической точностью.
Кому стоит попробовать:
- фронтендерам, работающим с интерактивными визуализациями, дашбордами, где нужны сложные эффекты с прозрачностью;
- тем, кто хочет изучить WebGL и шейдеры через готовый React-компонент;
- интерфейсным разработчикам, стремящимся к «vibe coding» — создавать UI, которые не только выглядят круто, но и ощущаются живыми.
Где осторожнее:
- если проект должен работать одинаково во всех браузерах — придётся иметь ввиду фолбэки и возможно отказаться от эффекта;
- на слабых устройствах — проверяйте производительность;
- если нужно просто простое размытие — Meniscus может быть overkill.
Дальше можно поиграться с параметрами линзы, попробовать интегрировать с агентами (agentic workflows) для динамического управления эффектами, или комбинировать с RAG-стратегиями, где визуальный feedback помогает в работе с AI.
Ссылки:
Если любите прокачивать UI с помощью реальных физических моделей — Meniscus стоит в списке экспериментов. Но не ждите, что он заменит привычные blur-эффекты на всех устройствах прямо сейчас.
Попробуй сам: Cursor — AI-редактор для разработчиков.
Источник: https://www.reddit.com/r/reactjs/comments/1wouf7j/meniscus_react_glass_that_refracts_the_page_using/