Добавляем эффект бликов линз CSS к фотографиям для придания им яркости
Я большой поклонник фильмов Дж. Дж. Абрамса. Мне нравятся их напряженные сюжеты, остроумные диалоги и, конечно же, анаморфные блики линз (lens flares). Такие режиссеры, как Абрамс, используют lens flares, чтобы добавить в свои фильмы немного "доморощенного" реализма. Эту технику мы можем легко воссоздать в таких инструментах, как Photoshop, а затем добавить на наши сайты в виде растровых изображений.
Но что, если мы хотим применить тот же вид lens flare без использования инструментов редактирования фотографий? Можно создать CSS lens flare, чтобы придать кинематографический оттенок изображениям в галерее, фоновым фотографиям или профилям пользователей.
В фотографии существуют различные типы бликов. Тот, с которым мы работаем, известен как артефакт, поскольку он оставляет после себя маленькие пятна света, которые принимают форму диафрагмы камеры, куда попадает луч и отражается от поверхности объектива.
Вот хороший пример бликов, которые мы собираемся сделать, взятый, естественно, прямо из кадра фильма Дж. Дж. Абрамса:
В приведенном выше lens flare есть несколько составляющих. Давайте перечислим их, чтобы знать, к чему стремиться:
Центральный источник света выглядит как светящийся шар.
Есть несколько горизонтальных эллиптических световых полос — лучи света, которые искажены и размыты, что приводит к появлению вытянутых эллипсов.
Случайные лучи света отходят от центрального источника под разными углами.
Для начала мы используем приведенные ниже элементы HTML, которые соответствуют компонентам блика. Имеется центральный источник света и два неправильных округлых блика, три горизонтальных lens flares и три конусообразных лучеобразных блика.
<div class="lens-center"></div>
<div class="circle-1"></div>
<div class="circle-2"></div>
<div class="left-flare horizontal-flare"></div>
<div class="right-flare horizontal-flare"></div>
<div class="full-flare horizontal-flare"></div>
<div class="conic-1"></div>
<div class="conic-2"></div>
<div class="conic-3"></div>
</div>
Наконец, для того чтобы lens flare правдоподобно накладывались на изображение, их центральный источник света должен быть настраиваемым. Таким образом, мы сможем разместить его над достоверным существующим источником света на изображении и не перекрыть ни одного лица.
Фон и источник света для CSS lens flare
Давайте начнем с черного фона и центрального источника света для нашего CSS lens flare. Большинство градиентов в Интернете — линейные, с одноцветными переходами, но мы можем применить к ним альфа-каналы, что на самом деле является хорошим способом получения эффекта свечения. Радиальный градиент округлой формы с несколькими слоями полупрозрачных цветов дает нам хороший эффект центра объектива.
background: radial-gradient(
closest-side circle at center,
hsl(4 5% 100% / 100%) 0%,
hsl(4 5% 100% / 100%) 15%,
hsl(4 10% 70% / 70%) 30%,
hsl(4 0% 50% / 30%) 55%,
hsl(4 0% 10% / 5%) 75%,
transparent 99
);
filter: blur(4px);
Интересно узнать о синтаксисе HSL? Он новый и, похоже, является будущим направлением определения альфа-прозрачности во всех цветовых функциях CSS.
Обратите внимание, что мы используем фильтр размытия CSS, чтобы градиенты выглядели более похожими на слои рассеянного света.
Теперь, зная, как добавлять круговые блики, давайте создадим более крупный рассеянный блик за источником света, а также три дополнительных блика под углом 45 градусов от центра, чтобы придать эффекту более реалистичный вид.
Результат смотрите в оригинале
Настройка горизонтальных световых полос
Давайте начнем с горизонтальных бликов. Есть несколько вариантов, которые могут быть использованы: градиент в виде очень вытянутого эллипса — самый простой подход. Однако я заметил, что горизонтальные lens flares обычно менее симметричны, чем те, что на моих референсных фотографиях, поэтому мне захотелось сделать и свои немного менее симметричными.
К счастью, радиальные градиенты имеют опциональный аргумент расположения в CSS. Мы можем создать две: левую и правую части одного и того же горизонтального блика немного разного размера и слегка отличающихся цветов. Также можно добавить фильтр прозрачности, чтобы создать область, где горизонтальные блики соединяются в центре, чтобы сделать его менее резким.
background: radial-gradient(
closest-side circle at center,
transparent 50%,
hsl(4 10% 70% / 40%) 90%,
transparent 100%
);
filter: blur(5px);
По ходу дела давайте также добавим один полностью вытянутый эллиптический нижний блик на три четверти длины окна просмотра для придания еще одного штриха "реалистичности".
Результат смотрите в оригинале
Создание рассеянных лучей света
Когда радиальные и горизонтальные блики расставлены, у нас остались только наклонные лучи, расходящиеся от источника света. Мы могли бы добавить дополнительные эллиптические радиальные градиенты, затем исказить и переместить контейнер, чтобы получить близкое приближение. Но у нас также есть градиент CSS, который уже создан для этой работы, — конический градиент. Ниже приведен пример, который дает нам конический градиент с углом 7 градусов и смещением на 5 градусов от правого нижнего угла контейнера.
background: conic-gradient(
from 5deg at 0% 100%,
transparent 0deg,
hsl(4 10% 70% / 30%) 7deg,
transparent 15deg
);
transform-origin: bottom left;
transform: rotate(-45deg);
Мы добавим несколько конических градиентов отцентрованных посередине нашего блика, с различными углами градиента полупрозрачных цветов. Поскольку конические градиенты могут показывать угол своего контейнера div, мы будем их трансформировать с помощью вращения, используя наш источник света в качестве начала координат, что приведет к эффекту смещения диффузионного светофильтра.
Результат смотрите в оригинале
Использование кастомных свойств CSS для создания более гибкого эффекта lens flare
До сих пор мы создавали респонсивный, но статично расположенный эффект lens flare в фиксированном месте. Было бы трудно настроить центр lens flare, не ломая при этом горизонтальные и конические блики вокруг него.
Чтобы сделать CSS lens flare одновременно регулируемым, и менее хрупким, мы определим положение, размер и оттенок блика источника света с помощью набора кастомных свойств.
:root {
--hue: 4;
--lens-center-size: 40%;
--lens-spread-size: 80%;
--lens-left: 55%;
--lens-top: 15%;
}
В процессе работы мы также отрегулируем оттенок и размер высоты горизонтального блика. Для ширины горизонтального блика мы используем возможность перегрузки CSS-переменных, чтобы сделать их регулируемыми самостоятельно; в противном случае мы вернемся к центру блика источника света или центру изображения.
.left-flare {
width: var(--left-flare-width, var(--lens-left, 50%));
}
Вот как выглядит завершенный эффект CSS lens flare с фоном фотографии и lens flare, перемещенными вверх, чтобы расположение источника света выглядело правдоподобно. Добавьте свою собственную фотографию, чтобы увидеть, как это работает в разных контекстах!
Результат смотрите в оригинале
Другие примеры эффектов CSS и не CSS lens flare
Разумеется, это лишь один из способов создания CSS lens flare. Мне нравится этот подход, потому что он гибкий в плане цвета, размера и позиционирования блика и его составляющих. Это делает его более многократно используемым компонентом, который можно применять во многих контекстах.
Вот один из проектов Кита Гранта, в котором используется линейный градиент, а также кастомные свойства CSS. Затем он добавляет немного JavaScript, чтобы рандомизировать значения HSLA.
Результат смотрите в оригинале
Николас Гест предлагает еще один вариант CSS lens flare, который применяет свойство тени блока к псевдоэлементам ::before
и ::after
элемента .flare
, чтобы получить эффект, плюс немного jQuery, который заставляет блик следовать за мышью при наведении курсора.
Результат смотрите в оригинале
Эта работа выполнена с помощью Canvas и отличается тем, что источник света следует за мышью при наведении, показывая, как артефакты lens flare меняют положение при изменении места источника света.
Результат смотрите в оригинале
Здесь та же самая идея:
Результат смотрите в оригинале
А также интересный вариант, в котором используются GSAP, Canvas и библиотека JS.LensFlare:
Результат смотрите в оригинале
Как бы вы подошли к созданию эффекта lens flare CSS? Поделитесь в комментариях.
Скоро в OTUS пройдет открытое занятие «Использование псевдоэлементов для создания интересных анимаций кнопок», на котором посмотрим, можно ли с помощью обычного CSS сделать нажатие на кнопки интересным и даже интригующим. Регистрация на вебинар.