3b1b-manim/manimlib/mobject/svg/special_tex.py
Grant Sanderson f4737828f6
Video work (#2326)
* Only use -no-pdf for xelatex rendering

* Instead of tracking du and dv points on surface, track points off the surface in the normal direction

This means that surface shading will not necessarily work well for arbitrary transformations of the surface. But the existing solution was flimsy anyway, and caused annoying issues with singularity points.

* Have density of anchor points on arcs depend on arc length

* Allow for specifying true normals and orientation of Sphere

* Change miter threshold on stroke shader

* Add get_start_and_end to DashedLine

* Add min_total_width option to DecimalNumber

* Have BackgroundRectangle.set_style absorb (and ignore) added configuration

Note, this feels suboptimal

* Add LineBrace

* Update font_size adjustment in Tex

* Add scale_factor parameter to BulletedList.fade_all_but

* Minor import tweaks

* Add play_sound
2025-03-20 12:00:35 -07:00

82 lines
2.7 KiB
Python

from __future__ import annotations
from manimlib.constants import MED_SMALL_BUFF, WHITE, GREY_C
from manimlib.constants import DOWN, LEFT, RIGHT, UP
from manimlib.constants import FRAME_WIDTH
from manimlib.constants import MED_LARGE_BUFF, SMALL_BUFF
from manimlib.mobject.geometry import Line
from manimlib.mobject.types.vectorized_mobject import VGroup
from manimlib.mobject.svg.tex_mobject import TexText
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from manimlib.typing import ManimColor, Vect3
class BulletedList(VGroup):
def __init__(
self,
*items: str,
buff: float = MED_LARGE_BUFF,
aligned_edge: Vect3 = LEFT,
**kwargs
):
labelled_content = [R"\item " + item for item in items]
tex_string = "\n".join([
R"\begin{itemize}",
*labelled_content,
R"\end{itemize}"
])
tex_text = TexText(tex_string, isolate=labelled_content, **kwargs)
lines = (tex_text.select_part(part) for part in labelled_content)
super().__init__(*lines)
self.arrange(DOWN, buff=buff, aligned_edge=aligned_edge)
def fade_all_but(self, index: int, opacity: float = 0.25, scale_factor=0.7) -> None:
max_dot_height = max([item[0].get_height() for item in self.submobjects])
for i, part in enumerate(self.submobjects):
trg_dot_height = (1.0 if i == index else scale_factor) * max_dot_height
part.set_fill(opacity=(1.0 if i == index else opacity))
part.scale(trg_dot_height / part[0].get_height(), about_edge=LEFT)
class TexTextFromPresetString(TexText):
tex: str = ""
default_color: ManimColor = WHITE
def __init__(self, **kwargs):
super().__init__(
self.tex,
color=kwargs.pop("color", self.default_color),
**kwargs
)
class Title(TexText):
def __init__(
self,
*text_parts: str,
font_size: int = 72,
include_underline: bool = True,
underline_width: float = FRAME_WIDTH - 2,
# This will override underline_width
match_underline_width_to_text: bool = False,
underline_buff: float = SMALL_BUFF,
underline_style: dict = dict(stroke_width=2, stroke_color=GREY_C),
**kwargs
):
super().__init__(*text_parts, font_size=font_size, **kwargs)
self.to_edge(UP, buff=MED_SMALL_BUFF)
if include_underline:
underline = Line(LEFT, RIGHT, **underline_style)
underline.next_to(self, DOWN, buff=underline_buff)
if match_underline_width_to_text:
underline.match_width(self)
else:
underline.set_width(underline_width)
self.add(underline)
self.underline = underline