Радиальные градиенты
Радиальный градиент - это цветовой переход, который раскрывается из центральной точки. Вместо того чтобы проецировать пиксели на прямую линию, рендерер измеряет расстояние каждого пикселя от центра, нормализует это расстояние через круг или эллипс и берет цвет из упорядоченного stop-листа на соответствующем радиусе.
В gradiente радиальный градиент - это типизированная модель с формой, размером, позицией, настройками интерполяции, stops, опциональными color hints и флагом повтора. Одну и ту же модель можно преобразовать в CSS, Canvas 2D, Canvas WebGL, SVG или в кастомный target трансформера.
radial-gradient(circle at 35% 35% in oklch, #ff74f6 0%, #fb7655 45%, #405de6 100%)radial-gradient(circle at 35% 35% in oklch, #ff74f6 0%, #fb7655 45%, #405de6 100%)Каждый preview-блок на этой странице отрисовывает один и тот же исходный градиент сразу в четырех targets: CSS, Canvas 2D, Canvas WebGL и SVG. Колонка WebGL - это снимок, созданный через transformTo('canvas-webgl', gradient), чтобы страница не держала слишком много активных WebGL-контекстов одновременно. Превью грузятся лениво, когда пример приближается к области просмотра.
Использование радиального градиента во фреймворке
Одна и та же модель gradiente может быть подключена в React, Vanilla JS, Vue или Svelte. Каждый пример парсит исходную строку, преобразует ее через transformTo('css') и применяет результат как настоящий background image.
Из чего состоит радиальный градиент
У модели радиального градиента есть пять смысловых частей:
Модель, которую хранит gradiente, не привязана к конкретному рендереру:
type GradientRadialConfig = {
shape: 'circle' | 'ellipse'
size:
| {
kind: 'extent'
value: 'closest-side' | 'closest-corner' | 'farthest-side' | 'farthest-corner'
}
| {
kind: 'explicit'
x: GradientLengthPercentage
y?: GradientLengthPercentage
}
position: GradientPosition
interpolation: {
colorSpace: GradientColorSpace
hue?: GradientHueInterpolation
}
isRepeating?: boolean
}Позиции stops хранятся как нормализованные числа: 0 означает центр, а 1 означает вычисленный внешний радиус. Используется та же общая stop-модель:
type GradientRadialStop =
| {
type: 'color-stop'
value: string
position: number
}
| {
type: 'color-hint'
position: number
}Значения цветов остаются строками, чтобы сохранить авторский ввод. Рендереры конвертируют и сэмплируют их только тогда, когда им нужны конкретные цвета.
Что делает gradiente
Для radial-gradient gradiente берет на себя работу, которая обычно распределяется между парсерами, UI-кодом, сериализаторами и рендерерами:
- Парсит CSS-like строки радиальных градиентов в экземпляр
GradientRadial. - Хранит форму, размер, позицию центра, интерполяцию, stops и состояние повтора.
- Подставляет дефолтные значения из одного места в конструкторе.
- Вычисляет отсутствующие позиции stops.
- Сохраняет color hints как полноценные stop-данные.
- Компактно сериализует double-position stops.
- Нормализует повторяющиеся радиальные градиенты через ту же модель.
- Вычисляет конкретные радиусы для рендерера, когда известна область отрисовки.
- Преобразует одну и ту же модель в CSS, Canvas 2D, Canvas WebGL и SVG.
Анатомия
Полный синтаксис состоит из одного опционального элемента конфигурации и обязательного stop-листа:
radial-gradient(
[shape] [size] [at position] [in color-space [hue-mode hue]],
color-stop-or-hint,
color-stop-or-hint,
...
)Первый элемент до запятой считается конфигурацией только тогда, когда в нем есть токены радиальной конфигурации. Все после первой запятой относится к stop-листу.
radial-gradient(circle closest-side at 30% 35% in oklch, red 0%, 35%, blue 100%)radial-gradient(circle closest-side at 30% 35% in oklch, red 0%, 35%, blue 100%)В этом примере есть:
circle: нормализованное поле расстояния имеет форму круга.closest-side: внешний радиус касается ближайшей стороны области отрисовки.at 30% 35%: центр смещен ближе к верхней левой области.in oklch: цвета интерполируются в OKLCH.red 0%: первый color stop расположен в центре.35%: color hint, который двигает середину перехода от red к blue.blue 100%: последний color stop расположен на вычисленном внешнем радиусе.
Дефолты
Если радиальная конфигурация не указана, gradiente использует CSS-like дефолт:
radial-gradient(red, blue)radial-gradient(red, blue)Дефолты класса:
shape: "ellipse"
size.kind: "extent"
size.value: "farthest-corner"
position: center center
interpolation.colorSpace: "srgb"
isRepeating: falseДефолтные значения не выводятся в toString(). Поэтому radial-gradient(ellipse farthest-corner at center in srgb, red, blue) может сериализоваться в компактный radial-gradient(red, blue).
Форма
Форма управляет полем расстояния, которое использует рендерер.
circle сохраняет одинаковые радиусы по x и y. Это удобно для свечений, spotlight-эффектов, focus rings, круглых масок, кнопок, бейджей и центрированных эффектов.
radial-gradient(circle, red, blue)radial-gradient(circle, red, blue)ellipse позволяет использовать разные радиусы по x и y. Это дефолтная форма, потому что она естественно заполняет прямоугольные области.
radial-gradient(ellipse 35% 70%, cyan, blue 60%, black)radial-gradient(35% 70%, cyan 0%, blue 60%, black 100%)Когда форма не указана, gradiente хранит ellipse. Когда форма явно равна circle, сериализатор сохраняет ее, потому что она меняет геометрию.
Размер
Размер определяет вычисленный радиус или радиусы. Он может быть keyword-based или явным.
Extent keywords:
closest-side дает компактный результат и часто полезен для контролируемых локальных подсветок.
radial-gradient(circle closest-side, red, blue)radial-gradient(circle closest-side, red, blue)closest-corner зависит и от центра, и от прямоугольной области отрисовки.
radial-gradient(circle closest-corner at 25% 75%, #ff74f6, #405de6)radial-gradient(circle closest-corner at 25% 75%, #ff74f6, #405de6)farthest-side может создавать широкие поля, которые при этом останавливаются раньше самого дальнего угла.
radial-gradient(circle farthest-side at left center, #ff74f6, #405de6)radial-gradient(circle farthest-side at left center, #ff74f6, #405de6)Явные размеры используют конкретные радиусы. Для круга нужен один length; для эллипса можно использовать два length или percentage значения.
radial-gradient(circle 70px at center, red, blue)radial-gradient(circle 70px, red, blue)Для явного эллипса первое значение - это радиус по x, второе - радиус по y:
radial-gradient(35% 70%, cyan 0%, blue 60%, black 100%)Позиция
Позиция двигает центр радиального градиента. Она всегда указывается после at.
Keyword-позиции используют x/y keywords:
radial-gradient(circle at top left, red, blue)radial-gradient(circle at left top, red, blue)gradiente нормализует keyword-позиции в порядок x/y. Например, at top left сериализуется как at left top.
Value-позиции используют два length-percentage значения:
radial-gradient(circle at 25% 75%, red, blue)radial-gradient(circle at 25% 75%, red, blue)Текущий radial parser намеренно держит позиции строгими: keyword-позиции состоят только из keywords, а value-позиции требуют два length-percentage токена. Смешанные CSS-формы вроде left 20px top 10px пока не входят в эту модель.
Stop-лист
Stop-лист определяет, какие цвета появляются вдоль радиуса. На практике радиальному градиенту обычно нужны минимум два color stops.
Если у color stop нет явной позиции, gradiente вычисляет ее по соседним stops. Первый неразрешенный color stop становится 0%, последний становится 100%, а неразрешенные stops между известными позициями распределяются равномерно.
radial-gradient(circle, red 0%, yellow 40%, blue 100%)radial-gradient(circle, red 0%, yellow 40%, blue 100%)Color hints - это bare percentages между двумя color stops. Они не создают новый color stop, а двигают воспринимаемую середину сегмента интерполяции.
radial-gradient(circle, red 0%, 35%, blue 100%)radial-gradient(circle, red 0%, 35%, blue 100%)Double-position stops создают жесткие кольца. Цвет, записанный с двумя позициями, хранится как два соседних color stops с одним и тем же цветом, а потом по возможности сериализуется обратно в компактную форму.
radial-gradient(circle, red 0% 35%, blue 35% 100%)radial-gradient(circle, red 0% 35%, blue 35% 100%)Интерполяция
Интерполяция управляет путем между цветами. Для радиальных градиентов это особенно важно: маленькая область центра может усиливать артефакты интерполяции, и грязная середина или резкий переход становятся очень заметными.
Дефолтное пространство интерполяции - srgb.
radial-gradient(circle in srgb, red, blue)radial-gradient(circle, red, blue)Перцепционные пространства вроде oklab часто дают более плавные переходы.
radial-gradient(circle at 25% 75% in oklab, red, blue)radial-gradient(circle at 25% 75% in oklab, red, blue)Полярные цветовые пространства могут использовать режимы hue-интерполяции. gradiente поддерживает shorter, longer, increasing и decreasing.
radial-gradient(in oklch longer hue, hsl(325, 64%, 54%), hsl(208, 94%, 47%))radial-gradient(in oklch longer hue, hsl(325, 64%, 54%), hsl(208, 94%, 47%))Поддерживаемые color spaces:
oklab
lch
oklch
hsl
hwb
lab
srgb
srgb-linear
xyz
display-p3
a98-rgb
prophoto-rgb
rec2020Повторяющиеся радиальные градиенты
repeating-radial-gradient(...) использует тот же внутренний вид градиента, что и radial-gradient(...). Префикс выставляет isRepeating: true в config, а type экземпляра остается radial-gradient.
repeating-radial-gradient(circle at center, red 0%, blue 20%)repeating-radial-gradient(circle, red 0%, blue 20%)Повторяющиеся радиальные градиенты полезны для ripples, targets, колец, scan-эффектов, halftone-like поверхностей и генерируемых систем паттернов.
Программное создание
Большинству пользователей стоит начинать с parse(), потому что он принимает формат, который люди уже знают по CSS. Когда градиент нужно собрать напрямую, используйте GradientRadial.
Конструктор принимает два параметра:
new GradientRadial(stops, config?)stops обязателен. config опционален, а пропущенные значения берутся из дефолтов класса.
import { GradientRadial } from 'gradiente'
const gradient = new GradientRadial(
[
{
type: 'color-stop',
value: '#ff74f6',
position: 0,
},
{
type: 'color-stop',
value: '#405de6',
position: 1,
},
],
{
shape: 'circle',
size: {
kind: 'extent',
value: 'closest-side',
},
position: {
kind: 'values',
x: {
kind: 'percent',
value: 35,
},
y: {
kind: 'percent',
value: 45,
},
},
interpolation: {
colorSpace: 'oklch',
},
},
)radial-gradient(circle closest-side at 35% 45% in oklch, #ff74f6, #405de6)Трансформация радиального градиента
Каждый renderer target получает одну и ту же исходную модель. В этом главный смысл Core API: один раз распарсить, много раз трансформировать.
import { parse, transformTo } from 'gradiente'
const gradient = parse(
'radial-gradient(ellipse 35% 70% at 35% 45% in oklch longer hue, #ff74f6, #405de6)'
)
const css = transformTo('css', gradient)
const canvas2d = transformTo('canvas-2d', gradient)
const webgl = transformTo('canvas-webgl', gradient)
const svg = transformTo('svg', gradient)radial-gradient(35% 70% at 35% 45% in oklch longer hue, #ff74f6, #405de6)У outputs трансформеров разные формы:
Нормализация
Используйте format() перед сохранением пользовательского ввода. Он парсит строку во внутреннюю модель и сериализует ее обратно в каноническую строку gradiente.
import { format } from 'gradiente'
const input = 'radial-gradient(circle closest-side at 35% 45% in oklch, #ff74f6 0%, 42%, #405de6 100%)'
const normalized = format(input)radial-gradient(circle closest-side at 35% 45% in oklch, #ff74f6 0%, 42%, #405de6 100%)Нормализация полезна, когда пользователи вводят градиенты вручную, когда сохраняется состояние редактора или когда сгенерированным градиентам нужен стабильный output для тестов и snapshots.
Практический чеклист
Используйте этот порядок при создании или валидации радиального градиента:
- Выберите форму:
circleдля одинаковых радиусов,ellipseдля прямоугольных полей. - Выберите размер: extent keyword для CSS-like поведения или явные радиусы для контролируемой геометрии.
- Выберите позицию через
at, если центр должен уйти из дефолтного центра. - Выберите интерполяцию:
srgbдля CSS parity,oklabилиoklchдля более плавных переходов. - Добавьте минимум два color stops, чтобы получить полезный визуальный результат.
- Добавьте явные позиции stops, если кольца или размеры свечения должны переживать редактирование.
- Используйте color hints, когда нужно сдвинуть середину перехода.
- Используйте double-position stops, когда нужны жесткие кольца.
- Используйте
format()перед сохранением пользовательского ввода. - Используйте
transformTo()для renderer output вместо ручной конвертации строки.