Три способа создания клякс с помощью CSS и SVG

от автора

Кляксы (Blob) — это гладкие, аморфные, желеобразные формы, обычно  причудливые и забавные. Их можно использовать в качестве элементов иллюстраций и фоновых эффектов в сети.

Итак, как же они устроены? Разумеется, можно открыть какой-то графический редактор и сделайте их, верно? Конечно, это круто. Но мы пишем здесь о CSS финтах, и было бы гораздо интереснее посмотреть на возможности, которые нам дают CSS и SVG — двух наших любимых ингредиентов!

У нас есть несколько способов сделать кляксы. Давай проверим их.

Рисуем круги в SVG

Начнем с чего-то простенького. Мы можем рисовать SVG в чем-то вроде Illustrator, Sketch, Figma или чем-то ещё, но вместо этого мы будем программировать SVG.

<circle cx="100" cy="100" r="40" fill="red" />

SVG делает рисование круга довольно тривиальным благодаря элементу <circle> с соответствующим значениями:

cxопределяет координату X центра окружности.

cy определяет координату Y.

r — радиус.

fill используется для заливки формы цветом.

Этот фрагмент создает круг с радиусом 40px  с центром в точке  100px по оси X и 100px по оси Y. Координаты отсчитываются с верхнего левого угла родительского контейнера.

Давайте создадим несколько перекрывающихся кругов следующим образом:

<svg height="300" width="300">   <circle cx="80" cy="80" r="40" fill="red" />   <circle cx="120" cy="80" r="40" fill="red" />   <circle cx="150" cy="80" r="40" fill="red" />   <circle cx="150" cy="120" r="40" fill="red" />   <circle cx="100" cy="100" r="40" fill="red" /> </svg>

<svg>действует как холст, на котором нарисованы все различные формы и фигуры. Его значения высоты и ширины указывают на размер, в который должен быть заключен весь рисунок. Если какая-то часть фигуры выходит за пределы размера SVG, эта часть будет обрезана.

Но кляксы не всегда такие идеально круглые… Мы можем смешать объекты, используя <ellipse> вместо <circle>:

<ellipse cx="200" cy="80" rx="100" ry="50" fill="red" />

Этот элемент очень похож на  круг, за исключением имени тега и двух значений радиуса, чтобы определить горизонтальный (rx) и вертикальный (ry) радиусы по отдельности. Забавно то, что мы все равно можем получить правильный круг, если значения радиусов будут одинаковыми. Так что в некотором смысле <ellipse> немного более универсальный круг.

Если бы всё, что нам было нужно — это круг, мы, вероятно, могли бы использовать CSS без SVG. Любой прямоугольный элемент может стать кругом или эллипсом с правильно заданным значением border-radius.

.circle {   border-radius: 50%;   height: 50px;   width: 50px; }

…но об этом немного позже.

Фристайл с SVG-путями

Благодаря тегу <path> в SVG мы можем создавать любые формы. Это как рисовать карандашом или ручкой. Вы начинаете с точки и рисуете линии, кривые, формы, а потом замыкаете путь.

В <path> есть много  параметров  для различных задач, например:

M – Переход к точке

L – Рисование линии

C – Рисование кривой

– Кривые Безье

Z– Закрывание пути

Нам просто нужен параметр кривой (C) для примитивной кляксы. Но мы также переместим начальную точку и закроем путь, так что мы также воспользуемся параметрами M и Z.

Координаты играют большую роль в теге, поэтому то, что мы собираемся рассмотреть, будет выглядеть как данные Google Maps, заблокированные внутри нашего кода. Но это становится более логичным, когда мы знаем, что они делают.

Попробуем это…

<svg xmlns="http://www.w3.org/2000/svg">   <path     fill="#24A148"     d=""   /> </svg>

Здесь атрибут d хранит данные пути. Он содержит информацию о том, где начинается рисунок, в каком направлении он движется, какой форме следует и где заканчивается. Например:

<path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>

Это показывает, что наш путь начинается с координат (10 10), обозначенных буквой M перед ними. Затем он устанавливает кубическую кривую Безье (C) с двумя контрольными точками. Кривые Безье похожи на ручки на обоих концах пути, которые контролируют изгиб между ними. У нас есть две «ручки» Безье: одна для начального положения (20 20) кривой, а другая для конечного положения (40 20).

Давайте воспользуемся этими знаниями для создания нашего большого двоичного объекта.

Нарисованная мной клякса, на самом деле, немного сложна, с её множеством кривых и контрольных точек. Несколько смущает, что многие координаты не являются целыми числами,  но, тем не менее, теперь, когда мы знаем, что делает параметр d в теге <path> и какие атрибуты он использует для рисования точек на пути, это не выглядит так страшно.

Очевидно, что это большой объем кода, который нужно не только написать вручную, но и сделать все правильно. Но благо, для этого есть инструменты, которые облегчат вашу жизнь.

www.blobmaker.app

Эффекты липкости с фильтрами CSS и SVG

Правда SVG <path> сложен? Что, если я представлю вам способ преобразовать множество пользовательских фигур (которые вы можете создавать с помощью div) в липкие кляксы? Идея состоит в следующем — мы собираемся создать два пересекающихся прямоугольника. Они одного цвета, но имеют небольшую прозрачность, чтобы затемнить места пересечения.

Затем мы используем функции размытия SVG, чтобы размазать прямоугольники, создав дополнительное липкое пятно с более мягкими краями.

Два пересекающихся прямоугольника превратятся в это –

Давайте сначала разберемся, как работают фильтры в SVG. Они объявляются с помощью тега <filter> в элементах HTML или других элементах SVG, например, для тега <circle> можем применить CSS  правило.

circle {   filter: url("#id_of_filter"); } 

<filter> — это, по сути, оболочка для фактических эффектов фильтра, которые включают:

  • <feGaussianBlur>

  • <feImage>

  • <feMerge>

  • <feColorMatrix>

Наша клякса размытая и цветная, поэтому мы собираемся использовать <feGaussianBlur>и <feColorMatrix>.

<feGaussianBlur>принимает несколько атрибутов, но нас интересуют только два из них: сколько размытия мы хотим и где мы этого хотим. Стандартное отклонение (stdDeviation) и свойства in соответствуют нашим запросам.

in принимает одно из двух значений:

SourceGraphic — размывает всю форму

SourceAlpha — размывает альфа-значение и используется для создания теневых эффектов.

Немного поигравшись, я обнаружил эффект <feGaussianBlur>:

<feGaussianBlur in="SourceGraphic" stdDeviation="30" />

Это вставляется прямо в разметке HTML с идентификатором, который мы вызываем для родительского элемента нашего большого двоичного объекта:

<!-- The SVG filter --> <svg style="position: absolute; width: 0; height: 0;">   <filter id="goo">     <feGaussianBlur in="SourceGraphic" stdDeviation="30" />   </filter> </svg>  <!-- The blob --> <div class="hooks-main">   <div></div>   <div></div> </div> 

Фильтр на самом деле не отображается, даже если он находится в разметке. Вместо этого мы ссылаемся на него как на фильтр CSS в родительском элементе большого двоичного объекта:

Мдассс, это пока не то что нам надо. Размытие расфокусировано, а форма элемента потеряла границу и цвет. Нам нужен эффект выпуклости с размытием границ и сплошной цвет для заливки формы. Здесь в игру вступает наш следующий фильтр SVG, <feColorMatrix>.

Нам нужны два атрибута <feColorMatrix> :

in — указывает, где применяется эффект, как и <feGaussianBlur>.

values — матрица из четырех строк и пяти столбцов.

Атрибут values имеет немного больше нюансов. Он содержит матрицу, которая умножается на значения цвета и альфа канала каждого пикселя и генерирует новое значение цвета для этого пикселя. Математически говоря:

new pixel color value = ( values matrix ) × ( current pixel color value )

Немного математики в наших трансформациях. В этом уравнении матрица значений равна:

[F-red1 F-green1 F-blue1 F-alpha1 F-constant1  F-red2 F-green2 F-blue2 F-alpha2 F-constant2  F-red3 F-green3 F-blue3 F-alpha3 F-constant3  F-red4 F-green4 F-blue4 F-alpha4 F-constant4]

Здесь F-red означает долю красного в пикселях со значением от 0 до 1.

F-constant — это некоторое постоянное значение, которое нужно добавить (или вычесть) из значения цвета.

Разбиваем эти значения дальше…

У нас есть цветной пиксель со значением RGBA rgba (214, 232, 250, 1). Чтобы преобразовать его в новый цвет, мы умножим его на нашу матрицу значений.

Значение пикселя не изменилось, потому что мы умножили его на единичную матрицу, но если вы измените, значения матрицы, то изменится и ее значение в пикселях.

Узнайте больше о матрице значений из документации MDN.

В нашем случае эти значения работают очень хорошо:

<filter id="goo">   <feGaussianBlur in="SourceGraphic" stdDeviation="30" />   <feColorMatrix     in="blur"     values="1 0 0 0 0              0 1 0 0 0              0 0 1 0 0              0 0 0 30 -7"   /> </filter>

Я добавил еще несколько стилей в кляксу, чтобы растянуть её из угла.

Попробуйте использовать эти значения фильтра в других формах и дайте мне знать, как они работают для вас, в комментариях.

Использование CSS border-radius

Как упоминалось раньше, можно создать кляксу и при помощи CSS свойстваborder-radius. Он также может создавать формы, похожие на капли, благодаря способности сглаживать углы элемента. Это возможно, потому что каждый угловой радиус разделен на два радиуса, по одному для каждой кромки. Вот почему у нас может быть больше форм, кроме круга и эллипса.

Возможно, вы привыкли использовать border-radius как сокращение для всех четырех углов элемента:

.rounded {   border-radius: 25%; }

Это хороший способ добиться единообразия всех углов. Но кляксы не такие однородные. Мы хотим, чтобы одни углы были более округлыми, чем другие, чтобы некоторые из них выглядели липкими. Вот почему мы выбираем составляющие свойства border-radius, например:

.element {   border-top-left-radius: 70% 60%;   border-top-right-radius: 30% 40%;   border-bottom-right-radius: 30% 60%;   border-bottom-left-radius: 70% 40%; }

Как можно видеть каждое свойство принимает два значения. По одному на каждый край угла, что дает нам большую гибкость, чтобы изгибать элемент в интересные формы. Затем мы можем добавить цвет фона, заполнить его градиентом или даже установить на нем тень, чтобы получить аккуратный эффект.

ссылка на оригинал статьи https://habr.com/ru/post/545932/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *