Мыльные пузыри на SVG
Честно говоря, пузыри у меня получились почти случайно, когда мне потребовалось как следует изучить градиенты и я экспериментировала с их возможностями. И я сама до сих пор не очень понимаю, как так получилось, используя только SVG — векторный формат, — сделать такой невесомый мыльный пузырь.
See the Pen SVG Bubbles by yoksel (@yoksel) on CodePen.
На самом деле, если разобраться, тут нет ничего сложного, а вся магия заключается в использовании масок в сочетании с градиентами.
Подробно про устройство SVG-масок можно почитать здесь, а про градиенты — вот здесь.
Разберём пузырь на слои (от нижнего слоя к верхнему):
Пузырь состоит из пяти слоёв, каждый из которых является фигурой c градиентом, некоторые из них — ещё и с масками (внутри которых тоже градиенты).
Важно: всё содержимое пузыря находится внутри тега svg
:
Также обратите внимание на обязательный атрибут viewBox
: он нужен затем, чтобы при изменении размеров изображения внутренняя система координат ресайзилась вместе с ним, и элементы не расползались кто куда, а оставались на своих местах. Особенно это важно для координат, которые не могут быть заданы в процентах.
В примерах тег svg
будет опущен, но не забудьте его добавить, если будете использовать примеры кода из статьи.
Разноцветный слой
Начнём с самого главного (и самого верхнего) слоя, он имитирует поверхность пузыря с радужными разводами:
По сути, к фигуре применены два градиента, один из них внутри маски. Эта конструкция позволяет получить фигуру с линейным градиентом и с радиальной прозрачностью одновременно.
Как сделать:
-
Создаём фигуру с разноцветным градиентом
Пишем градиент:
Применяем его к фигуре:
Получается разноцветная основа, которой не хватает лёгкости и прозрачности.
-
Добавляем прозрачность
Для этого воспользуемся радиальным градиентом с черными и белыми оттенками разной степени прозрачности (значения подбирались опытным путём):
Чтобы прозрачность выглядела более естественно, нужно немного сместить центр градиента, для этого воспользуемся атрибутами
fx
иfy
:Вот что получилось:
Теперь делаем маску. В
mask
кладётся прямоугольник, в качестве заливки используется свежесозданный градиент:Затем добавляем маску к фигуре с разноцветной заливкой:
Результат:
Весь код разноцветного слоя:
Получилась полупрозрачная радужная поверхность, пока ещё не очень похожая на мыльный пузырь.
Погуглив картинки по запросу soap bubble, я подумала, что пузырю можно добавить внутренние отражения вверху и внизу.
Отражения
В качестве отражений я использовала две фигуры с однотонной заливкой и маской, добавляющей фигурам прозрачность.
Прозрачность сделана маской, хотя, теоретически, можно было бы обойтись одними градиентами. Но мне хотелось, чтобы отражения были одинаковыми, а кроме того, использование в маске только белого и чёрного цветов позволяет получить более управляемые градиенты.
Как сделать:
-
Создаём фигуры с однотонной заливкой
-
Добавляем прозрачность с помощью масок
В этом градиенте так же используются белый и чёрный разной степени прозрачности, а центральный цвет сдвинут вверх с помощью атрибута
fy
:Используя этот градиент, создадим две маски: для верхнего отражения и для нижнего. В маске для верхнего отражения используется тот же градиент, но прямоугольник с градиентом перевёрнут кверх ногами.
Добавляем маски к фигурам с заливкой:
Результат:
Весь код слоя с отражениями:
Объединим слои. Отражения внутренние, поэтому слои с ними располагаются под разноцветным слоем:
Пузырь стал более многоцветным, но сейчас его поверхность выглядит матовой. Чтобы сделать её блестящей, нужно добавить блики.
Блики
Они сделаны двумя эллипсами с градиентной заливкой:
Контурная обводка показывает границы пузыря.
Как сделать:
-
Создаём градиент
Он состоит из оттенков белого разной степени прозрачности, центральный цвет сдвинут к верхнему краю:
-
Рисуем эллипсы
Один располагаем вверху слева, другой — внизу справа, добавляем градиентную заливку:
Так как радиальный градиент применили к эллипсам, он сплющился, чтобы уместиться в фигуре целиком.
-
Добавляем трансформации
Чтобы блики визуально находились на поверхности пузыря, их надо немного повернуть:
Результат:
Весь код слоя с бликами:
Финальная сборка
Теперь можно собрать весь код в финальную версию. В примерах я объединяла в группы разные компоненты одного слоя, но если теперь просто свалить весь код в одну кучу, во-первых, получится неверная последовательность слоёв, а во-вторых, таким кодом будет просто неудобно пользоваться.
При этом код содержит два типа элементов, и можно удобно сгруппировать элементы по типу. Первый тип — это простые фигуры (в нашем случае — круги и эллипсы), именно они являются видимыми слоями, из которых в итоге получается пузырь. Второй тип — это элементы, которые не отображаются на странице, но влияют на внешний вид отображаемых фигур: это маски и градиенты.
Неотображаемые элементы будет удобно положить в defs
— это такой элемент, специально предназначенный для хранения переиспользуемых штук. Ни сам элемент, ни его содержимое не отображаются на странице.
Отображаемые элементы следует расположить после defs
. При этом нужно обратить внимание на порядок слоёв и помнить, что чем ниже слой в коде, тем ближе он к зрителю, то есть самым первым к коде должен быть нижний блик, а самым верхним — слой с разноцветным градиентом.
Примерный код (маски и градиенты опущены, полный код есть ниже):
И весь пузырь целиком:
See the Pen grEWZw by yoksel (@yoksel) on CodePen.
Обратите внимание, что белые блики выглядят цветными. Так как нижний блик как бы отражается от внутренней поверхности пузыря, и относительно зрителя расположен на самой дальней его стенке, в слоях он находится глубже всех, в самом низу (и первым в коде).
Верхний же блик предполагается на внешней стенке пузыря, ближайшей к зрителю, но чтобы и его тоже немного привести в соответствие по цветам, он был размещён не самым верхним слоем, а под слоем с радужными разводами.
Заключение
Используя сочетание масок и градиентов можно сделать векторный мыльный пузырь. Преимущество вектора перед растром состоит в том, что его можно сколько угодно растягивать и сжимать без потери качества, а кроме того, цвета такого пузыря можно анимировать.
Я думаю, что это не самое точное изображение мыльного пузыря, но фотореализм и не был моей целью — мне хотелось узнать насколько сложными могут быть градиенты и какую пользу можно извлечь из сочетания градиентов и масок. Результаты впечатляют, и я уверена, что используя вышеописанные способы, разработчики с богатой фантазией могут сделать много интересного.
Также, если у вас на примете есть интересные демо с использованием SVG-градиентов, поделитесь ссылками в комментариях.