mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
feat(color): add HSV support to Color class
Add `Color.hsv` property and `Color.from_hsv` class method. This utilizes the existing `HSV` namedtuple which is currently unused.
This commit is contained in:
@@ -31,7 +31,7 @@ output = table
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from colorsys import hls_to_rgb, rgb_to_hls
|
||||
from colorsys import hls_to_rgb, hsv_to_rgb, rgb_to_hls, rgb_to_hsv
|
||||
from functools import lru_cache
|
||||
from operator import itemgetter
|
||||
from typing import Callable, NamedTuple
|
||||
@@ -82,7 +82,7 @@ class HSV(NamedTuple):
|
||||
s: float
|
||||
"""Saturation in range 0 to 1."""
|
||||
v: float
|
||||
"""Value un range 0 to 1."""
|
||||
"""Value in range 0 to 1."""
|
||||
|
||||
|
||||
class Lab(NamedTuple):
|
||||
@@ -212,6 +212,21 @@ class Color(NamedTuple):
|
||||
r, g, b = hls_to_rgb(h, l, s)
|
||||
return cls(int(r * 255 + 0.5), int(g * 255 + 0.5), int(b * 255 + 0.5))
|
||||
|
||||
@classmethod
|
||||
def from_hsv(cls, h: float, s: float, v: float) -> Color:
|
||||
"""Create a color from HSV components.
|
||||
|
||||
Args:
|
||||
h: Hue.
|
||||
s: Saturation.
|
||||
v: Value.
|
||||
|
||||
Returns:
|
||||
A new color.
|
||||
"""
|
||||
r, g, b = hsv_to_rgb(h, s, v)
|
||||
return cls(int(r * 255 + 0.5), int(g * 255 + 0.5), int(b * 255 + 0.5))
|
||||
|
||||
@property
|
||||
def inverse(self) -> Color:
|
||||
"""The inverse of this color.
|
||||
@@ -286,6 +301,19 @@ class Color(NamedTuple):
|
||||
h, l, s = rgb_to_hls(r, g, b)
|
||||
return HSL(h, s, l)
|
||||
|
||||
@property
|
||||
def hsv(self) -> HSV:
|
||||
"""This color in HSV format.
|
||||
|
||||
HSV color is an alternative way of representing a color, which can be used in certain color calculations.
|
||||
|
||||
Returns:
|
||||
Color encoded in HSV format.
|
||||
"""
|
||||
r, g, b = self.normalized
|
||||
h, s, v = rgb_to_hsv(r, g, b)
|
||||
return HSV(h, s, v)
|
||||
|
||||
@property
|
||||
def brightness(self) -> float:
|
||||
"""The human perceptual brightness.
|
||||
|
||||
@@ -52,6 +52,17 @@ def test_hsl():
|
||||
assert red.hsl.css == "hsl(356,81.8%,43.1%)"
|
||||
|
||||
|
||||
def test_hsv():
|
||||
red = Color(200, 20, 32)
|
||||
print(red.hsv)
|
||||
assert red.hsv == pytest.approx(
|
||||
(0.9888888888888889, 0.8999999999999999, 0.7843137254901961)
|
||||
)
|
||||
assert Color.from_hsv(
|
||||
0.9888888888888889, 0.8999999999999999, 0.7843137254901961
|
||||
).normalized == pytest.approx(red.normalized, rel=1e-5)
|
||||
|
||||
|
||||
def test_color_brightness():
|
||||
assert Color(255, 255, 255).brightness == 1
|
||||
assert Color(0, 0, 0).brightness == 0
|
||||
|
||||
Reference in New Issue
Block a user