Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e663946
Experimenting with an HSL class
MrDiver Dec 10, 2023
bf5c699
Merge branch 'main' into color_experiments
JasonGrace2282 Dec 27, 2023
3cebc3e
Add some more functionality
MrDiver Jul 21, 2024
16f7391
Adding a lot of tests and implementing fully functional conversion be…
MrDiver Jul 24, 2024
fed7ba5
Fix Merge
MrDiver Jul 24, 2024
f9e6fa2
Fixing tests
MrDiver Jul 24, 2024
91f203c
Fixing typing
MrDiver Jul 24, 2024
6de137f
return str to normal
MrDiver Jul 24, 2024
c6dbf3c
Additional documentation
MrDiver Jul 25, 2024
6b05c25
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
2a6687a
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
417771f
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
d7f2eb7
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
f734202
Fix documentation and typing and revamp operators to respect color sp…
MrDiver Jul 25, 2024
a38cf7f
Fix color operator typing and add operator tests
MrDiver Jul 25, 2024
892cdd7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 25, 2024
1fcf19c
Fix typeguard
MrDiver Jul 25, 2024
3e8c598
Merge branch 'color_experiments' of github.com:MrDiver/manim into col…
MrDiver Jul 25, 2024
7955087
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 25, 2024
49ea0a3
Import ManimFloat
MrDiver Jul 25, 2024
281a356
Merge branch 'color_experiments' of github.com:MrDiver/manim into col…
MrDiver Jul 25, 2024
e8ab6e7
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
68dcb4b
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
a6cafac
Add docstring to _internal_space
MrDiver Jul 25, 2024
1902772
Merge branch 'color_experiments' of github.com:MrDiver/manim into col…
MrDiver Jul 25, 2024
ff125ba
naming of functions according to pep8
MrDiver Jul 25, 2024
04dba5e
Merge branch 'main' into color_experiments
MrDiver Jul 25, 2024
a34e00c
Fix naming
MrDiver Jul 25, 2024
6b03c9c
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
a40cb86
Update manim/utils/color/core.py
MrDiver Jul 25, 2024
b63d85a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions manim/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
HSV_Array_Float: TypeAlias = RGB_Array_Float
HSV_Tuple_Float: TypeAlias = RGB_Tuple_Float

HSL_Array_Float: TypeAlias = RGB_Array_Float
HSL_Tuple_Float: TypeAlias = RGB_Tuple_Float

ManimColorInternal: TypeAlias = npt.NDArray[ManimColorDType]

# Point Types
Expand Down
117 changes: 117 additions & 0 deletions manim/utils/color/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
from typing_extensions import Self, TypeAlias

from manim.typing import (
HSL_Array_Float,
HSL_Tuple_Float,
HSV_Array_Float,
HSV_Tuple_Float,
ManimColorDType,
Expand Down Expand Up @@ -481,6 +483,22 @@ def to_hsv(self) -> HSV_Array_Float:
"""
return colorsys.rgb_to_hsv(*self.to_rgb())

def to_hsl(self) -> HSL_Array_Float:
"""Converts the Manim Color to HSL array.

.. note::
Be careful this returns an array in the form `[h, s, l]` where the elements are floats.
This might be confusing because rgb can also be an array of floats so you might want to annotate the usage
of this function in your code by typing the variables with :class:`HSL_Array_Float` in order to differentiate
between rgb arrays and hsl arrays

Returns
-------
HSL_Array_Float
A hsl array containing 3 elements of type float ranging from 0 to 1
"""
return colorsys.rgb(*self.to_rgb())

def invert(self, with_alpha=False) -> ManimColor:
"""Returns an linearly inverted version of the color (no inplace changes)

Expand Down Expand Up @@ -521,6 +539,21 @@ def interpolate(self, other: ManimColor, alpha: float) -> ManimColor:
self._internal_value * (1 - alpha) + other._internal_value * alpha
)

def opacity(self, opacity: float) -> ManimColor:
"""Creates a new ManimColor with the given opacity and the same color value as before

Parameters
----------
opacity : float
The new opacity value to be used

Returns
-------
ManimColor
The new ManimColor with the same color value but the new opacity
"""
return ManimColor(self._internal_value, opacity)

@classmethod
def from_rgb(
cls,
Expand Down Expand Up @@ -609,6 +642,27 @@ def from_hsv(
rgb = colorsys.hsv_to_rgb(*hsv)
return cls(rgb, alpha)

@classmethod
def from_hsl(
cls, hsl: HSL_Array_Float | HSL_Tuple_Float, alpha: float = 1.0
) -> Self:
"""Creates a ManimColor from an HSL Array

Parameters
----------
hsl : HSL_Array_Float | HSL_Tuple_Float
Any 3 Element Iterable containing floats from 0-1
alpha : float, optional
the alpha value to be used, by default 1.0

Returns
-------
ManimColor
The ManimColor with the corresponding RGB values to the HSL
"""
rgb = colorsys.hls_to_rgb(*hsl)
return cls(rgb, alpha)

@overload
@classmethod
def parse(
Expand Down Expand Up @@ -702,6 +756,69 @@ def __xor__(self, other: ManimColor) -> ManimColor:
return ManimColor(self.to_integer() ^ other.to_integer())


class HSV(ManimColor):

Check warning

Code scanning / CodeQL

`__eq__` not overridden when adding attributes

The class 'HSV' does not override ['__eq__'](1), but adds the new attribute [__hsv](2). The class 'HSV' does not override ['__eq__'](1), but adds the new attribute [__hsv](3).
def __init__(self, hsv: HSV_Array_Float | HSV_Tuple_Float) -> None:
self.hsv = hsv
super().__init__(colorsys.hsv_to_rgb(*hsv))

@property
def hue(self) -> float:
return self.hsv[0]

@property
def saturation(self) -> float:
return self.hsv[1]

@property
def value(self) -> float:
return self.hsv[2]

@hue.setter
def hue(self, value: float) -> None:
self.hsv[0] = value
self._internal_value[:3] = colorsys.hsv_to_rgb(*self.hsv)

@saturation.setter
def saturation(self, value: float) -> None:
self.hsv[1] = value
self._internal_value[:3] = colorsys.hsv_to_rgb(*self.hsv)

@value.setter
def value(self, value: float) -> None:
self.hsv[2] = value
self._internal_value[:3] = colorsys.hsv_to_rgb(*self.hsv)

def opacity(self, opacity: float) -> ManimColor:
return HSV(self.hsv, opacity)

@property
def h(self) -> float:
return self.hsv[0]

@property
def s(self) -> float:
return self.hsv[1]

@property
def v(self) -> float:
return self.hsv[2]

@h.setter
def h(self, value: float) -> None:
self.hsv[0] = value
self._internal_value[:3] = colorsys.hsv_to_rgb(*self.hsv)

@s.setter
def s(self, value: float) -> None:
self.hsv[1] = value
self._internal_value[:3] = colorsys.hsv_to_rgb(*self.hsv)

@v.setter
def v(self, value: float) -> None:
self.hsv[2] = value
self._internal_value[:3] = colorsys.hsv_to_rgb(*self.hsv)


ParsableManimColor: TypeAlias = Union[
ManimColor,
int,
Expand Down