Colors
Color helpers convert colors, blend hex values, and generate palettes.
The most commonly used helpers are exported from top-level pydreamplet:
import pydreamplet as dp
Lower-level legacy helpers are still available from pydreamplet.colors.
Theme
Theme stores reusable font settings and color tokens. With no arguments it
uses built-in defaults.
theme = dp.Theme()
assert theme.font_family == "sans-serif"
assert theme.font_size == 14
assert theme.blue == "oklch(62.3% 0.214 259.815)"
assert theme.color is theme.colors
Pass a JSON file path to override part or all of the default theme:
{
"font": {
"fontFamily": "Roboto",
"fontSize": 12,
"fontWeight": 400,
"lineHeight": 1.5
},
"colors": {
"ink": "oklch(27.4% 0.006 286.033)",
"surface": "oklch(96.7% 0.001 286.375)",
"brand": "oklch(62.3% 0.214 259.815)"
}
}
theme = dp.Theme("themes/light.json")
theme.font_family = "Roboto"
theme.font_size = 12
theme.font_weight = 600
theme.brand = (212, 136, 113)
theme.muted = (212, 136, 113, 0.5)
theme.gray = 128
assert theme.brand == "#d48871"
assert theme.muted == "rgba(212, 136, 113, 0.5)"
assert theme.gray == "#808080"
assert theme.colors.brand == "#d48871"
assert theme.colors["surface"] == "oklch(96.7% 0.001 286.375)"
Color is the token container used by Theme.colors. It supports attribute
access, mapping access, custom tokens, hex strings, CSS color strings, grayscale
integers, RGB tuples, and RGBA tuples. Theme also exposes color tokens
directly, so theme.amber is equivalent to theme.colors.amber.
Default theme colors are annotated on Theme, so IDEs can suggest names such as
theme.amber, theme.blue, and theme.surface. Runtime color tokens loaded
from JSON or assigned in Python are also exposed through dir(theme) for tools
that use runtime introspection.
Named default colors use Tailwind CSS 4.3 shade 500. theme.surface uses
Tailwind zinc-100, and theme.ink uses Tailwind zinc-800.
Visual Example
import pydreamplet as dp
palette = dp.generate_colors("#db45f9", n=8)
svg = dp.SVG(360, 120)
for index, color in enumerate(palette):
svg.append(
dp.Rect(x=20 + index * 40, y=24, width=34, height=52, rx=6, fill=color),
dp.Text(str(index + 1), x=37 + index * 40, y=96, font_size=13, text_anchor="middle", fill="currentColor"),
)
Top-Level Helpers
Theme(path: str | Path | None = None)
Color(**values: ColorInput)
hex_to_rgb(hex_color: str) -> tuple[int, int, int]
rgb_to_hex(rgb: tuple[int, int, int]) -> str
color2rgba(c: ColorInput, alpha: float = 1) -> str
blend_colors(color1: ColorInput, color2: ColorInput, proportion: float) -> str
blend(color1: ColorInput, color2: ColorInput, proportion: float) -> str
tone(color: ColorInput, amount: float) -> str
random_color() -> str
generate_colors(base_color: str, n: int = 10) -> list[str]
hex_to_rgb
Converts a six-digit hex color to an RGB tuple. The leading # is optional.
Three-digit shorthand is not accepted by this helper.
assert dp.hex_to_rgb("#ffffff") == (255, 255, 255)
assert dp.hex_to_rgb("000000") == (0, 0, 0)
Invalid lengths raise ValueError.
rgb_to_hex
Converts an RGB tuple to a lowercase hex string.
assert dp.rgb_to_hex((0, 0, 255)) == "#0000ff"
color2rgba
Converts a hex string, grayscale integer, or three-number RGB sequence to CSS
rgba(...).
assert dp.color2rgba((255, 0, 0), alpha=0.5) == "rgba(255, 0, 0, 0.5)"
assert dp.color2rgba(128, alpha=0.75) == "rgba(128, 128, 128, 0.75)"
assert dp.color2rgba("#00ff00", alpha=0.3) == "rgba(0, 255, 0, 0.3)"
RGB channels and alpha are constrained to their valid ranges.
blend_colors
Blends two supported color values. proportion=0 returns the first color and
proportion=1 returns the second. Proportions outside [0, 1] are constrained.
Opaque blends return hex. Blends involving alpha return rgba(...).
assert dp.blend_colors("#123456", "#abcdef", 0) == "#123456"
assert dp.blend_colors((0, 0, 0), 255, 0.5) in ("#7f7f7f", "#808080")
assert dp.blend_colors((212, 136, 113, 0.5), "#000000", 0) == "rgba(212, 136, 113, 0.5)"
assert dp.blend("invalid", "#abcdef", 0.5) == "#000000"
blend remains available as the shorter legacy name.
tone
Since v2.2.0Lightens or darkens a supported color. Positive amounts blend toward white,
negative amounts blend toward black, and values outside [-1, 1] are
constrained. Alpha is preserved.
assert dp.tone("#808080", 0.25) == "#a0a0a0"
assert dp.tone("#808080", -0.25) == "#606060"
theme = dp.Theme()
dark_red = dp.tone(theme.red, -0.2)
random_color
Returns a random six-digit hex color string.
color = dp.random_color()
assert color.startswith("#")
assert len(color) == 7
generate_colors
Generates n colors by preserving the base color's lightness and saturation and
rotating hue evenly around the color wheel.
palette = dp.generate_colors("#db45f9", n=5)
assert len(palette) == 5
assert palette[0].lower() == "#db45f9"
Module Helpers
These helpers are available from pydreamplet.colors, but are not exported from
top-level pydreamplet.
from pydreamplet.colors import hexStr, random_int, str2rgb
| Helper | Signature | Notes |
|---|---|---|
hexStr | (n: int) -> str | Formats an integer as a two-digit lowercase hex string. |
random_int | (min_val: int, max_val: int) -> int | Inclusive random integer helper. |
str2rgb | (col: str) -> dict[str, int] | Accepts #RRGGBB and #RGB; invalid input returns black. |
from pydreamplet.colors import hexStr, str2rgb
assert hexStr(16) == "10"
assert str2rgb("#f00") == {"r": 255, "g": 0, "b": 0}
assert str2rgb("notacolor") == {"r": 0, "g": 0, "b": 0}