Allow using :meth:.MovingCamera.auto_zoom without animation (#2693)

* Allow using `MovingCamera.auto_zoom` without animation

* added test for auto_zoom width

* type hints for MovingCamera.auto_zoom

* black

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Mohsin Shaikh 2022-04-23 02:07:52 +05:00 committed by GitHub
commit 584d80242f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 6 deletions

View file

@ -14,6 +14,7 @@ from .. import config
from ..camera.camera import Camera
from ..constants import DOWN, LEFT, ORIGIN, RIGHT, UP
from ..mobject.frame import ScreenRectangle
from ..mobject.mobject import Mobject
from ..mobject.types.vectorized_mobject import VGroup
from ..utils.color import WHITE
@ -175,7 +176,13 @@ class MovingCamera(Camera):
"""
return [self.frame]
def auto_zoom(self, mobjects, margin=0, only_mobjects_in_frame=False):
def auto_zoom(
self,
mobjects: list[Mobject],
margin: float = 0,
only_mobjects_in_frame: bool = False,
animate: bool = True,
):
"""Zooms on to a given array of mobjects (or a singular mobject)
and automatically resizes to frame all the mobjects.
@ -195,11 +202,14 @@ class MovingCamera(Camera):
only_mobjects_in_frame
If set to ``True``, only allows focusing on mobjects that are already in frame.
animate
If set to ``False``, applies the changes instead of returning the corresponding animation
Returns
-------
_AnimationBuilder
Returns an animation that zooms the camera view to a given
list of mobjects.
Union[_AnimationBuilder, ScreenRectangle]
_AnimationBuilder that zooms the camera view to a given list of mobjects
or ScreenRectangle with position and size updated to zoomed position.
"""
scene_critical_x_left = None
@ -242,8 +252,9 @@ class MovingCamera(Camera):
new_width = abs(scene_critical_x_left - scene_critical_x_right)
new_height = abs(scene_critical_y_up - scene_critical_y_down)
m_target = self.frame.animate if animate else self.frame
# zoom to fit all mobjects along the side that has the largest size
if new_width / self.frame.width > new_height / self.frame.height:
return self.frame.animate.set_x(x).set_y(y).set(width=new_width + margin)
return m_target.set_x(x).set_y(y).set(width=new_width + margin)
else:
return self.frame.animate.set_x(x).set_y(y).set(height=new_height + margin)
return m_target.set_x(x).set_y(y).set(height=new_height + margin)

11
tests/test_camera.py Normal file
View file

@ -0,0 +1,11 @@
from __future__ import annotations
from manim import MovingCamera, Square
def test_movingcamera_auto_zoom():
camera = MovingCamera()
square = Square()
margin = 0.5
camera.auto_zoom([square], margin=margin, animate=False)
assert camera.frame.height == square.height + margin