Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions manim/mobject/geometry/shape_matchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from manim.mobject.geometry.polygram import RoundedRectangle
from manim.mobject.mobject import Mobject
from manim.mobject.types.vectorized_mobject import VGroup
from manim.utils.color import BLACK, RED, YELLOW, Color, Colors
from manim.utils.color import BLACK, RED, YELLOW, Color


class SurroundingRectangle(RoundedRectangle):
Expand Down Expand Up @@ -79,7 +79,7 @@ def construct(self):
def __init__(
self,
mobject,
color: Colors | None = None,
color: str | None = None,
stroke_width: float = 0,
stroke_opacity: float = 0,
fill_opacity: float = 0.75,
Expand Down
3 changes: 1 addition & 2 deletions manim/mobject/mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
BLACK,
WHITE,
YELLOW_C,
Colors,
color_gradient,
interpolate_color,
)
Expand Down Expand Up @@ -1646,7 +1645,7 @@ def put_start_and_end_on(self, start, end):

# Background rectangle
def add_background_rectangle(
self, color: Optional[Colors] = None, opacity: float = 0.75, **kwargs
self, color: str = None, opacity: float = 0.75, **kwargs
):
"""Add a BackgroundRectangle as submobject.

Expand Down
3 changes: 1 addition & 2 deletions manim/mobject/opengl/opengl_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from manim.constants import *
from manim.utils.bezier import integer_interpolate, interpolate
from manim.utils.color import *
from manim.utils.color import Colors
from manim.utils.config_ops import _Data, _Uniforms

# from ..utils.iterables import batch_by_property
Expand Down Expand Up @@ -1983,7 +1982,7 @@ def set_shadow(self, shadow, recurse=True):
# Background rectangle

def add_background_rectangle(
self, color: Colors | None = None, opacity: float = 0.75, **kwargs
self, color: str | None = None, opacity: float = 0.75, **kwargs
):
# TODO, this does not behave well when the mobject has points,
# since it gets displayed on top
Expand Down
10 changes: 8 additions & 2 deletions manim/mobject/text/text_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def construct(self):

from __future__ import annotations

from manim.utils.color import get_all_colors

__all__ = ["Text", "Paragraph", "MarkupText", "register_font"]


Expand All @@ -71,7 +73,7 @@ def construct(self):
from manim.mobject.geometry.arc import Dot
from manim.mobject.svg.svg_mobject import SVGMobject
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.utils.color import Colors, color_gradient
from manim.utils.color import *
from manim.utils.deprecation import deprecated

TEXT_MOB_SCALE_FACTOR = 0.05
Expand Down Expand Up @@ -1331,7 +1333,11 @@ def _parse_color(self, col):
if re.match("#[0-9a-f]{6}", col):
return col
else:
return Colors[col.lower()].value
# lookup in COLOR_VALUES
colorDict = get_all_colors()
return colorDict[col]



def _extract_color_tags(self):
"""Used to determine which parts (if any) of the string should be formatted
Expand Down
263 changes: 6 additions & 257 deletions manim/utils/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
]

import random
from enum import Enum
from typing import Iterable

import numpy as np
Expand All @@ -30,260 +29,6 @@
from ..utils.bezier import interpolate
from ..utils.space_ops import normalize


class Colors(Enum):
"""A list of pre-defined colors.

Examples
--------

.. manim:: ColorsOverview
:save_last_frame:
:hide_source:

from manim.utils.color import Colors
class ColorsOverview(Scene):
def construct(self):
def color_group(color):
group = VGroup(
*[
Line(ORIGIN, RIGHT * 1.5, stroke_width=35, color=Colors[name].value)
for name in subnames(color)
]
).arrange_submobjects(buff=0.4, direction=DOWN)

name = Text(color).scale(0.6).next_to(group, UP, buff=0.3)
if any(decender in color for decender in "gjpqy"):
name.shift(DOWN * 0.08)
group.add(name)
return group

def subnames(name):
return [name + "_" + char for char in "abcde"]

color_groups = VGroup(
*[
color_group(color)
for color in [
"blue",
"teal",
"green",
"yellow",
"gold",
"red",
"maroon",
"purple",
]
]
).arrange_submobjects(buff=0.2, aligned_edge=DOWN)

for line, char in zip(color_groups[0], "abcde"):
color_groups.add(Text(char).scale(0.6).next_to(line, LEFT, buff=0.2))

def named_lines_group(length, colors, names, text_colors, align_to_block):
lines = VGroup(
*[
Line(
ORIGIN,
RIGHT * length,
stroke_width=55,
color=Colors[color].value,
)
for color in colors
]
).arrange_submobjects(buff=0.6, direction=DOWN)

for line, name, color in zip(lines, names, text_colors):
line.add(Text(name, color=color).scale(0.6).move_to(line))
lines.next_to(color_groups, DOWN, buff=0.5).align_to(
color_groups[align_to_block], LEFT
)
return lines

other_colors = (
"pink",
"light_pink",
"orange",
"light_brown",
"dark_brown",
"gray_brown",
)

other_lines = named_lines_group(
3.2,
other_colors,
other_colors,
[BLACK] * 4 + [WHITE] * 2,
0,
)

gray_lines = named_lines_group(
6.6,
["white"] + subnames("gray") + ["black"],
[
"white",
"lighter_gray / gray_a",
"light_gray / gray_b",
"gray / gray_c",
"dark_gray / gray_d",
"darker_gray / gray_e",
"black",
],
[BLACK] * 3 + [WHITE] * 4,
2,
)

pure_colors = (
"pure_red",
"pure_green",
"pure_blue",
)

pure_lines = named_lines_group(
3.2,
pure_colors,
pure_colors,
[BLACK, BLACK, WHITE],
6,
)

self.add(color_groups, other_lines, gray_lines, pure_lines)

VGroup(*self.mobjects).move_to(ORIGIN)


The preferred way of using these colors is by importing their constants from manim:

.. code-block:: pycon

>>> from manim import RED, GREEN, BLUE
>>> RED
'#FC6255'

Note this way uses the name of the colors in UPPERCASE.

Alternatively, you can also import this Enum directly and use its members
directly, through the use of :code:`color.value`. Note this way uses the
name of the colors in lowercase.

.. code-block:: pycon

>>> from manim.utils.color import Colors
>>> Colors.red.value
'#FC6255'

.. note::

The colors of type "C" have an alias equal to the colorname without a letter,
e.g. GREEN = GREEN_C

"""

white: str = "#FFFFFF"
gray_a: str = "#DDDDDD"
gray_b: str = "#BBBBBB"
gray_c: str = "#888888"
gray_d: str = "#444444"
gray_e: str = "#222222"
black: str = "#000000"
lighter_gray: str = gray_a
light_gray: str = gray_b
gray: str = gray_c
dark_gray: str = gray_d
darker_gray: str = gray_e

blue_a: str = "#C7E9F1"
blue_b: str = "#9CDCEB"
blue_c: str = "#58C4DD"
blue_d: str = "#29ABCA"
blue_e: str = "#236B8E"
pure_blue: str = "#0000FF"
blue: str = blue_c
dark_blue: str = blue_e

teal_a: str = "#ACEAD7"
teal_b: str = "#76DDC0"
teal_c: str = "#5CD0B3"
teal_d: str = "#55C1A7"
teal_e: str = "#49A88F"
teal: str = teal_c

green_a: str = "#C9E2AE"
green_b: str = "#A6CF8C"
green_c: str = "#83C167"
green_d: str = "#77B05D"
green_e: str = "#699C52"
pure_green: str = "#00FF00"
green: str = green_c

yellow_a: str = "#FFF1B6"
yellow_b: str = "#FFEA94"
yellow_c: str = "#FFFF00"
yellow_d: str = "#F4D345"
yellow_e: str = "#E8C11C"
yellow: str = yellow_c

gold_a: str = "#F7C797"
gold_b: str = "#F9B775"
gold_c: str = "#F0AC5F"
gold_d: str = "#E1A158"
gold_e: str = "#C78D46"
gold: str = gold_c

red_a: str = "#F7A1A3"
red_b: str = "#FF8080"
red_c: str = "#FC6255"
red_d: str = "#E65A4C"
red_e: str = "#CF5044"
pure_red: str = "#FF0000"
red: str = red_c

maroon_a: str = "#ECABC1"
maroon_b: str = "#EC92AB"
maroon_c: str = "#C55F73"
maroon_d: str = "#A24D61"
maroon_e: str = "#94424F"
maroon: str = maroon_c

purple_a: str = "#CAA3E8"
purple_b: str = "#B189C6"
purple_c: str = "#9A72AC"
purple_d: str = "#715582"
purple_e: str = "#644172"
purple: str = purple_c

pink: str = "#D147BD"
light_pink: str = "#DC75CD"

orange: str = "#FF862F"
light_brown: str = "#CD853F"
dark_brown: str = "#8B4513"
gray_brown: str = "#736357"


def print_constant_definitions():
"""
A simple function used to generate the constant values below. To run it
paste this function and the Colors class into a file and run them.
"""
constants_names: list[str] = []
for name in Colors.__members__.keys():
name_upper = name.upper()

constants_names.append(name_upper)
print(f"{name_upper} = Colors.{name}")

if "GRAY" in name_upper:
name_upper = name_upper.replace("GRAY", "GREY")

constants_names.append(name_upper)
print(f"{name_upper} = Colors.{name}")

constants_names_repr = '[\n "' + '",\n "'.join(constants_names) + '",\n]'

print(f"\n__all__ += {constants_names_repr}")


WHITE: str = "#FFFFFF"
GRAY_A: str = "#DDDDDD"
GREY_A: str = "#DDDDDD"
Expand Down Expand Up @@ -450,6 +195,11 @@ def print_constant_definitions():
"GREY_BROWN",
]

color_map = dict(((colorName, value) for colorName, value in locals().items() if str(value).startswith("#")))
all_colors = [c for colors, c in locals().items() if str(c).startswith("#")]

def get_all_colors():
return color_map

def color_to_rgb(color: Color | str) -> np.ndarray:
if isinstance(color, str):
Expand Down Expand Up @@ -535,8 +285,7 @@ def random_bright_color() -> Color:


def random_color() -> Color:
return random.choice([c.value for c in list(Colors)])

return random.choice(all_colors)

def get_shaded_rgb(
rgb: np.ndarray,
Expand Down