mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Enhancement: Migrate width/height/depth to properties (#1024)
* Migrate width/height/depth to properties * Fix examples * Fix typos * Import manim for doctests * Expect Square for doctests * Improve docs for width/height/depth properties
This commit is contained in:
parent
05ca2949fd
commit
3ad385a168
28 changed files with 333 additions and 145 deletions
|
|
@ -330,7 +330,7 @@ Plotting with Manim
|
|||
y_max=6,
|
||||
x_labeled_nums=[0,2,3],
|
||||
**kwargs)
|
||||
|
||||
|
||||
def construct(self):
|
||||
self.setup_axes()
|
||||
curve1 = self.get_graph(lambda x: 4 * x - x ** 2, x_min=0, x_max=4)
|
||||
|
|
@ -435,7 +435,7 @@ Special Camera Settings
|
|||
dot = Dot().shift(UL * 2)
|
||||
image = ImageMobject(np.uint8([[0, 100, 30, 200],
|
||||
[255, 0, 5, 33]]))
|
||||
image.set_height(7)
|
||||
image.height = 7
|
||||
frame_text = Text("Frame", color=PURPLE).scale(1.4)
|
||||
zoomed_camera_text = Text("Zoomed camera", color=RED).scale(1.4)
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class WriteStuff(Scene):
|
|||
)
|
||||
group = VGroup(example_text, example_tex)
|
||||
group.arrange(DOWN)
|
||||
group.set_width(config["frame_width"] - 2 * LARGE_BUFF)
|
||||
group.width = config["frame_width"] - 2 * LARGE_BUFF
|
||||
|
||||
self.play(Write(example_text))
|
||||
self.play(Write(example_tex))
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class MovingCamera(Camera):
|
|||
float
|
||||
The height of the frame.
|
||||
"""
|
||||
return self.frame.get_height()
|
||||
return self.frame.height
|
||||
|
||||
@property
|
||||
def frame_width(self):
|
||||
|
|
@ -80,7 +80,7 @@ class MovingCamera(Camera):
|
|||
float
|
||||
The width of the frame.
|
||||
"""
|
||||
return self.frame.get_width()
|
||||
return self.frame.width
|
||||
|
||||
@property
|
||||
def frame_center(self):
|
||||
|
|
@ -158,9 +158,9 @@ class MovingCamera(Camera):
|
|||
# def realign_frame_shape(self):
|
||||
# height, width = self.frame_shape
|
||||
# if self.fixed_dimension == 0:
|
||||
# self.frame_shape = (height, self.frame.get_width())
|
||||
# self.frame_shape = (height, self.frame.width
|
||||
# else:
|
||||
# self.frame_shape = (self.frame.get_height(), width)
|
||||
# self.frame_shape = (self.frame.height, width)
|
||||
# self.resize_frame_shape(fixed_dimension=self.fixed_dimension)
|
||||
|
||||
def get_mobjects_indicating_movement(self):
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ class MultiCamera(MovingCamera):
|
|||
for imfc in self.image_mobjects_from_cameras:
|
||||
pixel_height, pixel_width = self.pixel_array.shape[:2]
|
||||
imfc.camera.frame_shape = (
|
||||
imfc.camera.frame.get_height(),
|
||||
imfc.camera.frame.get_width(),
|
||||
imfc.camera.frame.height,
|
||||
imfc.camera.frame.width,
|
||||
)
|
||||
imfc.camera.reset_pixel_shape(
|
||||
int(pixel_height * imfc.get_height() / self.frame_height),
|
||||
int(pixel_width * imfc.get_width() / self.frame_width),
|
||||
int(pixel_height * imfc.height / self.frame_height),
|
||||
int(pixel_width * imfc.width / self.frame_width),
|
||||
)
|
||||
|
||||
def reset(self):
|
||||
|
|
|
|||
|
|
@ -404,8 +404,8 @@ def serialize_mobject(mobject):
|
|||
logger.info(
|
||||
f"Expected path {mobject.path} to be under the assets dir ({assets_dir_path})"
|
||||
)
|
||||
mob_proto.image_mobject_data.height = mobject.get_height()
|
||||
mob_proto.image_mobject_data.width = mobject.get_width()
|
||||
mob_proto.image_mobject_data.height = mobject.height
|
||||
mob_proto.image_mobject_data.width = mobject.width
|
||||
mob_center = mobject.get_center()
|
||||
mob_proto.image_mobject_data.center.x = mob_center[0]
|
||||
mob_proto.image_mobject_data.center.y = mob_center[1]
|
||||
|
|
|
|||
|
|
@ -16,16 +16,27 @@ from ..utils.color import BLACK
|
|||
|
||||
class ScreenRectangle(Rectangle):
|
||||
def __init__(self, aspect_ratio=16.0 / 9.0, height=4, **kwargs):
|
||||
self.aspect_ratio = aspect_ratio
|
||||
self.height = height
|
||||
Rectangle.__init__(self, **kwargs)
|
||||
self.set_width(self.aspect_ratio * self.get_height(), stretch=True)
|
||||
Rectangle.__init__(self, width=aspect_ratio * height, height=height, **kwargs)
|
||||
|
||||
@property
|
||||
def aspect_ratio(self):
|
||||
"""The aspect ratio.
|
||||
|
||||
When set, the width is stretched to accommodate
|
||||
the new aspect ratio.
|
||||
"""
|
||||
|
||||
return self.width / self.height
|
||||
|
||||
@aspect_ratio.setter
|
||||
def aspect_ratio(self, value):
|
||||
self.stretch_to_fit_width(value * self.height)
|
||||
|
||||
|
||||
class FullScreenRectangle(ScreenRectangle):
|
||||
def __init__(self, **kwargs):
|
||||
ScreenRectangle.__init__(self, **kwargs)
|
||||
self.set_height(config["frame_height"])
|
||||
self.height = config["frame_height"]
|
||||
|
||||
|
||||
class FullScreenFadeRectangle(FullScreenRectangle):
|
||||
|
|
@ -41,8 +52,18 @@ class FullScreenFadeRectangle(FullScreenRectangle):
|
|||
|
||||
class PictureInPictureFrame(Rectangle):
|
||||
def __init__(self, height=3, aspect_ratio=16.0 / 9.0, **kwargs):
|
||||
self.height = height
|
||||
self.aspect_ratio = aspect_ratio
|
||||
Rectangle.__init__(
|
||||
self, width=self.aspect_ratio * self.height, height=self.height, **kwargs
|
||||
)
|
||||
Rectangle.__init__(self, width=aspect_ratio * height, height=height, **kwargs)
|
||||
|
||||
@property
|
||||
def aspect_ratio(self):
|
||||
"""The aspect ratio.
|
||||
|
||||
When set, the width is stretched to accommodate
|
||||
the new aspect ratio.
|
||||
"""
|
||||
|
||||
return self.width / self.height
|
||||
|
||||
@aspect_ratio.setter
|
||||
def aspect_ratio(self, value):
|
||||
self.stretch_to_fit_width(value * self.height)
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ class Circle(Arc):
|
|||
# TODO: Figure out and fix
|
||||
self.replace(mobject, dim_to_match, stretch)
|
||||
|
||||
self.set_width(np.sqrt(mobject.get_width() ** 2 + mobject.get_height() ** 2))
|
||||
self.width = np.sqrt(mobject.width ** 2 + mobject.height ** 2)
|
||||
return self.scale(buffer_factor)
|
||||
|
||||
def point_at_angle(self, angle):
|
||||
|
|
@ -519,9 +519,7 @@ class LabeledDot(Dot):
|
|||
rendered_label = label
|
||||
|
||||
if radius is None:
|
||||
radius = (
|
||||
0.1 + max(rendered_label.get_width(), rendered_label.get_height()) / 2
|
||||
)
|
||||
radius = 0.1 + max(rendered_label.width, rendered_label.height) / 2
|
||||
Dot.__init__(self, radius=radius, **kwargs)
|
||||
rendered_label.move_to(self.get_center())
|
||||
self.add(rendered_label)
|
||||
|
|
@ -530,10 +528,8 @@ class LabeledDot(Dot):
|
|||
class Ellipse(Circle):
|
||||
def __init__(self, width=2, height=1, **kwargs):
|
||||
Circle.__init__(self, **kwargs)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.set_width(self.width, stretch=True)
|
||||
self.set_height(self.height, stretch=True)
|
||||
self.stretch_to_fit_width(width)
|
||||
self.stretch_to_fit_height(height)
|
||||
|
||||
|
||||
class AnnularSector(Arc):
|
||||
|
|
@ -788,11 +784,10 @@ class TangentLine(Line):
|
|||
|
||||
class Elbow(VMobject):
|
||||
def __init__(self, width=0.2, angle=0, **kwargs):
|
||||
self.width = width
|
||||
self.angle = angle
|
||||
VMobject.__init__(self, **kwargs)
|
||||
self.set_points_as_corners([UP, UP + RIGHT, RIGHT])
|
||||
self.set_width(self.width, about_point=ORIGIN)
|
||||
self.scale_to_fit_width(width, about_point=ORIGIN)
|
||||
self.rotate(self.angle, about_point=ORIGIN)
|
||||
|
||||
|
||||
|
|
@ -1227,20 +1222,27 @@ class Rectangle(Polygon):
|
|||
close_new_points=True,
|
||||
**kwargs
|
||||
):
|
||||
self.height = height
|
||||
self.width = width
|
||||
self.mark_paths_closed = mark_paths_closed
|
||||
self.close_new_points = close_new_points
|
||||
Polygon.__init__(self, UL, UR, DR, DL, color=color, **kwargs)
|
||||
self.set_width(self.width, stretch=True)
|
||||
self.set_height(self.height, stretch=True)
|
||||
self.stretch_to_fit_width(width)
|
||||
self.stretch_to_fit_height(height)
|
||||
|
||||
|
||||
class Square(Rectangle):
|
||||
def __init__(self, side_length=2.0, **kwargs):
|
||||
self.side_length = side_length
|
||||
Rectangle.__init__(self, height=side_length, width=side_length, **kwargs)
|
||||
|
||||
@property
|
||||
def side_length(self):
|
||||
"""The square's side length."""
|
||||
|
||||
return self.width
|
||||
|
||||
@side_length.setter
|
||||
def side_length(self, value):
|
||||
self.width = value
|
||||
|
||||
|
||||
class RoundedRectangle(Rectangle):
|
||||
def __init__(self, corner_radius=0.5, **kwargs):
|
||||
|
|
@ -1279,8 +1281,8 @@ class ArrowTip(VMobject):
|
|||
... def __init__(self, **kwargs):
|
||||
... RegularPolygon.__init__(self, n=5, **kwargs)
|
||||
... length = 0.35
|
||||
... self.set_width(length)
|
||||
... self.set_height(length, stretch=True)
|
||||
... self.width = length
|
||||
... self.stretch_to_fit_height(length)
|
||||
>>> arr = Arrow(np.array([-2, -2, 0]), np.array([2, 2, 0]),
|
||||
... tip_shape=MyCustomArrowTip)
|
||||
>>> isinstance(arr.tip, RegularPolygon)
|
||||
|
|
@ -1419,8 +1421,8 @@ class ArrowTriangleTip(ArrowTip, Triangle):
|
|||
start_angle=start_angle,
|
||||
**kwargs
|
||||
)
|
||||
self.set_width(length)
|
||||
self.set_height(length, stretch=True)
|
||||
self.width = length
|
||||
self.stretch_to_fit_height(length)
|
||||
|
||||
|
||||
class ArrowTriangleFilledTip(ArrowTriangleTip):
|
||||
|
|
@ -1450,8 +1452,8 @@ class ArrowCircleTip(ArrowTip, Circle):
|
|||
Circle.__init__(
|
||||
self, fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs
|
||||
)
|
||||
self.set_width(length)
|
||||
self.set_height(length, stretch=True)
|
||||
self.width = length
|
||||
self.stretch_to_fit_height(length)
|
||||
|
||||
|
||||
class ArrowCircleFilledTip(ArrowCircleTip):
|
||||
|
|
@ -1482,8 +1484,8 @@ class ArrowSquareTip(ArrowTip, Square):
|
|||
side_length=length,
|
||||
**kwargs
|
||||
)
|
||||
self.set_width(length)
|
||||
self.set_height(length, stretch=True)
|
||||
self.width = length
|
||||
self.stretch_to_fit_height(length)
|
||||
|
||||
|
||||
class ArrowSquareFilledTip(ArrowSquareTip):
|
||||
|
|
|
|||
|
|
@ -84,9 +84,8 @@ class ManimBanner(VGroup):
|
|||
tex.next_to(anim, buff=0.01)
|
||||
tex.align_to(self.M, DOWN)
|
||||
anim.add(tex)
|
||||
anim.set_color(self.font_color).set_height(
|
||||
m_height_over_anim_height * self.M.get_height()
|
||||
)
|
||||
anim.set_color(self.font_color)
|
||||
anim.height = m_height_over_anim_height * self.M.height
|
||||
|
||||
# Note: "anim" is only shown in the expanded state
|
||||
# and thus not yet added to the submobjects of self.
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class Matrix(VMobject):
|
|||
def add_brackets(self, left="\\big[", right="\\big]"):
|
||||
bracket_pair = MathTex(left, right)
|
||||
bracket_pair.scale(2)
|
||||
bracket_pair.stretch_to_fit_height(self.get_height() + 2 * self.bracket_v_buff)
|
||||
bracket_pair.stretch_to_fit_height(self.height + 2 * self.bracket_v_buff)
|
||||
l_bracket, r_bracket = bracket_pair.split()
|
||||
l_bracket.next_to(self, LEFT, self.bracket_h_buff)
|
||||
r_bracket.next_to(self, RIGHT, self.bracket_h_buff)
|
||||
|
|
@ -228,7 +228,7 @@ def get_det_text(
|
|||
):
|
||||
parens = MathTex("(", ")")
|
||||
parens.scale(initial_scale_factor)
|
||||
parens.stretch_to_fit_height(matrix.get_height())
|
||||
parens.stretch_to_fit_height(matrix.height)
|
||||
l_paren, r_paren = parens.split()
|
||||
l_paren.next_to(matrix, LEFT, buff=0.1)
|
||||
r_paren.next_to(matrix, RIGHT, buff=0.1)
|
||||
|
|
|
|||
|
|
@ -354,6 +354,86 @@ class Mobject(Container):
|
|||
# Unhandled attribute, therefore error
|
||||
raise AttributeError
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
"""The width of the mobject.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`float`
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. manim:: WidthExample
|
||||
|
||||
class WidthExample(Scene):
|
||||
def construct(self):
|
||||
decimal = DecimalNumber().to_edge(UP)
|
||||
rect = Rectangle(color=BLUE)
|
||||
rect_copy = rect.copy().set_stroke(GRAY, opacity=0.5)
|
||||
|
||||
decimal.add_updater(lambda d: d.set_value(rect.width))
|
||||
|
||||
self.add(rect_copy, rect, decimal)
|
||||
self.play(rect.animate.set(width=7))
|
||||
self.wait()
|
||||
"""
|
||||
|
||||
# Get the length across the X dimension
|
||||
return self.length_over_dim(0)
|
||||
|
||||
@width.setter
|
||||
def width(self, value):
|
||||
self.scale_to_fit_width(value)
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""The height of the mobject.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`float`
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. manim:: HeightExample
|
||||
|
||||
class HeightExample(Scene):
|
||||
def construct(self):
|
||||
decimal = DecimalNumber().to_edge(UP)
|
||||
rect = Rectangle(color=BLUE)
|
||||
rect_copy = rect.copy().set_stroke(GRAY, opacity=0.5)
|
||||
|
||||
decimal.add_updater(lambda d: d.set_value(rect.height))
|
||||
|
||||
self.add(rect_copy, rect, decimal)
|
||||
self.play(rect.animate.set(height=5))
|
||||
self.wait()
|
||||
"""
|
||||
|
||||
# Get the length across the Y dimension
|
||||
return self.length_over_dim(1)
|
||||
|
||||
@height.setter
|
||||
def height(self, value):
|
||||
self.scale_to_fit_height(value)
|
||||
|
||||
@property
|
||||
def depth(self):
|
||||
"""The depth of the mobject.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`float`
|
||||
"""
|
||||
|
||||
# Get the length across the Z dimension
|
||||
return self.length_over_dim(2)
|
||||
|
||||
@depth.setter
|
||||
def depth(self, value):
|
||||
self.scale_to_fit_depth(value)
|
||||
|
||||
def get_array_attrs(self):
|
||||
return ["points"]
|
||||
|
||||
|
|
@ -754,24 +834,120 @@ class Mobject(Container):
|
|||
self.scale(length / old_length, **kwargs)
|
||||
return self
|
||||
|
||||
def scale_to_fit_width(self, width, **kwargs):
|
||||
"""Scales the mobject to fit a width while keeping height/depth proportional.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`Mobject`
|
||||
``self``
|
||||
|
||||
Examples
|
||||
--------
|
||||
::
|
||||
|
||||
>>> from manim import *
|
||||
>>> sq = Square()
|
||||
>>> sq.height
|
||||
2.0
|
||||
>>> sq.scale_to_fit_width(5)
|
||||
Square
|
||||
>>> sq.width
|
||||
5.0
|
||||
>>> sq.height
|
||||
5.0
|
||||
"""
|
||||
|
||||
return self.rescale_to_fit(width, 0, stretch=False, **kwargs)
|
||||
|
||||
def stretch_to_fit_width(self, width, **kwargs):
|
||||
"""Stretches the mobject to fit a width, not keeping height/depth proportional.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`Mobject`
|
||||
``self``
|
||||
|
||||
Examples
|
||||
--------
|
||||
::
|
||||
|
||||
>>> from manim import *
|
||||
>>> sq = Square()
|
||||
>>> sq.height
|
||||
2.0
|
||||
>>> sq.stretch_to_fit_width(5)
|
||||
Square
|
||||
>>> sq.width
|
||||
5.0
|
||||
>>> sq.height
|
||||
2.0
|
||||
"""
|
||||
|
||||
return self.rescale_to_fit(width, 0, stretch=True, **kwargs)
|
||||
|
||||
def scale_to_fit_height(self, height, **kwargs):
|
||||
"""Scales the mobject to fit a height while keeping width/depth proportional.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`Mobject`
|
||||
``self``
|
||||
|
||||
Examples
|
||||
--------
|
||||
::
|
||||
|
||||
>>> from manim import *
|
||||
>>> sq = Square()
|
||||
>>> sq.width
|
||||
2.0
|
||||
>>> sq.scale_to_fit_height(5)
|
||||
Square
|
||||
>>> sq.height
|
||||
5.0
|
||||
>>> sq.width
|
||||
5.0
|
||||
"""
|
||||
|
||||
return self.rescale_to_fit(height, 1, stretch=False, **kwargs)
|
||||
|
||||
def stretch_to_fit_height(self, height, **kwargs):
|
||||
"""Stretches the mobject to fit a height, not keeping width/depth proportional.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`Mobject`
|
||||
``self``
|
||||
|
||||
Examples
|
||||
--------
|
||||
::
|
||||
|
||||
>>> from manim import *
|
||||
>>> sq = Square()
|
||||
>>> sq.width
|
||||
2.0
|
||||
>>> sq.stretch_to_fit_height(5)
|
||||
Square
|
||||
>>> sq.height
|
||||
5.0
|
||||
>>> sq.width
|
||||
2.0
|
||||
"""
|
||||
|
||||
return self.rescale_to_fit(height, 1, stretch=True, **kwargs)
|
||||
|
||||
def scale_to_fit_depth(self, depth, **kwargs):
|
||||
"""Scales the mobject to fit a depth while keeping width/height proportional."""
|
||||
|
||||
return self.rescale_to_fit(depth, 2, stretch=False, **kwargs)
|
||||
|
||||
def stretch_to_fit_depth(self, depth, **kwargs):
|
||||
"""Stretches the mobject to fit a depth, not keeping width/height proportional."""
|
||||
|
||||
return self.rescale_to_fit(depth, 2, stretch=True, **kwargs)
|
||||
|
||||
def set_width(self, width, stretch=False, **kwargs):
|
||||
return self.rescale_to_fit(width, 0, stretch=stretch, **kwargs)
|
||||
|
||||
def set_height(self, height, stretch=False, **kwargs):
|
||||
return self.rescale_to_fit(height, 1, stretch=stretch, **kwargs)
|
||||
|
||||
def set_depth(self, depth, stretch=False, **kwargs):
|
||||
return self.rescale_to_fit(depth, 2, stretch=stretch, **kwargs)
|
||||
|
||||
def set_coord(self, value, dim, direction=ORIGIN):
|
||||
curr = self.get_coord(dim, direction)
|
||||
shift_vect = np.zeros(self.dim)
|
||||
|
|
@ -810,8 +986,8 @@ class Mobject(Container):
|
|||
raise Warning("Attempting to replace mobject with no points")
|
||||
return self
|
||||
if stretch:
|
||||
self.stretch_to_fit_width(mobject.get_width())
|
||||
self.stretch_to_fit_height(mobject.get_height())
|
||||
self.stretch_to_fit_width(mobject.width)
|
||||
self.stretch_to_fit_height(mobject.height)
|
||||
else:
|
||||
self.rescale_to_fit(
|
||||
mobject.length_over_dim(dim_to_match), dim_to_match, stretch=False
|
||||
|
|
@ -1061,15 +1237,6 @@ class Mobject(Container):
|
|||
np.max, np.max, dim
|
||||
) - self.reduce_across_dimension(np.min, np.min, dim)
|
||||
|
||||
def get_width(self):
|
||||
return self.length_over_dim(0)
|
||||
|
||||
def get_height(self):
|
||||
return self.length_over_dim(1)
|
||||
|
||||
def get_depth(self):
|
||||
return self.length_over_dim(2)
|
||||
|
||||
def get_coord(self, dim, direction=ORIGIN):
|
||||
"""
|
||||
Meant to generalize get_x, get_y, get_z
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class NumberLine(Line):
|
|||
self.unit_size = unit_size
|
||||
self.include_ticks = include_ticks
|
||||
self.tick_size = tick_size
|
||||
self.width = width
|
||||
self.tick_frequency = tick_frequency
|
||||
self.leftmost_tick = leftmost_tick
|
||||
self.numbers_with_elongated_ticks = numbers_with_elongated_ticks
|
||||
|
|
@ -83,8 +82,8 @@ class NumberLine(Line):
|
|||
color=color,
|
||||
**kwargs,
|
||||
)
|
||||
if self.width is not None:
|
||||
self.set_width(self.width)
|
||||
if width is not None:
|
||||
self.width = width
|
||||
self.unit_size = self.get_unit_size()
|
||||
self.shift(-self.number_to_point(self.number_at_center))
|
||||
|
||||
|
|
|
|||
|
|
@ -114,9 +114,9 @@ class DecimalNumber(VMobject):
|
|||
for i, c in enumerate(num_string):
|
||||
if c == "-" and len(num_string) > i + 1:
|
||||
self[i].align_to(self[i + 1], UP)
|
||||
self[i].shift(self[i + 1].get_height() * DOWN / 2)
|
||||
self[i].shift(self[i + 1].height * DOWN / 2)
|
||||
elif c == ",":
|
||||
self[i].shift(self[i].get_height() * DOWN / 2)
|
||||
self[i].shift(self[i].height * DOWN / 2)
|
||||
if self.unit and self.unit.startswith("^"):
|
||||
self.unit_sign.align_to(self, UP)
|
||||
#
|
||||
|
|
@ -187,7 +187,7 @@ class DecimalNumber(VMobject):
|
|||
new_submobject.original_id = generated_id
|
||||
|
||||
# Make sure last digit has constant height
|
||||
new_decimal.scale(self[-1].get_height() / new_decimal[-1].get_height())
|
||||
new_decimal.scale(self[-1].height / new_decimal[-1].height)
|
||||
new_decimal.move_to(self, self.edge_to_fix)
|
||||
new_decimal.match_style(self)
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ class SampleSpace(Rectangle):
|
|||
def add_title(self, title="Sample space", buff=MED_SMALL_BUFF):
|
||||
# TODO, should this really exist in SampleSpaceScene
|
||||
title_mob = Tex(title)
|
||||
if title_mob.get_width() > self.get_width():
|
||||
title_mob.set_width(self.get_width())
|
||||
if title_mob.width > self.width:
|
||||
title_mob.width = self.width
|
||||
title_mob.next_to(self, UP, buff=buff)
|
||||
self.title = title_mob
|
||||
self.add(title_mob)
|
||||
|
|
@ -175,8 +175,6 @@ class BarChart(VGroup):
|
|||
**kwargs
|
||||
):
|
||||
VGroup.__init__(self, **kwargs)
|
||||
self.height = height
|
||||
self.width = width
|
||||
self.n_ticks = n_ticks
|
||||
self.tick_width = tick_width
|
||||
self.label_y_axis = label_y_axis
|
||||
|
|
@ -191,19 +189,19 @@ class BarChart(VGroup):
|
|||
if self.max_value is None:
|
||||
self.max_value = max(values)
|
||||
|
||||
self.add_axes()
|
||||
self.add_bars(values)
|
||||
self.add_axes(width, height)
|
||||
self.add_bars(values, width, height)
|
||||
self.center()
|
||||
|
||||
def add_axes(self):
|
||||
x_axis = Line(self.tick_width * LEFT / 2, self.width * RIGHT)
|
||||
y_axis = Line(MED_LARGE_BUFF * DOWN, self.height * UP)
|
||||
def add_axes(self, width, height):
|
||||
x_axis = Line(self.tick_width * LEFT / 2, width * RIGHT)
|
||||
y_axis = Line(MED_LARGE_BUFF * DOWN, height * UP)
|
||||
ticks = VGroup()
|
||||
heights = np.linspace(0, self.height, self.n_ticks + 1)
|
||||
heights = np.linspace(0, height, self.n_ticks + 1)
|
||||
values = np.linspace(0, self.max_value, self.n_ticks + 1)
|
||||
for y, value in zip(heights, values):
|
||||
tick = Line(LEFT, RIGHT)
|
||||
tick.set_width(self.tick_width)
|
||||
tick.width = self.tick_width
|
||||
tick.move_to(y * UP)
|
||||
ticks.add(tick)
|
||||
y_axis.add(ticks)
|
||||
|
|
@ -215,18 +213,18 @@ class BarChart(VGroup):
|
|||
labels = VGroup()
|
||||
for tick, value in zip(ticks, values):
|
||||
label = MathTex(str(np.round(value, 2)))
|
||||
label.set_height(self.y_axis_label_height)
|
||||
label.height = self.y_axis_label_height
|
||||
label.next_to(tick, LEFT, SMALL_BUFF)
|
||||
labels.add(label)
|
||||
self.y_axis_labels = labels
|
||||
self.add(labels)
|
||||
|
||||
def add_bars(self, values):
|
||||
buff = float(self.width) / (2 * len(values) + 1)
|
||||
def add_bars(self, values, width, height):
|
||||
buff = float(width) / (2 * len(values) + 1)
|
||||
bars = VGroup()
|
||||
for i, value in enumerate(values):
|
||||
bar = Rectangle(
|
||||
height=(value / self.max_value) * self.height,
|
||||
height=(value / self.max_value) * height,
|
||||
width=buff,
|
||||
stroke_width=self.bar_stroke_width,
|
||||
fill_opacity=self.bar_fill_opacity,
|
||||
|
|
|
|||
|
|
@ -15,9 +15,13 @@ class SurroundingRectangle(Rectangle):
|
|||
def __init__(self, mobject, color=YELLOW, buff=SMALL_BUFF, **kwargs):
|
||||
self.color = color
|
||||
self.buff = buff
|
||||
kwargs["width"] = mobject.get_width() + 2 * self.buff
|
||||
kwargs["height"] = mobject.get_height() + 2 * self.buff
|
||||
Rectangle.__init__(self, color=color, **kwargs)
|
||||
Rectangle.__init__(
|
||||
self,
|
||||
color=color,
|
||||
width=mobject.width + 2 * self.buff,
|
||||
height=mobject.height + 2 * self.buff,
|
||||
**kwargs
|
||||
)
|
||||
self.move_to(mobject)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class Brace(MathTex):
|
|||
else:
|
||||
mob.move_to(self.get_tip())
|
||||
buff = kwargs.get("buff", DEFAULT_MOBJECT_TO_MOBJECT_BUFFER)
|
||||
shift_distance = mob.get_width() / 2.0 + buff
|
||||
shift_distance = mob.width / 2.0 + buff
|
||||
mob.shift(self.get_direction() * shift_distance)
|
||||
return self
|
||||
|
||||
|
|
|
|||
|
|
@ -238,8 +238,8 @@ class Code(VGroup):
|
|||
foreground = VGroup(self.code, self.line_numbers)
|
||||
else:
|
||||
foreground = self.code
|
||||
height = foreground.get_height() + 0.1 * 3 + 2 * self.margin
|
||||
width = foreground.get_width() + 0.1 * 3 + 2 * self.margin
|
||||
height = foreground.height + 0.1 * 3 + 2 * self.margin
|
||||
width = foreground.width + 0.1 * 3 + 2 * self.margin
|
||||
|
||||
rect = RoundedRectangle(
|
||||
corner_radius=self.corner_radius,
|
||||
|
|
@ -262,7 +262,7 @@ class Code(VGroup):
|
|||
)
|
||||
|
||||
self.background_mobject = VGroup(rect, buttons)
|
||||
x = (height - foreground.get_height()) / 2 - 0.1 * 3
|
||||
x = (height - foreground.height) / 2 - 0.1 * 3
|
||||
self.background_mobject.shift(foreground.get_center())
|
||||
self.background_mobject.shift(UP * x)
|
||||
if self.insert_line_no:
|
||||
|
|
|
|||
|
|
@ -84,13 +84,11 @@ class SVGMobject(VMobject):
|
|||
self.file_name = file_name or self.file_name
|
||||
self.ensure_valid_file()
|
||||
self.should_center = should_center
|
||||
self.height = height
|
||||
self.width = width
|
||||
self.unpack_groups = unpack_groups
|
||||
VMobject.__init__(
|
||||
self, fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs
|
||||
)
|
||||
self.move_into_position()
|
||||
self.move_into_position(width, height)
|
||||
|
||||
def ensure_valid_file(self):
|
||||
"""Reads self.file_name and determines whether the given input file_name
|
||||
|
|
@ -504,17 +502,17 @@ class SVGMobject(VMobject):
|
|||
)
|
||||
self.ref_to_element.update(new_refs)
|
||||
|
||||
def move_into_position(self):
|
||||
def move_into_position(self, width, height):
|
||||
"""Uses the SVGMobject's config dictionary to set the Mobject's
|
||||
width, height, and/or center it. Use ``width``, ``height``, and
|
||||
``should_center`` respectively to modify this.
|
||||
"""
|
||||
if self.should_center:
|
||||
self.center()
|
||||
if self.height is not None:
|
||||
self.set_height(self.height)
|
||||
if self.width is not None:
|
||||
self.set_width(self.width)
|
||||
if height is not None:
|
||||
self.height = height
|
||||
if width is not None:
|
||||
self.width = width
|
||||
|
||||
|
||||
class VMobjectFromSVGPathstring(VMobject):
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ class SingleStringMathTex(SVGMobject):
|
|||
background_stroke_color=background_stroke_color,
|
||||
**kwargs,
|
||||
)
|
||||
if self.height is None:
|
||||
if height is None:
|
||||
self.scale(TEX_MOB_SCALE_FACTOR)
|
||||
if self.organize_left_to_right:
|
||||
self.organize_submobjects_left_to_right()
|
||||
|
|
@ -560,16 +560,16 @@ class Title(Tex):
|
|||
self.match_underline_width_to_text = match_underline_width_to_text
|
||||
self.underline_buff = underline_buff
|
||||
Tex.__init__(self, *text_parts, **kwargs)
|
||||
self.underline_width = config["frame_width"] - 2
|
||||
self.scale(self.scale_factor)
|
||||
self.to_edge(UP)
|
||||
if self.include_underline:
|
||||
underline_width = config["frame_width"] - 2
|
||||
underline = Line(LEFT, RIGHT)
|
||||
underline.next_to(self, DOWN, buff=self.underline_buff)
|
||||
if self.match_underline_width_to_text:
|
||||
underline.match_width(self)
|
||||
else:
|
||||
underline.set_width(self.underline_width)
|
||||
underline.width = underline_width
|
||||
self.add(underline)
|
||||
self.underline = underline
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ class CairoText(SVGMobject):
|
|||
if self.t2g:
|
||||
self.set_color_by_t2g()
|
||||
# anti-aliasing
|
||||
if self.height is None and self.width is None:
|
||||
if height is None and width is None:
|
||||
self.scale(TEXT_MOB_SCALE_FACTOR)
|
||||
|
||||
def __repr__(self):
|
||||
|
|
@ -568,7 +568,7 @@ class Paragraph(VGroup):
|
|||
self[line_no].move_to(
|
||||
np.array(
|
||||
[
|
||||
self.get_right()[0] - self[line_no].get_width() / 2,
|
||||
self.get_right()[0] - self[line_no].width / 2,
|
||||
self[line_no].get_center()[1],
|
||||
0,
|
||||
]
|
||||
|
|
@ -578,7 +578,7 @@ class Paragraph(VGroup):
|
|||
self[line_no].move_to(
|
||||
np.array(
|
||||
[
|
||||
self.get_left()[0] + self[line_no].get_width() / 2,
|
||||
self.get_left()[0] + self[line_no].width / 2,
|
||||
self[line_no].get_center()[1],
|
||||
0,
|
||||
]
|
||||
|
|
@ -799,7 +799,7 @@ class Text(SVGMobject):
|
|||
if self.t2g:
|
||||
self.set_color_by_t2g()
|
||||
# anti-aliasing
|
||||
if self.height is None and self.width is None:
|
||||
if height is None and width is None:
|
||||
self.scale(TEXT_MOB_SCALE_FACTOR)
|
||||
|
||||
def __repr__(self):
|
||||
|
|
@ -1252,7 +1252,7 @@ class MarkupText(SVGMobject):
|
|||
*(self._parse_color(grad["from"]), self._parse_color(grad["to"]))
|
||||
)
|
||||
# anti-aliasing
|
||||
if self.height is None and self.width is None:
|
||||
if height is None and width is None:
|
||||
self.scale(TEXT_MOB_SCALE_FACTOR)
|
||||
|
||||
def text2hash(self):
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ class AbstractImageMobject(Mobject):
|
|||
self.center()
|
||||
h, w = self.get_pixel_array().shape[:2]
|
||||
if self.scale_to_resolution:
|
||||
self.height = h / self.scale_to_resolution * config["frame_height"]
|
||||
height = h / self.scale_to_resolution * config["frame_height"]
|
||||
else:
|
||||
self.height = 3 ## this is the case for ImageMobjectFromCamera
|
||||
self.stretch_to_fit_height(self.height)
|
||||
self.stretch_to_fit_width(self.height * w / h)
|
||||
height = 3 ## this is the case for ImageMobjectFromCamera
|
||||
self.stretch_to_fit_height(height)
|
||||
self.stretch_to_fit_width(height * w / h)
|
||||
|
||||
|
||||
class ImageMobject(AbstractImageMobject):
|
||||
|
|
@ -80,7 +80,7 @@ class ImageMobject(AbstractImageMobject):
|
|||
def construct(self):
|
||||
image = ImageMobject(np.uint8([[0, 100, 30, 200],
|
||||
[255, 0, 5, 33]]))
|
||||
image.set_height(7)
|
||||
image.height = 7
|
||||
self.add(image)
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1740,10 +1740,12 @@ class VectorizedPoint(VMobject):
|
|||
)
|
||||
self.set_points(np.array([location]))
|
||||
|
||||
def get_width(self):
|
||||
@VMobject.width.getter
|
||||
def width(self):
|
||||
return self.artificial_width
|
||||
|
||||
def get_height(self):
|
||||
@VMobject.height.getter
|
||||
def height(self):
|
||||
return self.artificial_height
|
||||
|
||||
def get_location(self):
|
||||
|
|
|
|||
|
|
@ -926,22 +926,22 @@ class GraphScene(Scene):
|
|||
group.add(group.df_label)
|
||||
|
||||
if len(labels) > 0:
|
||||
max_width = 0.8 * group.dx_line.get_width()
|
||||
max_height = 0.8 * group.df_line.get_height()
|
||||
if labels.get_width() > max_width:
|
||||
labels.set_width(max_width)
|
||||
if labels.get_height() > max_height:
|
||||
labels.set_height(max_height)
|
||||
max_width = 0.8 * group.dx_line.width
|
||||
max_height = 0.8 * group.df_line.height
|
||||
if labels.width > max_width:
|
||||
labels.width = max_width
|
||||
if labels.height > max_height:
|
||||
labels.height = max_height
|
||||
|
||||
if dx_label is not None:
|
||||
group.dx_label.next_to(
|
||||
group.dx_line, np.sign(dx) * DOWN, buff=group.dx_label.get_height() / 2
|
||||
group.dx_line, np.sign(dx) * DOWN, buff=group.dx_label.height / 2
|
||||
)
|
||||
group.dx_label.set_color(group.dx_line.get_color())
|
||||
|
||||
if df_label is not None:
|
||||
group.df_label.next_to(
|
||||
group.df_line, np.sign(dx) * RIGHT, buff=group.df_label.get_height() / 2
|
||||
group.df_line, np.sign(dx) * RIGHT, buff=group.df_label.height / 2
|
||||
)
|
||||
group.df_label.set_color(group.df_line.get_color())
|
||||
|
||||
|
|
@ -992,7 +992,7 @@ class GraphScene(Scene):
|
|||
Any valid keyword argument of a self.play call.
|
||||
"""
|
||||
triangle = RegularPolygon(n=3, start_angle=np.pi / 2)
|
||||
triangle.set_height(MED_SMALL_BUFF)
|
||||
triangle.height = MED_SMALL_BUFF
|
||||
triangle.move_to(self.coords_to_point(x_val, 0), UP)
|
||||
triangle.set_fill(color, 1)
|
||||
triangle.set_stroke(width=0)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Examples
|
|||
text = Text("Hello World").set_color(BLUE)
|
||||
self.add(text)
|
||||
self.camera_frame.save_state()
|
||||
self.play(self.camera_frame.animate.set_width(text.get_width() * 1.2))
|
||||
self.play(self.camera_frame.animate.set(width=text.width * 1.2))
|
||||
self.wait(0.3)
|
||||
self.play(Restore(self.camera_frame))
|
||||
|
||||
|
|
@ -40,11 +40,11 @@ Examples
|
|||
s = Square(color=BLUE, fill_opacity=0.5).move_to(2 * LEFT)
|
||||
t = Triangle(color=YELLOW, fill_opacity=0.5).move_to(2 * RIGHT)
|
||||
self.add(s, t)
|
||||
self.play(self.camera_frame.animate.move_to(s).set_width(s.get_width()*2))
|
||||
self.play(self.camera_frame.animate.move_to(s).set(width=s.width*2))
|
||||
self.wait(0.3)
|
||||
self.play(self.camera_frame.animate.move_to(t).set_width(t.get_width()*2))
|
||||
self.play(self.camera_frame.animate.move_to(t).set(width=t.width*2))
|
||||
|
||||
self.play(self.camera_frame.animate.move_to(ORIGIN).set_width(14))
|
||||
self.play(self.camera_frame.animate.move_to(ORIGIN).set(width=14))
|
||||
|
||||
.. manim:: MovingCameraOnGraph
|
||||
|
||||
|
|
|
|||
|
|
@ -99,14 +99,14 @@ class SampleSpaceScene(Scene):
|
|||
|
||||
def get_posterior_rectangles(self, buff=MED_LARGE_BUFF):
|
||||
prior_rects = self.get_prior_rectangles()
|
||||
areas = [rect.get_width() * rect.get_height() for rect in prior_rects]
|
||||
areas = [rect.width * rect.height for rect in prior_rects]
|
||||
total_area = sum(areas)
|
||||
total_height = prior_rects.get_height()
|
||||
total_height = prior_rects.height
|
||||
|
||||
post_rects = prior_rects.copy()
|
||||
for rect, area in zip(post_rects, areas):
|
||||
rect.stretch_to_fit_height(total_height * area / total_area)
|
||||
rect.stretch_to_fit_width(area / rect.get_height())
|
||||
rect.stretch_to_fit_width(area / rect.height)
|
||||
post_rects.arrange(DOWN, buff=0)
|
||||
post_rects.next_to(self.sample_space, RIGHT, buff)
|
||||
return post_rects
|
||||
|
|
@ -122,7 +122,7 @@ class SampleSpaceScene(Scene):
|
|||
braces = post_rects.braces
|
||||
labels = post_rects.labels
|
||||
for rect, brace, label in zip(post_rects, braces, labels):
|
||||
brace.stretch_to_fit_height(rect.get_height())
|
||||
brace.stretch_to_fit_height(rect.height)
|
||||
brace.next_to(rect, RIGHT, SMALL_BUFF)
|
||||
label.next_to(brace, RIGHT, SMALL_BUFF)
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,4 @@ class ZoomedScene(MovingCameraScene):
|
|||
float
|
||||
The zoom factor.
|
||||
"""
|
||||
return fdiv(
|
||||
self.zoomed_camera.frame.get_height(), self.zoomed_display.get_height()
|
||||
)
|
||||
return fdiv(self.zoomed_camera.frame.height, self.zoomed_display.height)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ def index_labels(mobject, label_height=0.15):
|
|||
labels = VGroup()
|
||||
for n, submob in enumerate(mobject):
|
||||
label = Integer(n)
|
||||
label.set_height(label_height)
|
||||
label.height = label_height
|
||||
label.move_to(submob)
|
||||
label.set_stroke(BLACK, 5, background=True)
|
||||
labels.add(label)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ def test_simple_animate():
|
|||
s = Square()
|
||||
scale_factor = 2
|
||||
anim = s.animate.scale(scale_factor).build()
|
||||
assert anim.mobject.target.get_width() == scale_factor * s.get_width()
|
||||
assert anim.mobject.target.width == scale_factor * s.width
|
||||
|
||||
|
||||
def test_chained_animate():
|
||||
|
|
@ -20,7 +20,7 @@ def test_chained_animate():
|
|||
direction = np.array((1, 1, 0))
|
||||
anim = s.animate.scale(scale_factor).shift(direction).build()
|
||||
assert (
|
||||
anim.mobject.target.get_width() == scale_factor * s.get_width()
|
||||
anim.mobject.target.width == scale_factor * s.width
|
||||
and (anim.mobject.target.get_center() == direction).all()
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ class WriteStuff(Scene):
|
|||
)
|
||||
group = VGroup(example_text, example_tex)
|
||||
group.arrange(DOWN)
|
||||
group.set_width(config["frame_width"] - 2 * LARGE_BUFF)
|
||||
group.width = config["frame_width"] - 2 * LARGE_BUFF
|
||||
|
||||
self.play(Write(example_text))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue