Перейти к содержанию

Справочник по Gradient

Gradient — это класс, который превращает число в цвет. Он доступен сразу после from drawzero import *. Используйте его, когда вам нужны плавные цветовые переходы для тепловых карт, индикаторов выполнения, систем частиц или анимированных следов.

Это руководство также показывает, как комбинировать градиенты с фигурами из Графические примитивы, советами по прозрачности из Прозрачность и толщина линии и анимированными циклами из Анимации.

Быстрый старт

from drawzero import *

heat = Gradient([C.blue, C.cyan, C.yellow, C.red])
print(heat(0.0))   # (0, 0, 255) - первый цвет
print(heat(0.5))   # (0, 255, 255) - средний цвет
print(heat(1.0))   # (255, 0, 0) - последний цвет
  • Первый аргумент — это список цветов. Вы можете смешивать константы из C, именованные строки ('gold') или кортежи RGB, такие как (34, 139, 34).
  • По умолчанию допустимый диапазон ввода (домен) от 0 до 1.
  • Передача значения меньше начального приводит к выбору первого цвета; большие значения — к выбору последнего.

Почему градиенты полезны

  • Непрерывное затенение – рисуйте прямоугольники, которые плавно переходят от холодных к горячим цветам.
  • Анимированные эффекты – изменяйте цвета частиц по мере их старения.
  • Индикаторы состояния – сопоставляйте прогресс (0–100) с палитрой.

Откройте пример 13_gradients.py после прочтения этой страницы. Файл также указан в Обзоре примеров.

Создание градиента

Gradient(color_list, start=0.0, end=1.0, *extra_domain_points)
  • color_list должен содержать как минимум два элемента.
  • Если вы передаете только start и end, утилита равномерно распределяет цвета по этому диапазону.
  • Когда вы предоставляете дополнительные числа, утилита автоматически их сортирует. Конечный домен всегда имеет ту же длину, что и color_list.

Равномерно распределенный домен

heat = Gradient([C.blue, C.white, C.red], 0, 100)
print(heat(0))     # синий
print(heat(50))    # белый
print(heat(100))   # красный

Цвета располагаются в точках 0, 50 и 100, потому что список содержит три элемента.

Пользовательские позиции для каждого цвета

mist = Gradient([C.black, 'purple', C.white], 0, 30, 100)
print(mist(10))   # темно-фиолетовый
print(mist(60))   # бледно-фиолетовый, близкий к белому

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

Использование необработанных кортежей RGB

sunrise = Gradient([(25, 25, 112), (255, 140, 0), (255, 215, 0)], -1, 1)

Любое число за пределами [-1, 1] будет приведено к первому или последнему кортежу.

Правила проверки

Если точки домена не соответствуют количеству цветов, Gradient вызывает BadDrawParmsError. Сообщение предлагает исправленный вызов, такой как Gradient([C.red, C.green], 0, 100).

Выборка цветов внутри рисунков

Объекты Gradient являются вызываемыми. Вы можете передавать результат прямо в утилиты рисования.

from drawzero import *

glow = Gradient([C.black, C.blue, C.cyan, C.white])

for index in range(10):
    color = glow(index / 9)   # 0.0 .. 1.0
    filled_circle(color, (500, 500), 40 + index * 15)

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

Сетка прямоугольников тепловой карты

from drawzero import *

heat = Gradient([C.darkblue, C.lawngreen, C.yellow, C.orangered], 0, 30)
cell_size = 80

for row in range(5):
    for col in range(5):
        value = row * 5 + col  # имитация показаний датчика
        color = heat(value)
        filled_rect(color, (100 + col * cell_size, 100 + row * cell_size), cell_size, cell_size)
        text('white', f"{value}", (110 + col * cell_size, 110 + row * cell_size))

Утилита приводит любое число выше 30 к последнему цвету (C.orangered).

Сопоставление прогресса анимации с цветами

Градиенты очень хорошо сочетаются с циклом tick() из Анимации.

from drawzero import *

trail = Gradient([C.white, C.skyblue, C.blue, C.navy])
ball = Pt(200, 500, heading=0)

while tick():
    clear()
    for tail in range(20):
        color = trail(tail / 19)
        filled_circle(color, (ball.x - tail * 12, ball.y), 20 - tail)
    ball.forward(5)
    if ball.x > 1000:
        ball.goto(0, ball.y)

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

Понимание интерполяции

Между двумя значениями домена утилита линейно смешивает цветовые каналы:

channel = left_channel * (right_x - current_x) / diff + right_channel * (current_x - left_x) / diff

Каждый канал (R, G, B) округляется до ближайшего целого числа. Обычно вам не нужно беспокоиться об этой математике, но это помогает объяснить, почему градиенты создают плавные переходы даже при неравномерном распределении домена.

Советы и устранение неполадок

  • Домен должен быть отсортирован. Утилита автоматически сортирует ваши числа, но передача смешанных строк и чисел вызывает сообщение об ошибке.
  • Короткие палитры требуют соответствующей длины домена. Два цвета работают с двумя точками домена. Три цвета требуют трех точек и так далее.
  • Повторно используйте градиенты. Сохраните объект один раз (например, heat = Gradient(...)) и вызывайте его много раз за кадр вместо создания новых градиентов внутри циклов.
  • Комбинируйте с альфа-каналом. Используйте ключевое слово alpha из Прозрачность и толщина линии, чтобы еще больше затушевать фигуры.
  • Тестируйте в оболочке. Градиенты имеют читаемое repr, поэтому их печать помогает при отладке.
heat = Gradient([C.blue, C.white, C.red], 0, 100)
print(heat)
# Gradient([(0, 0, 255), (255, 255, 255), (255, 0, 0)], 0, 50.0, 100)

Где читать дальше

  • Графические примитивы – показывает все функции, которые принимают цвета.
  • Помощник Pt – используйте движущиеся точки вместе с градиентами для анимированных следов.
  • Обзор примеров – найдите 13_gradients.py и другие скрипты, которые смешивают градиенты с движением.
  • Заметки по архитектуре – краткое изложение того, как вспомогательные утилиты (включая Gradient) вписываются в проект.

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