From 12a4cf65b09798cb2fedd9f25962825848e48576 Mon Sep 17 00:00:00 2001 From: Luca Moschella Date: Thu, 4 Apr 2024 00:23:50 +0200 Subject: [PATCH] Implement spacing decaying at increasing indentation levels (#31) * Implement spacing decaying at increasing levels * Restore left edge behaviour * Default to center the list * Improve the defaults and the showcasing * Fix inconsistency in showcasing spacing * Run pre-commits --- src/powermanim/layouts/arrangedbullets.py | 62 ++++++++++++------- .../showcase/layouts/arrangedbullets.py | 3 +- .../showcase/templates/bulletlist.py | 1 + src/powermanim/templates/bulletlist.py | 12 ++-- 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/powermanim/layouts/arrangedbullets.py b/src/powermanim/layouts/arrangedbullets.py index 2f65c30..24c25a7 100644 --- a/src/powermanim/layouts/arrangedbullets.py +++ b/src/powermanim/layouts/arrangedbullets.py @@ -9,7 +9,7 @@ def __init__( *text: str, level: int = 0, group: T.Optional[int] = None, - adjustment: float = 0.0, + adjustment: T.Optional[T.Union[float, T.Sequence[float]]] = 0.0, symbol: T.Optional[str] = r"\bullet", autoplace: bool = True, **kwargs, @@ -52,7 +52,7 @@ def unindent(self, indent_buff: float = MED_LARGE_BUFF * 1.5): """ self.shift(LEFT * indent_buff * self.intend_level) - def adjust(self, adjustment: T.Optional[float] = None): + def adjust(self, adjustment: T.Optional[T.Union[float, T.Sequence[float]]] = None): """Adjust the bullet point. Args: @@ -69,7 +69,7 @@ def __init__( *text: str, level: int = 0, group: T.Optional[int] = None, - adjustment: float = 0.0, + adjustment: T.Optional[T.Union[float, T.Sequence[float]]] = 0.0, symbol: T.Optional[str] = r"$\bullet$", force_inline: bool = False, arg_separator="", @@ -95,41 +95,61 @@ def __init__( class ArrangedBullets(VGroup): - def arrage_rows(self, rows: T.Iterable[T.Union[MathBullet, Bullet, MathTex, Tex, Text]]): - bullet_rows: T.Iterable[MathBullet] = ( - VGroup(*rows) - .arrange(DOWN, aligned_edge=LEFT, buff=self.line_spacing) - .to_edge(LEFT, buff=self.left_buff) - .shift(self.global_shift) - ) - - for row in bullet_rows: + def arrange_rows(self, rows: T.Iterable[MathBullet]): + reference_row, *remaining_rows = VGroup(*rows).arrange(DOWN, aligned_edge=LEFT, buff=0) + + remaining_rows: T.Sequence[MathBullet] + for bullet in remaining_rows: + current_spacing = self.line_spacing * (self.line_spacing_decay**bullet.level) + + current_center = bullet.get_center() + current_up = bullet.get_critical_point(UP) + reference_down = reference_row.get_critical_point(DOWN) + + bullet.move_to( + np.asarray( + [ + # Start from the bottom of the previous line + # Add the decayed line spacing, depending on the bullet level + # Add half the object height, to account for multilines + current_center[0], + reference_down[1] - current_spacing - abs(current_center[1] - current_up[1]), + current_center[2], + ] + ) + ) + reference_row = bullet + + for row in rows: row.indent(indent_buff=self.indent_buff) row.adjust() def __init__( self, - *rows: T.Union[MathBullet, Bullet, MathTex, Tex, Text], + *rows: T.Union[MathBullet, Bullet, MathTex, Tex, Text, str], line_spacing: float = MED_LARGE_BUFF * 1.5, + line_spacing_decay: float = 1.0, indent_buff: float = MED_LARGE_BUFF * 1.5, - left_buff: float = MED_LARGE_BUFF * 1.5, - global_shift: float = 0.0, - ): + left_buff: float = MED_LARGE_BUFF * 2, + ): # TODO: remove argument defaults in next version? """A VGroup that arranges the rows in a list of bullet points. Args: rows: A list of items to be displayed. line_spacing: The spacing between the rows. + line_spacing_decay: The rate at which the spacing decays at each level indent_buff: The spacing between the bullet and the text. - left_buff: The spacing between the left edge of the rows and the left edge of the screen. - global_shift: The global_shift of the rows. + left_buff: The buff from the left edge """ self.line_spacing = line_spacing + self.line_spacing_decay = line_spacing_decay self.indent_buff = indent_buff self.left_buff = left_buff - self.global_shift = global_shift - rows = [(row if isinstance(row, MathBullet) else Bullet(row)) for row in rows] + rows: T.Sequence[T.Union[MathBullet, Bullet, MathTex, Tex, Text]] = [ + (Bullet(row) if isinstance(row, str) else row) for row in rows + ] - self.arrage_rows((row for row in rows if row.autoplace)) + self.arrange_rows([row for row in rows if row.autoplace]) super().__init__(*rows) + self.move_to(ORIGIN).to_edge(LEFT, self.left_buff) diff --git a/src/powermanim/showcase/layouts/arrangedbullets.py b/src/powermanim/showcase/layouts/arrangedbullets.py index 216c99d..4f72ec7 100644 --- a/src/powermanim/showcase/layouts/arrangedbullets.py +++ b/src/powermanim/showcase/layouts/arrangedbullets.py @@ -21,8 +21,7 @@ def construct(self): g_rows = VGroup(*rows).set_opacity(0.25).scale(0.9) g_rows.target = ArrangedBullets( *g_rows.copy(), - line_spacing=MED_LARGE_BUFF * 1.25, - left_buff=MED_LARGE_BUFF * 3, + line_spacing_decay=0.65, ).set_opacity(1) self.play( diff --git a/src/powermanim/showcase/templates/bulletlist.py b/src/powermanim/showcase/templates/bulletlist.py index c9b0f2d..5ab5001 100644 --- a/src/powermanim/showcase/templates/bulletlist.py +++ b/src/powermanim/showcase/templates/bulletlist.py @@ -23,6 +23,7 @@ def construct(self): bullets = BulletList( *rows, scale_active=1.2, + line_spacing_decay=0.65, ) self.add(bullets) diff --git a/src/powermanim/templates/bulletlist.py b/src/powermanim/templates/bulletlist.py index 5829bf2..f9c3269 100644 --- a/src/powermanim/templates/bulletlist.py +++ b/src/powermanim/templates/bulletlist.py @@ -10,33 +10,33 @@ def __init__( self, *rows: T.Union[MathBullet, Tex, Text], line_spacing: float = MED_LARGE_BUFF * 1.5, + line_spacing_decay: float = 1.0, # TODO: in the next version, change default to 0.65 indent_buff: float = MED_LARGE_BUFF * 1.5, - left_buff: float = MED_LARGE_BUFF * 2, - global_shift: float = 0.0, inactive_opacity: float = 0.5, active_opacity: float = 1.0, - scale_active: float = 1.0, + scale_active: float = 1.0, # TODO: in the next version, change default to 1.2 anim_lag_ratio: float = 0, + left_buff: float = MED_LARGE_BUFF * 2, ): """A class to represent an highlatable list of items. Args: rows: A list of items to be displayed. line_spacing: The spacing between the rows. + line_spacing_decay: The rate at which the spacing decays at each level indent_buff: The spacing between the bullet and the text. - left_buff: The spacing between the left edge of the rows and the left edge of the screen. - global_shift: The global_shift to apply to the rows. inactive_opacity: The opacity of the inactive items. active_opacity: The opacity of the active items. scale_active: The scale of the active items. anim_lag_ratio: The animation lag ratio. + left_buff: The buff from the left edge """ self.arranged_list = ArrangedBullets( *rows, line_spacing=line_spacing, + line_spacing_decay=line_spacing_decay, indent_buff=indent_buff, left_buff=left_buff, - global_shift=global_shift, ) super().__init__(