что такое градиент в цвете
А давайте я вам расскажу про градиенты!
скрин финального результата
В этой статье я рассказываю о том, как я изобрел свой личный велосипед, рисующий градиент практически как в фотошопе. Сразу предупреждаю, алгоритм ужасно медленный и неоптимизированный. Оптимизацией и рассмотрением какого-нибудь популярного алгоритма градиента я собираюсь заняться во второй части статьи
Зачем?
Как-то захотелось мне реализовать программную отрисовку градиентов, максимально похожих на фотошоповские. Никакой конкретной цели у меня не было, так, интересная задачка на вечер. В качестве языка была выбрана Java. Важной идеей было то, что я хотел написать этот алгоритм именно своими силами, не подглядывая в чужие алгоритмы.
Что должно было получиться
Метод drawGradient() должен работать следующим образом: мы задаем координаты и цвета двух точек, после чего поверх всего изображения рисуется градиент. Примерно так:
На данном рисунке точка A имеет координаты (55; 20) и цвет 0xff2e2e2e, а точка B — координаты (175; 180) и цвет 0xffb5b5b5. не забываем, что начало координат находится в левом верхнем углу, а ось Y направлена вниз.
Начинаем разбираться
В качестве эталона я взял градиент из фотошопа с прошлого скриншота. Как можно заметить, градиент состоит из трех частей:
Красная часть должна быть залита цветом точки А, зеленая — точки B, а цвет каждого пикселя оставшейся зоны должен вычисляться в зависимости от расстояния от него до прямых c и d.
Думаю очевидно, что нам нужен алгоритм, который будет определять расстояние от любого пикселя до прямых c и d. Также нужен способ для определения того, какой пиксель лежит в «красной» области, какой в «зеленой», а какой в оставшейся области.
Вспомним школьный курс геометрии и нарисуем следующую иллюстрацию для случайного пикселя E:
На данном рисунке AF — расстояние от пикселя E до прямой a. И, соответсвенно, FB — расстояние до прямой b. Именно эти расстояния и будут определять цвет пикселя. И тут же решается и проблема с определением того, к какой области относится пиксель. Тут все очень просто. Если AF + FB > AB, значит пиксель лежит либо в красной, либо в зеленой зоне. Чтобы определить в какой именно, сравним AF и FB. Если AF > FB, значит пиксель лежит в зеленой зоне, иначе в красной. Вот такая математика.
Итак, наша задача найти AF и BF. Сконцентрируемся на AF, по теореме Пифагора выходит, что:
Так, квадрат длины AE мы можем узнать из той же теоремы Пифагора, благо нам известны координаты точек A и E. Получается вот так:
Осталось найти только EF. Это немного потруднее, но ничего страшного. Так как наш отрезок EF представляет собой высоту треугольника, опущенную на сторону AB, нам поможет формула нахождения высоты. Выглядит она так:
А p — это одна из самых вводящих в заблуждение вещей. Это не периметр, а полупериметр. Помню пару раз совершал в школе фэйлы по этому поводу. Считается так:
AB и EB подсчитываем точно также как и AE — исходя из координат.
Итак, алгоритм подсчета AF как на ладони:
1. Рассчитываем AE, EB и AB
2. Рассчитываем p
3. Рассчитываем EF
4. Рассчитываем AF
Алгоритм для BF аналогичен, не буду его расписывать.
Самое время покодить!
Я решил создать класс, который представляет обертку для BufferedImage, назовем его EditableImage. И в этом классе, по моим прикидкам, должны были быть следующие методы:
Тут и далее все цвета в моем коде задаются в виде int, который имеет следующий вид:
Идея с классом удобна тем, что если я потом захочу реализовать еще какие-нибудь фишки кроме градиента, это будет легко сделать.
Начнем со вспомогательных штук, которые к градиенту не имеют отношения
Данную программу можно скомпилировать уже на этом этапе, но она покажет нам просто черную картинку. Самое время написать метод для градиента!
У меня получилось вот так:
Обратите внимание что я применяю функцию модуля — Math.abs() везде, где есть хоть малейшая вероятность того, что в функцию нахождения квадратного корня — Math.sqrt() может попасть отрицательное число. В противном случае у нас появятся артефакты.
Осталось только разобраться с методом interpolate и дело в шляпе. Он должен принимать начальный цвет, конечный цвет и число progress, которое может быть от 0 до 1 и которое определяет долю каждого цвета. Например если progress = 0, возвращается начальный цвет, если progress = 1 — конечный цвет, а если progress = 0.5 — средний цвет между начальным и конечным. Задача ясна, метод написан:
Давайте глянем на результат!
Уже неплохо, но наш использует линейную интерполяцию, а в фотошопе в ходу определенно какая-то другая.
Про интерполяции
Посмотрите внимательно на картинку. Левый градиент нарисован нашим алгоритмом, правый — фотошопом. На каждой строке стоит красная точка. И чем темнее строка, тем точка левее:
Как видно, линия у нас прямая, как рельса. Надо это исправлять. Вот тут я так ничего дельного не придумал и решил подсмотреть в интернете. Нашел статью на хабре, в которой описаны некоторые виды интерполяции и даже код есть: habrahabr.ru/post/142592
Ну что, реализуем косинусную интерполяция! Во первых добавим в класс EditableImage две константы:
Во вторых перепишем немного метод interpolate, чтобы ему на вход подавалась одна из этих констант:
Затем в список параметров метода drawGradient добавим int interpolation и в строчку вызова метода interpolate добавим эту переменную:
И в завершение в классе GradientPanel перепишем вызов метода drawGradient, добавив в него INTERPOLATION_COS
Вот что получилось с этим методом интерполяции:
Хм, выглядит неплохо, но в фотошопе линия явно не такая кривая. Что же делать? То слишком прямая, то слишком кривая… А что если сделать среднее из этих двух крайностей?
Отличная идея, добавляем константу INTERPOLATION_COS_LINEAR = 2
А в код метода interpolate добавляем еще один else if:
И о чудо, получилась практически полная копия градиента из фотошопа!
Сами поглядите:
Наша слева.
А вот вам две картинки с верхнего скриншота, совмещенные в одну. Видно, что интерполяция практически одинаковая, отличия можно свалить на погрешности при округлениях:
Ура, мы сделали градиент как в фотошопе, хоть и гораздо более медленный.
Исходники и jar
На этом я заканчиваю первую часть. Во второй части я постараюсь оптимизировать алгоритм так круто, как только смогу. И реализую какой-нибудь готовый известный быстрый алгоритм рисования градиента, а потом сравню его по скорости со своим.
Кстати, если у вас есть на примете быстрые алгоритмы рисования градиентов, оставляйте их в комментариях.
Работа с цветами и градиентами: инструменты и примеры
Пиксель-addicted руководитель направления дизайна ZephyrLab Дима Уколов сделал подборку о цветах и градиентах. Откуда они к нам такие пришли, удобные инструменты для работы и много вдохновляющих примеров.
С самого начала плоские приглушенные цвета вызывали неоднозначные эмоции. Просто, спокойно и современно, но всё время оставалось чувство недосказанности. Плоский стиль вообще пришёл в режиме «это временно, просто переходный период, потерпи».
И действительно, этот тренд был объективной необходимостью перед обновлением стилистики, можно сказать, революции в сфере web-дизайна, которая происходила на фоне всё больших возможностей вёрстки и кодинга.
Кстати, градиент в эпоху «до флэта» использовался в основном в натуральных скевоморфичных текстурах, где он особо не бросался в глаза. Чистые градиентные переливы старались не использовать — считалось дурным тоном. Во времена повального увлечения плоским дизайном про градиенты забыли вовсе.
Чистый градиент является мощным средством привлечения внимания, а удачные цветовые сочетания вытягивают стилистику сайта почти полностью. Объекты, иконки, символы и логотипы активно примеряют на себя различные сочетания.
Для поиска вдохновения и цветовых сочетаний можно воспользоваться сервисом webgradients.com — это более 200 вариаций и сочетаний.
materialui.co — удобный сервис с готовыми наборами. Не нужно наугад тыкать указателем в 17 млн. цветов с надеждой попасть с первого раза. Открываете сайт, кликаете на нужный цвет и копируете данные.
Светлые и белые фоны хорошо сочетаются в представлении товара или продукта, когда необходимо сохранить акцент на продукте и контрастном контенте и поддержать весь дизайн стилистически. Важно отметить, что почти всегда пастельный цвет будет хорошо сочетаться с паттерном или абстрактными геометрическими формами, поддерживающими стилистику. Хорошо в таких сочетаниях работают акценты и резкие переходы для форм захвата и CTA.
Чистые яркие цвета и контрастные сочетания пришли, наверное, из документации Гугл по материал-дизайну. Всё больше применяют дизайнеры подобные сочетания — зачастую проект только выигрывает от этого.
В наших проектах мы ещё в 2016 году начали использовать градиенты и яркие акцентные цвета и сочетания.
Старайтесь пробовать, экспериментировать и обсуждать совместно решения и вы увидите как качественно будет меняться ваш уровень.
Использование CSS-градиентов
Мы начнём с того, что покажем вам линейные градиенты, затем покажем возможности, поддерживаемые всеми типами градиентов, используя линейные градиенты в качестве примера, затем перейдём к круговым, коническим и повторяющимся градиентам.
Использование линейных градиентов
Линейный градиент создаёт цветную полосу, имеющую вид прямой линии.
Обычный линейный градиент
Чтобы создать самый простой тип градиента, всё, что вам нужно – это указать два цвета. Они называются точки остановки цвета. Их должно быть, как минимум, две, но у вас может быть столько, сколько захотите.
Изменение направления
По умолчанию линейные градиенты идут сверху вниз. Вы можете изменить угол поворота путём задания направления.
Диагональные градиенты
Вы можете даже создать градиент, проходящий диагонально, из угла в угол.
Использование углов
Если вы хотите больше контроля над его направлением, вы можете задать градиенту определённый угол.
При использовании угла 0deg создаётся вертикальный градиент, идущий снизу вверх, 90deg создаёт горизонтальный градиент, идущий слева направо, и так далее по часовой стрелке. Отрицательные углы идут против часовой стрелки.
Указание цветов и создание эффектов
Все типы CSS-градиентов – это диапазон позиционно-зависимых цветов. Цвета, создаваемые CSS-градиентами, могут варьироваться непрерывно с изменением позиции, создавая плавные цветовые переходы. Возможно также создавать полосы сплошных цветов, и резкие переходы между двумя цветами. Следующее примеры работают во всех градиентных функциях:
Использование более двух цветов
Вам не нужно ограничиваться двумя цветами – вы можете использовать столько, сколько хотите! По умолчанию цвета равномерно распределены по градиенту.
Расположение точек остановок цветов
Создание резких переходов
Подсказки градиента
По умолчанию градиент идёт плавно от одного цвета до другого. Вы можете добавить цветовую подсказку, чтобы переместить значение средней точки перехода в определённую точку градиента. В этом примере мы переместили среднюю точку перехода из отметки 50% на отметку 10%.
Создание цветных линий и полосок
Чтобы добавить внутрь градиента сплошную цветную область без плавного перехода, добавьте две позиции для точки остановки. Точки остановки могут быть в двух позициях, что эквивалентно двум подряд точкам остановки с тем же цветом на разных позициях. Цвет достигнет полной насыщенности на первой точке, проследует с той же насыщенностью до второй точки остановки и перейдёт в цвет следующей точки остановки через первую позицию следующей точки остановки.
В первом примере выше лаймовый цвет идёт от отметки 0%, далее, как указано, до отметки 20%, сделает переход от лаймового до красного через 10% ширины градиента, достигнет сплошного красного на отметке 30%, и останется таким до 45% градиента, где он потускнеет до голубого, оставаясь таким ещё 15% градиента, и так далее.
Во втором примере каждая вторая точка остановки для каждого цвета находится на той же позиции, что и первая точка остановки соседнего цвета, создавая полосатый эффект.
В обоих примерах градиент написан дважды: первый – это метод из CSS-изображений уровня 3 использующий повторения цвета на каждой остановке, а второй пример – это метод из CSS-изображений уровня 4, где в линейном объявлении точек остановки используются множественные точки остановки с двумя значениями длин точек остановки.
Управление переходом градиента
По умолчанию градиент плавно переходит между цветами двух соседних точек остановки, а средняя точка между этими двумя точками остановки является средним значением цветового перехода. Вы можете контролировать интерполяцию или переход между двумя точками остановки добавлением его расположения в цветовой подсказке. В этом примере цвет достигает средней точки перехода от лаймового до голубого на расстоянии 20% градиента вместо стандартных 50%. Во втором примере нет такой подсказки, чтобы подчеркнуть отличие, получаемое при её использовании:
Перекрытие градиентов
Градиенты поддерживают прозрачность, так что вы можете накладывать фоны для получения всяких разных эффектов. Фоны накладываются снизу вверх таким образом, что первый объявленный будет лежать поверх остальных.
Наслаивание градиентов
Вы можете даже наслаивать градиенты друг на друга. Если верхние градиенты не полностью непрозрачны, градиенты, лежащие под ними, тоже будут видны.
Использование круговых градиентов
Круговые градиенты схожи с линейными градиентами, за исключением того, что они создают градиентный круг по направлению от центральной точки. Вы можете указать, где должна находиться центральная точка. Вы также можете сделать её круглой или овальной.
Обычный круговой градиент
Как и в случае с линейными градиентами, всё, что вам нужно, чтобы создать круговой градиент – это два цвета. По умолчанию центр градиента находится на отметке 50% 50%, градиент становится овальным с учётом соотношения сторон содержащего его блока:
Размещение круговых точек остановки
Опять же, как и у линейных градиентов, вы можете расположить каждую круговую точку остановки, указав значение в виде процентной или абсолютной длины.
Расположение центра градиента
Вы можете расположить центр градиента с помощью ключевых значений, процентной или абсолютной длины. Значения в виде числа или процента повторяются в случае, если указано только одно из них, иначе порядок повторения будет определяться порядком расположения, начиная слева и сверху.
Задание размеров кругового градиента
В отличие от линейных градиентов, круговому градиенту можно задавать размеры. Возможные значения включат в себя: ближайший угол, ближайшая сторона, самый дальний угол и самая дальняя сторона, самый дальний угол – значение по умолчанию.
Пример: ближайшая сторона для эллипса
Пример: самый дальний угол для эллипса
Пример: ближайшая сторона для круга
Наложение круговых градиентов
Вы можете накладывать круговые градиенты так же, как линейные. Первый объявленный будет сверху, последний – снизу.
Использование конических градиентов
CSS-функция conic-gradient() создаёт изображение, состоящее из градиента с переходом цвета, обёрнутым вокруг центральной точки (в отличие от градиента, исходящего кругом от центральной точки). Образцом конического градиента можно назвать круговые диаграммы и цветовые круги, но он также может быть использован для создания шахматной доски (клетки) и других интересных эффектов.
Синтаксис конического градиента схож с синтаксисом кругового градиента, но с тем отличием, что точки остановки цвета располагаются вокруг градиентной дуги, вдоль длины окружности круга, а не по градиентной линии, идущей от центра градиента. Также, точки остановки цвета задаются только в процентах или градусах, абсолютные величины недопустимы.
В круговом градиенте цвета переходят от центра окружности наружу, во всех направлениях. В случае конического градиента цвета идут, как бы оборачиваясь вокруг центра круга, начиная сверху и двигаясь по часовой стрелке. Так же, как и в круговом градиенте, вы можете указать расположение центра градиента. Так же, как и в линейном градиенте, вы можете изменять угол градиента.
Обычный конический градиент
Так же, как и в случае с линейными и круговыми градиентами, всё, что вам нужно для создания конического градиента – это два цвета. По умолчанию центр градиента находится в точке 50% 50%, начало градиента направлено вверх:
Расположение конического центра
Как и в круговом градиенте, вы можете задать расположение центра конического градиента с помощью ключевых значений, процентных или абсолютных величин с использованием ключевого слова «at».
Изменение угла
Несколько слов о градиентах
Всем привет! Сегодня хочу поговорить немного о градиентах, популярных сайтах, предоставляющих пользователям возможность выбирать и/или генерировать их, а так же, о нескольких градиентах, которые я люблю и применяю в различных проектах. Возможно, кому-то из вас они тоже понравятся.
Сегодня мало кто не знает, что такое градиенты и как их применять в разработке. Если верить статьям, то в 2018 году, применение ярких и насыщенных градиентов — это некий тренд.
Что такое градиент?
Давайте, для галочки, вспомним, что такое градиент.
Градие́нт (от лат. gradiens, род. падеж gradientis — шагающий, растущий) — вектор, своим направлением указывающий направление наибольшего возрастания некоторой величины <\displaystyle \varphi >\varphi, значение которой меняется от одной точки пространства к другой (скалярного поля), а по величине (модулю) равный скорости роста этой величины в этом направлении
Градиенты применяются в различных сферах, но нас интересует сфера веб-разработки, где градиенты часто применяются в качестве основного фона сайтов и различных контейнеров, линий, цитат, блоков и даже текста.
Форма записи градиентов в css
Давайте коротко рассмотрим, из чего же состоит классический градиент.
Градиент может быть записан двумя способами:
background: linear-gradient(36deg, #0dd3ff, #0389ff, #1c79c0);
background-image: linear-gradient(36deg, #0dd3ff, #0389ff, #1c79c0);
Какую форму записи использовать — решать вам.
В коде, приведенном выше, мы указали три значения свойств background:
Все значения разделяются запятыми, а количество цветов может быть абсолютно любым, от двух до бесконечности. Но, разумеется, в пределах разумного.
Написание цвета градиентов
Цвет градиента может быть записан любым доступным обозначением:
Вы также можете указывать цвета в процентном соотношении, добавив после цвета %. Например, rgb(0, 0, 0) 0%, rgb(255,255,255) 100%.
Вот собственно и все базовые знания, необходимые для применения градиентов в веб-разработке. Но наверняка не все знают, что градиенты можно использовать и в других случая. Ниже о них.
Градиенты с изображениями
Для записи комбинированного градиента, с картинкой в качестве фона, можно использовать и другие свойства background. Давайте рассмотрим на двух примерах:
В первом примере мы создали градиентный фон (пример 1), а во втором добавили изображение и наложили на него наш градиент (пример 2).
Градиент для текста
Иногда хочется сделать текст ссылки или заголовка более ярким, заметным и/или заменить обычный текст на какую-нибудь картинку. CSS позволяет нам это сделать, используя следующие свойства:
Аналогичные действия можно совершать, заменив градиент на ссылку с изображением.
Главное помните, что некоторые свойства поддерживаются не всеми версиями браузеров. Проверить совместимость можно на сайте Can I use
Объединение градиентов CSS в режиме Background Blend Mode
Такие функции, как linear-gradient(), radial-gradient(), и repeating-linear-gradient(), repeating-radial-gradient() и другие разновидности имеют широкую поддержку и более стандартизированный синтаксис во всех современных браузерах. Однако, свойство background также может включать в себя более одного градиента, причем каждая функция разделяется запятой. Lea Verou продемонстрировала впечатляющие модели — паттерны, которые могут быть созданы с помощью этой техники: от шахматных досок, до кирпичей, до звезд. Но теперь, когда у нас есть свойство background-blend-mode, мы можем создать новые градиенты и шаблоны. Примеры ниже.
Спектральный фон
Наложим три градиента, чтобы создать фон с почти полным спектром цветов, который можно отобразить на мониторе.
.spectrum-background <
background:
linear-gradient(red, transparent),
linear-gradient(to top left, lime, transparent),
linear-gradient(to top right, blue, transparent);
background-blend-mode: screen;
>
И вот у нас уже получился разноцветный фон. Создание подобного эффекта ранее было возможно только с изображением, вес которого составлял бы десятки килобайт. Но мы только что воспроизвели этот эффект через CSS менее чем на 200 байт, не говоря уже о сохранении HTTP-запроса.
Создаем плед на css
Мы также можем создать интересные шаблоны с градиентами при помощи background-blend-mode.
.plaid-background <
background:
repeating-linear-gradient(
-45deg,
transparent 0,
transparent 25%,
dodgerblue 0,
dodgerblue 50%
),
repeating-linear-gradient(
45deg,
transparent 0,
transparent 25%,
tomato 0,
tomato 50%
),
repeating-linear-gradient(
transparent 0,
transparent 25%,
gold 0,
gold 50%
), white;
background-blend-mode: multiply;
background-size: 100px 100px;
>
В итоге вот что у нас получилось,
Фон сайта с кружочками
Эффект ночного видения
Давайте теперь попробуем воссоздать еще один эффект с режимами смешивания CSS и сделать фотографию, как будто мы просматриваем ее через объектив очков ночного видения.
Возьмем обычное изображение
и наложим на него радиальный градиент и градиент, который мы использовали при создании пледа — repeating-linear-gradient
.night-vision-effect <
background:
url(https://wallpaperbrowse.com/media/images/soap-bubble-1958650_960_720.jpg),
radial-gradient(
rgba(0,255,0,.8),
black
),
repeating-linear-gradient(
transparent 0,
rgba(0,0,0,.2) 3px,
transparent 6px
);
background-blend-mode: overlay;
background-size: cover;
>
И вот результат.
Сайты-генераторы градиентов
Ниже я приведу подборку сайтов, позволяющих генерировать те самые градиенты, делать из них canvas, png и svg форматы и копировать код для установки в ваши проекты.
И напоследок, хочу поделиться с вами своей подборкой градиентов, которые мне очень нравятся и которые я применяю в различных проектах и при разработке сайтов.
Всем удачи и приятного творчества. Пишите в комментариях свои любимые градиенты.