mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Merge with main (#3815)
* fix a typo in deep_dive.rst (#3377) * Several GitHub actions updates (#3397) * Bump docker/login-action from 2 to 3 Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump docker/setup-buildx-action from 2 to 3 Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump docker/build-push-action from 4 to 5 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump docker/setup-qemu-action from 2 to 3 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * rtd: enable htmlzip build (#3355) also, bump python to 3.11 fixes https://github.com/ManimCommunity/manim/issues/3342 * fix(docs): Remove extra curly bracket in LaTeX math expression to fix issue #3330 (#3389) * Bug fix: Use np.isclose for float equality in number line elongated ticks (#3392) * use np.isclose for float equality in number line elongated ticks * use offsets relative to x_min to tell if we need to elongate a tick * forgot to subtract to create list of offsets * add test for elongated ticks float equality * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Remove unused import --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Updated several dependencies (#3399) * updated lockfile * ran poetry update again * pyproject.toml: update manimpango version (#3405) Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Added docs for functions in `mobject_update_utils` (#3325) * Added docs for functions in mobject_update_utils * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated docstring of always_shift Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Added period to sentence. Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Updated parameter description in always_redraw Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update always_rotate description Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Finished parameters in always_redraw Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Changed comment in always_shift Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * update always_shift description Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * used normalize from manim.utils.space_ops * fixed indentation in always_redraw * added type-hints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Fix tests to run on Cairo 1.18.0 (#3416) * Add a script to build and install cairo * Update gui tests for cairo 1.18.0 * update script to set env vars * Make the script run with plain python * Prefer the recently built one in pkg-config * Skip the built if it's windows * CI: build and install latest cairo * CI: only run when cache is missed * Disable compiling tests while building cairo * update poetry lock file * Display the cairo version when running pytest * fixup * tests: skip graphical test when cairo is old * fix the path to find the pkgconfig files on linux * set the LD_LIBRARY_PATH too only then it'll work on linux * fixup * small fixup * Move the script inside `.github/scripts` folder * Make the minimum cairo version a constant * Seperate setting env vars to a sperate step this seem to have broken when cache is hit * Fix: Fixed a bug in regards to empty inputs in AddTextLetterByLetter class. (#3404) * Misc: Just a class to test out some functions * Fix: Fixed a bug in AddTextLetterByLetter class * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix: Adjusted changes according to Ben's comments * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix: Removed imports * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Feat: Adjusted changes to AddTextLetterByLetter * Feat: Added test_creation * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Introduce new workflow creating a downloadable version of the documentation (#3417) * Revert "rtd: enable htmlzip build (#3355)" This reverts commit571f79be2c. * use python3.11 to build docs * upgrade python version used in release publish workflow * new workflow for building downloadable docs * change event trigger for testing * sudo apt * rename release job; build html in poetry env * set GITHUB_PATH instead of PATH * introduce additional step * use correct binary path * forgot microtype * fonts-roboto + actually compress files correctly * fix asset path * Update .github/workflows/release-publish-documentation.yml Co-authored-by: Naveen M K <naveen521kk@gmail.com> * pull_request -> workflow_dispatch * Update .github/workflows/release-publish-documentation.yml --------- Co-authored-by: Naveen M K <naveen521kk@gmail.com> * Fix incorrect submobject count of multi-part Tex/MathTex mobjects by stopping them from adding empty submobjects (#3423) * do not add a VectorizedPoint as a submobject if SingleStringMathTex renders to empty SVG * test new behavior * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update tests/module/mobject/text/test_texmobject.py * Update tests/module/mobject/text/test_texmobject.py --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * CI: fix caching of cairo (#3419) I forgot to change the path after moving around the file. * Fix CSV reader adding empty lists in rendering summary (#3430) * Fix CSV reader adding empty files Fixes issue #3311 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fix None check order in _tree_layout (#3421) * Fix None check order in _tree_layout * add tests to test_graph.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Bump teatimeguest/setup-texlive-action from 2 to 3 (#3431) Bumps [teatimeguest/setup-texlive-action](https://github.com/teatimeguest/setup-texlive-action) from 2 to 3. - [Release notes](https://github.com/teatimeguest/setup-texlive-action/releases) - [Commits](https://github.com/teatimeguest/setup-texlive-action/compare/v2...v3) --- updated-dependencies: - dependency-name: teatimeguest/setup-texlive-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * bump dependencies -- see #3241 (#3433) * Fix Typing (#3086) * first draft of color class + starting library conversion * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * changed everything to Manim color todo: figure out circular dependency in utils * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * first working draft of new color version * resolving conflicts * resolving conflicts * resolving conflicts * resolving conflicts * resolving conflicts * changed default internal value of ManimColor to np.ndarray[float] * starting to fix tests * fixed more tests and changed precision of manim color * removed premature color conversion * fixed some more tests * final test changes * fix doctests * fix for 3.8 * fixing ManimColor string representation * removing some unneccesary conversions * moved community constants to manim_colors.py and added more color standards * Added typing.py and typed bezier.py, core.py, constants.py fully * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixed codeql complaints * add type ignore for np.allclose * fixed import in three_dimensions * added ignore for F401 back again in flake * added typings to coordinate_systems.py * Few improvements to `graphing/coordinate_systems.py` * added some typings to mobject/geometry/line.py * updated typings for mobject/geometry/line.py * Add missing imports to `line.py` * added typings to three_dimensions.py * Use `FunctionOverride` for animation overrides Fix type signature of `set_color_by_gradient` * Remove `TYPE_CHECKING` check Doc is failing * Revert "Remove `TYPE_CHECKING` check" Fails due to circular import * Use `Self` in `coordinate_systems.py` * Typehinted mobject.py and updated manim.typing.py * Typed VMobject * Type-hinted manim.mobject.geometry * math.cos->np.cos, etc & fixed incorrect typehints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix missing annotations import * TypeAlias fix in typing.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add ignore errors again to mypy because commits are not possible like this * Fix last typing issues * Update docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Only type check manim * Try fixing pre-commit * fix merge * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix compat * Fix compat again * Fix imports compat * Use union syntax * Use union syntax * Fix reduce_across_dimension * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Various test and merge fixes * Doc fixes * Last doc fix * Revert usage of np over math * Bump numpy version * Remove obsolete duplicate example * Fixed Incorrect Typehint in manim.constants * Fix docstring typo * More fixes Use mypy.ini instead of .mypy.ini Fix more docstrings Improve types in utils and constants * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * docs fixes * Add internal aliases * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix compat * line lengths in .rst file, formatting, typos * add docstring for space_ops:cross2d * add some more arrow tip typings (in a non-circular import causing way) * yes, this can be deleted * fix formatting of example * added docstring to bezier::inverse_interpolation * added docstring + test for bezier::match_interpolate * some improvements in coordinate_systems * Vector -> Vector3 * replaced np.ndarray with more appropriate type hints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply feedback * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * revert to previous (new) version * fix doctest * fix ReST errors --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Alex Lembcke <alex.lembcke@gmail.com> Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> Co-authored-by: JasonGrace2282 <aarush.deshpande@gmail.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * fix: issue with ImageMobject bounding box (#3340) * fix: fix an issue with ImageMobject bounding box A missing point resulted in smaller bounding box causing issues it to be smaller when the object is rotated. Added the missing fourth point to ImageMobject points and altered call from camera. Filled in docstring that used to propagate from superclass, saying that ImageMobject has no points. * add a test to check that rotating an image to and from doesn't change it * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Václav Blažej <vaclav.blazej@warwick.ac.uk> Co-authored-by: Naveen M K <naveen521kk@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * chore(deps): add Python 3.12 support (#3395) * chore(deps): add Python 3.11 and 3.12 support chore(deps): update lock file chore(deps): remove colour fix(deps): force NumPy version fix(deps): relax constraints chore(deps): update lock file * fix(deps): make poetry happy * fix(ci): skia pathops on 3.12 * fix(test): doctest skip * disable python 3.8 pipeline * removed get_parameters, replaced by direct call to inspect * black --------- Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Added ability to remove non-svg LaTeX files (#3322) * Added ability to remove latex junk (default True) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed tests (hopefully), and whitelisted .tex * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * reverted weird changes from merge * See previous commit message * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed logs-too-long test * Fixed log output * Fixed typo ;) * deleted unused variable * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * moved latex deletion to tex_file_writing.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * removed changes in scene files * Added caching based on LaTeX expression .svg * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Deleted unused function in delete_old_tex * make if condition more readable Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * cleaned up svg file check * changed blacklist -> whitelist for file endings * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Reverted docstring change * Updated delete_non_svg files docstring * Changed list to a set * Update manim/_config/utils.py * Update manim/cli/render/global_options.py * added one test for the no_latex_cleanup config option --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> * feat: DecimalNumber() - added spacing between values and unit (#3366) * feat: DecimalNumber() - added spacing between values and unit * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/text/numbers.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Add option to run examples directly with binder (#3427) * Add option to run examples directly with binder The minified JS is from https://github.com/naveen521kk/manim-binder * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * slight style changes * update the js file to fix on chrome Signed-off-by: Naveen M K <naveen521kk@gmail.com> * show the run button as an cursor * make the video to be 100% of the width * Update manim/utils/docbuild/manim_directive.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Add a "Make interactive" button instead of "Run" button Clicking on the "Make interactive" button show the code-editor and "run" button * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update margin for run interactive button --------- Signed-off-by: Naveen M K <naveen521kk@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Prepare v0.18.0 (#3439) * generated changelog and bumped version * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * changed some PR descriptions in the changelog * fix some docbuild warnings * fixed a reference that became ambiguous * copyedit pass of changelog * some more changelog polishing * bump release date * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updated release date --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fixed wrong path in action building downloadable docs (#3450) * fixed wrong path in action building downloadable docs * fix second occurrence of wrong path * Allow accessing ghost vectors in :class:`.LinearTransformationScene` (#3435) * Fix CSV reader adding empty files Fixes issue #3311 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added LinearTransformationScene.ghost_vectors * Added test and prevented empty VGroups as ghost vectors * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed typo in example * Added ability to join together multiple renders * Revert "Added ability to join together multiple renders" (wrong branch) This reverts commitdee29c390f. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add type hints to `_config` (#3440) * Add type hints to `_config` * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix call issues * Fix wrong value being used * Fix test * Fix wrong value being set * lint * Few type fixes --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fix Idicate docs typo (#3461) * Update indication.py (#3477) reading docs, im sure oppising isnt a word * Optimized `get_unit_normal()` and replaced `np.cross()` with custom `cross()` in `manim.utils.space_ops` (#3494) * Added cross and optimized get_unit_normal in manim.utils.space_ops * Added missing border case to new get_unit_normal where one vector is nonzero * Updated test_threed.py::test_Sphere test data * Update dependency constraints, fix deprecation warnings (#3376) * WIP: Update metadata * Finish removing upper bounds Drop requests dependency, use urllib instead order depencencies * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix issues on 3.12 * Order dev dependencies * Update most dev deps, update lint config * Add missing import * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * trigger CI * More deprecation fixes * Missing argument * Deprecation fixes, again * Use older xdist to fix test flakyness --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix 360° to 180° in quickstart tutorial (#3498) * Update Docker base image to python3.12-slim (#3458) (#3459) * Update Docker base image to python3.12-slim (#3458) * Update docker/Dockerfile --------- Co-authored-by: Melody Griesen <jvgriese@ncsu.edu> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * fix line_join to joint_type in example_scenes/basic.py (#3510) * fix typo in docstring for DtUpdater example: line -> square (#3509) * Implement caching of fonts list to improve runtime performance (#3316) * Implement caching of fonts list to improve runtime performance * Fix small use_svg_cache kwargs error * replaced font list with LRU cache * Removed deprecated new command (#3512) Co-authored-by: Naveen M K <naveen521kk@gmail.com> * Added `cap_style` feature to `VMobject` (#3516) * Added cap_style feature to VMobject * Added an example to `set_cap_style` method * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Unsplitted line 2501 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added graphical test for cap_style * Added vmobject_cap_styles.npz for testing cap_styles * Removed # noqa comments from vectorized_mobject.py --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(cli): optionally hide version splash (#3329) * feat(cli): optionally hide version splash As discussed in #3326, this PR proposes a new optional flag to hide the version splash when manim command in launched. Additionally, the splash print is now inly executed when the CLI is executed, not on module import. After looking at the current documentation, it does not seem to change anything. I only saw that you documented a version splash for when the CLI is used, but not when the module is imported. So removing it should not break the api docs. In the future, users can still have version information with `import manim; print(manim.__version__)`. Closes #3326 * chore(tests): make tests pass --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> * Reformatting the `--save_sections` output to have the format `<Scene>_<SecNum>_<SecName><extension>` (#3499) * Worked on issue 3471, fixing rendered file names to inherit section name * Modified file name to include section number and name * Modified tests for file names to include number and name, in order to pass --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> * Explain ``.Transform`` vs ``.ReplacementTransform`` in quickstart examples (#3500) * Explained ReplacementTransform vs Transform * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added section explaining Transform vs ReplacementTransform * Added a->b->c example * Clarified explanation * Fixed Typo * Fixed missing colon * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> * Fix formatting building blocks (#3515) * Fix formatting building blocks * Fix formatting building blocks --------- Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> * Bump jupyter-server from 2.9.1 to 2.11.2 (#3497) Bumps [jupyter-server](https://github.com/jupyter-server/jupyter_server) from 2.9.1 to 2.11.2. - [Release notes](https://github.com/jupyter-server/jupyter_server/releases) - [Changelog](https://github.com/jupyter-server/jupyter_server/blob/main/CHANGELOG.md) - [Commits](https://github.com/jupyter-server/jupyter_server/compare/v2.9.1...v2.11.2) --- updated-dependencies: - dependency-name: jupyter-server dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Account for dtype in the pixel array so the maximum value stays correct in the invert function (#3493) * fix(lib): fix This fixes an issue where the `invert` argument would only work for `uint8` dtypes. Now the `max` value is updated according to the pixel array dtype. Maybe we should add unit tests for that, but haven't found an obvious place to put unit tests. * chore(ci): add basic test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix(ci): wrong attr name * Update tests/module/mobject/test_image.py --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Added `grid_lines` attribute to `Rectangle` to add individual styling to the grid lines (#3428) * Added 'grid_line_stroke_width' parameter in Rectangle * Added 'grid_lines' (VGroup) attribute to 'Rectangle' class --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> * Fix rectangle grid properties (#3082) (#3513) * Import for both vertical and horizontal gridlines in * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fix animations with zero runtime length to give a useful error instead of a broken pipe (#3491) * Fix animation group not erroring when instantiated with an empty list * Move error messages into Animation.begin() * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update manim/animation/animation.py * Update manim/animation/composition.py * Update manim/animation/animation.py Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> * fixed the stroke width issue with single color in streamlines (#3436) * fixed the stroke width issue with single color in streamlines * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added test for streamlines * Added test for streamlines --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: MrDiver <mrdiverlp@gmail.com> * Add Documentation to `.to_edge` and `to_corner` (#3408) * Added docstrings and example renders to Mobject.to_corner() and Mobject.to_edge * Added docstrings and example renders to Mobject.to_corner() and Mobject.to_edge * Update manim/mobject/mobject.py * Update manim/mobject/mobject.py * Update manim/mobject/mobject.py * Update manim/mobject/mobject.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update manim/mobject/mobject.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Adding the ability to pass lists and generators to .play() (#3365) * adding the ability to pass lists and generators to .play() * fix for _AnimationBuilder * Changed handling of generators to accept lists of generators and normal arguments at the same time * Animation group handles generators * Refactored into own function for reusability * Fix typing * Fix typing --------- Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> * follow-up to #3491, made errors more consistent. fixes #3527 * chore(docs): add some words about Cairo 1.18 (#3530) * chore(docs): add some words about Cairo 1.18 Closes #3521 * fix(docs): typo * Update testing.rst * Update testing.rst * Fix formatting of ``MoveAlongPath`` docs (#3541) * Remove wag method from Mobject * Fixed MoveAlongPath * Revert remove wag Created a new branch with the wrong base, sorry ;) * Fixed Animate Type-hint (#3543) * Remove wag method from Mobject (#3539) Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> * Fix typo of `get_y_axis_label` docstring (#3547) * Finish TODO's in ``contributing/typings.rst`` (#3545) * Updated typing docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added link for protocols * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added object vs Any * Fix Typo * Rephrase TypeVar Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * Compare between tuple vs list Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * typing -> collections.abc Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * typing -> collections.abc Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * change method to attr Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * clarify object typehint Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * Fix code typo Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * Added if TYPE_CHECKING section * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix reST for inline code * Elaborate on if TYPE_CHECKING Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * functions -> collections Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> * Fix use of `Mobject`'s deprecated `get_*()` and `set_*()` methods in Cairo tests (#3549) * Fix Deprecation warnings in cairo tests * Fix animation/specialized.py * add note in docstring of ManimColor about class constructors (#3554) * Added support for Manim type aliases in Sphinx docs + Added new TypeAliases (#3484) * Updated manim.typing and included TypeAliases in docs.source.conf * Added Vector2 and reorganized manim_type_aliases * Fixed __all__ exports for __all__ of manim * Update manim/cli/render/global_options.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Draft of new typing docs and new autotyping directive * Changed vertical bars to Unions * Updated poetry.lock * Created custom file parser for manim.typing * Got reST parser going * Updated autotyping and parsing * Update parsing * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added code_block toggle * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added typings to directives * Renamed Tuple to tuple in manim.typings * Added missing docs for type aliases * Fixed exponent typo in ManimInt * Hyperlinks to types work - removed Module Attributes section * Removed Unused Import Remove ``import re`` * Added freeglut-devel to workflows for Linux Hopefully (?) fix the GLU import error * Fix package name * Add support for Type Aliases section in every module - Renaming of Vector types * Add/fix docs for directive, parser and others * Fixed alias typo in module_parsing * Fix decode/import bugs, fix minor details in docs * Added missing docs for utils.docbuild and utils.testing * Sort alphabetically entries in utilities_misc.rst * Address review comments, add notes about Vector and hyperlinks inside definition blocks --------- Co-authored-by: MrDiver <mrdiverlp@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: JasonGrace2282 <aarush.deshpande@gmail.com> * Improve documentation section about contributing to docs (#3555) * Improve section in docs about contributing to docs * Add note about doc build command depending on the OS * Improve section in docs about contributing to docs * Add note about doc build command depending on the OS * Fix wrong toctree path in docs/source/contributing/docs.rst * Add helpful hints to `VGroup.add()` error message (#3561) * Improve VGroup creation error message * Use .__name__ for the type Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> --------- Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> * exception add if new_rings is none (#3574) * exception add if new_rings is none * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fix typing of `Animation` (#3568) * Add 'to be used in the future' TODOs to ManimFrame (#3553) * Refactor `TexTemplate` (#3520) * Refactor `TexTemplate` * Add tests, refactor some things * Fixed Some tests * Move typing imports * Fix remaining tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: JasonGrace2282 <aarush.deshpande@gmail.com> Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Bump github/codeql-action from 2 to 3 (#3567) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump actions/upload-artifact from 3 to 4 (#3566) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump actions/setup-python from 4 to 5 (#3565) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * updated several packages (pillow, jupyterlab, notebook, jupyterlab-lsp, jinja2, gitpython) (#3593) * Removed -s / --save_last_frame flag from CLI arguments (#3528) * Remove -s flag * Make help text more verbose * fix write_subcaption_file error when using opengl renderer (#3546) * fix write_subcaption_file error when using opengl renderer * Update manim/scene/scene_file_writer.py --------- Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update docker.rst to use bash from the PATH (#3582) * fix typo in value_tracker.py (#3594) * fix `get_arc_center()` returning reference of point (#3599) * Add ref_class (#3598) * Fix typehint (#3592) * Update ci.yml (#3611) * fix type hint of indication.py (#3613) * Revert vector type aliases to NumPy ndarrays (#3595) * Improve handling of specified font name (#3429) Co-authored-by: Jason Grace <110117391+JasonGrace2282@users.noreply.github.com> Co-authored-by: JasonGrace2282 <aarush.deshpande@gmail.com> The proposed fix does two things : * If the specified font is 'sans-serif' : change it to 'sans' as this is the name used in the list of fonts * if the font name is not in the list of fonts, automatically check if the capitalized version of the font exists in the list of fonts. If not, print a warning to the user. * Remove support for dynamic plugin imports (#3524) * Remove call to deprecated `pkg_resources` * Remove support for dynamic plugin imports, update plugin utilities * fix affected tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * more fixes * Last fix * Fix import * Update docs --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jason Villanueva <a@jsonvillanueva.com> * Run poetry lock --no-update (#3621) * Update jupyter.rst (#3630) Pinpoint IPython==8.21.0 for Google Colab, because more recent versions are incompatible with their runtime. * Fix Vector3 -> Vector3D in contributing docs (#3639) * Bump black from 23.12.1 to 24.3.0 (#3649) Bumps [black](https://github.com/psf/black) from 23.12.1 to 24.3.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.12.1...24.3.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump cryptography from 42.0.0 to 42.0.4 (#3629) Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.0 to 42.0.4. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/42.0.0...42.0.4) --- updated-dependencies: - dependency-name: cryptography dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Code Cleanup: removing unused imports and global variables (#3620) * Remove unused import * More security fixes * Remove unused global variable * More fixes * Revert change (actual fix would require some rewrite) * Add exception for edge case to satisfy warning * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Stuff * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fixing the behavior of `.become` to not modify target mobject via side effects fix color linking (#3508) * Copied ndarray for rgbas when interpolating * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * changing .become to copy the target mobject * change tests and test data to reflect .become new behavior * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update tests/test_graphical_units/test_mobjects.py * removed unused copy_submobject kwarg * added doctests and improved documentation * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Added some examples for `Mobject`/`VMobject` methods (#3641) * Add examples to mobject+vmobject methods * Add missing import * Separate whitespace to point_from_proportion * Fixes! * Changed example of Mobject.get_color * Remove unneccessary import * Add in import * Fix typehint of `Vector` direction parameter (#3640) * Fix typehint of Vector * Change from Vector to Point in typehint In `TipableVMobject._pointify` it converts a 3D list of the form [x, y, z] to a Vector3D. Therefore the direction parameter can take lists, not just numpy arrays. * Fix bug in :class:`.VMobjectFromSVGPath` (#3677) * Fixes #3676 * Update manim/mobject/svg/svg_mobject.py Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Fixed problem and added test --------- Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Flake8 rule C901 is about McCabe code complexity (#3673) * Flake8 rule C901 is about McCabe code complexity It is not about flake8-comprehensions. * max-complexity = 29 * Fix broken link to Poetry's installation guide in the first time contributors page (#3692) * Fix minor grammatical errors found in the index page of the documentation (#3690) * Fix some minor grammatical errors in the index page of the docs * Fix grammar * Undo uneccessary change in phrasing * fix(LICENSE): update year (#3689) * Remove deprecated parameters and animations (#3688) * Remove deprecated parameters/animations * Remove test * Remove test data * Attempted fix for windows cp1252 encoding failure (#3687) * Attempt to fix windows test * Revert "Attempt to fix windows test" This reverts commite31c2077cd. * try a different fix * maybe both fixes together? * try adding in CI * Update ci.yml * Update logger_utils.py * maybe needs a dash? * try utf8 again * Remove legacy_windows * try changing test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Try decoding after capturing bytes output * Nicer fix * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix typo (#3696) * Docs: fix out-dated CLI option in Manim's Output Settings (#3674) * Docs: fix out-dated CLI option in Manim's Output Settings * Docs: more fluent English Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Docs: break lines * Docs: more fluent English * Docs: remove a space Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> --------- Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * only do actions if try succeeded (#3694) * Mention pixi in installation guide (#3678) * Mention pixi in installation guide * Update docs/source/installation/conda.rst Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Add note --------- Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Fix successive calls of :meth:`.LinearTransformationScene.apply_matrix` (#3675) * docs: improve installation FAQ's * I have potentially resolved the issue when in LinearTransformationScene between two animations of transforming space we invoke the self.wait() * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * added another solutions in comments, added tests and removed wrong files from git * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * yeah , i forgot to save the file xd * fixed the test, removed the comments my in changed file * fix test and speed up test time for test_apply_matrix * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixed the test, removed the comments my in changed file * fixed the test * Revert "docs: improve installation FAQ's" This reverts commite53a1c8d6f. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: JasonGrace2282 <aarush.deshpande@gmail.com> Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Bump actions/cache from 3 to 4 (#3607) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Bump FedericoCarboni/setup-ffmpeg from 2 to 3 (#3608) Bumps [FedericoCarboni/setup-ffmpeg](https://github.com/federicocarboni/setup-ffmpeg) from 2 to 3. - [Release notes](https://github.com/federicocarboni/setup-ffmpeg/releases) - [Commits](https://github.com/federicocarboni/setup-ffmpeg/compare/v2...v3) --- updated-dependencies: - dependency-name: FedericoCarboni/setup-ffmpeg dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump ssciwr/setup-mesa-dist-win from 1 to 2 (#3609) Bumps [ssciwr/setup-mesa-dist-win](https://github.com/ssciwr/setup-mesa-dist-win) from 1 to 2. - [Release notes](https://github.com/ssciwr/setup-mesa-dist-win/releases) - [Commits](https://github.com/ssciwr/setup-mesa-dist-win/compare/v1...v2) --- updated-dependencies: - dependency-name: ssciwr/setup-mesa-dist-win dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: update typing guidelines (#3704) * Update typing guidelines * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix formatting * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update documentation and typings for `ParametricFunction` (#3703) * Update documentation and typings for ParametricFunction * Use manim tyings Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * fix typings * a few doc fixes * Update manim/mobject/graphing/functions.py Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update typings * remove extraneous line * update example code * add line back for comptibility * import TYPE_CHECKING --------- Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix(copyright): automate copyright updating for docs (#3708) * Fix some typehints in mobject.py (#3668) * refactor(mobject): fix some typehints * Move typing_extensions import under `if TYPE_CHECKING` * Change from using `def animate(self: T ,...) -> T` to `def animate(self, ...) -> Self` as stated in PEP 673 * Fix incorrect usage of `T` in a method * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * move updaters type alias into TYPE_CHECKING * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Bump idna from 3.6 to 3.7 (#3693) Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7) --- updated-dependencies: - dependency-name: idna dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump pillow from 10.2.0 to 10.3.0 (#3672) Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/10.2.0...10.3.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix typo (#3721) * Fixed `Mobject.put_start_and_end_on` with same start and end point (#3718) * fix put_start_and_end_on() at the same point * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#3332) * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.6.0) - [github.com/pycqa/isort: 5.12.0 → 5.13.2](https://github.com/pycqa/isort/compare/5.12.0...5.13.2) - [github.com/asottile/pyupgrade: v3.10.1 → v3.15.2](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.15.2) - [github.com/psf/black: 23.7.0 → 24.4.0](https://github.com/psf/black/compare/23.7.0...24.4.0) - [github.com/asottile/blacken-docs: 1.15.0 → 1.16.0](https://github.com/asottile/blacken-docs/compare/1.15.0...1.16.0) - [github.com/PyCQA/flake8: 6.1.0 → 7.0.0](https://github.com/PyCQA/flake8/compare/6.1.0...7.0.0) - [github.com/pre-commit/mirrors-mypy: v1.5.1 → v1.9.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.1...v1.9.0) - [github.com/codespell-project/codespell: v2.2.5 → v2.2.6](https://github.com/codespell-project/codespell/compare/v2.2.5...v2.2.6) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * make smoothererstep readable again, avoid overlong line * zoom_value more readable * fix blacken-docs touching .github * fix codespell setup, remove unnecessary file, fix some typos * flake8: ignore E704, triggered by overload * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update docs/source/tutorials/quickstart.rst * more flake fixes * try to make blacken-docs happy --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * fix(autoaliasattr): search for type aliases under if TYPE_CHECKING (#3671) * build(deps): read-the-docs sphinx (#3720) * Fix issue where SpiralIn doesn't show elements. (#3589) * Set SpiralIn to use fill_opacity 1 if not set * Create SpiralIn control data * Create test for SpiralIn * Fix spiralin to separate fill and stroke opacity * resolve opacity issue * fix test data --------- Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Clean Graph layouts and increase flexibility (#3434) * allow user-defined layout functions for Graph + fixup type annotations * only pass relevant args * write tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * change_layout forward root_vertex and partitions - deduplicated layout code in __init__ and change_layout - fixed change_layout backwards compatibility * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add test for change_layout * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix copy/paste error * fix * fixup types for CodeQL * static type the Layout Names * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix dynamic union type for Python 3.9 * add example scenes to LayoutFunction protocol documentation * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Replace references to np.ndarray with standard Manim types * Label NxGraph as a TypeAlias * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Follow-up to graph layout cleanup: improvements for tests and typing (#3728) * suggestions from review on #3434 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Update coordinate_systems.py (#3730) small change * build(ci): change from macos-latest to macos-13 (#3729) * Add ``--preview_command`` cli flag (#3615) * Add preview_command cli flag * Edit help for --preview_command * Change back from subprocess.run * Remove old comment * Bug with timg stopped happening with sp.run * Fix docstring * Revert "Fix docstring" This reverts commit d2c00fc24dc46586f994237f1d2758528b78d6a3. * Actually fix docstring * Change help for option Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> --------- Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * AnimationGroup: optimized interpolate() and fixed alpha bug on finish() (#3542) * Optimized AnimationGroup computation of start-end times with lag ratio * Added extra comment for init_run_time * Added full path to imports in composition.py * Optimized AnimationGroup.interpolate * Fixed final bugs * Removed accidental print * Final fix to AnimationGroup.interpolate * Fixed animations being skipped unintentionally * Addressed requested changes --------- Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Fixed ```get_anchors()``` Return Type Inconsistency (#3214) * changed return type of get_anchors() * Ensured consistency with OpenGLVMobject * Fixed CodeQl, updated docstring * Update manim/mobject/types/vectorized_mobject.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * Update manim/mobject/opengl/opengl_vectorized_mobject.py Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> * fixed typo, t -> e * fixed doctest --------- Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> * fixed [""] being set as loaded plugins (#3734) * Prepare new release: v0.18.1 (#3719) * add note about changelog in changelog.rst * bump version * Update CITATION.cff * feat: Add three animations that together simulate a typing animation (#3612) * feat: Add animations that together simulate typing AddTextLetterByLetterWithCursor RemoveTextLetterByLetterWithCursor Blink * Revert "feat: Add animations that together simulate typing" This reverts commit5fe256880d. * Revert "Revert "feat: Add animations that together simulate typing"" This reverts commit6a8244a157. * Add new animations to __all__ * Temporarily remove docs example * Modify "Blink" and add docstring examples back in To avoid 0-second animations, which fail docstring test * Address requested changes Fix imports Remove redundant constructor arguments Improve names * Shorten names * Fix release documentation building (#3737) * [pre-commit.ci] pre-commit autoupdate (#3739) updates: - [github.com/psf/black: 24.4.0 → 24.4.2](https://github.com/psf/black/compare/24.4.0...24.4.2) - [github.com/pre-commit/mirrors-mypy: v1.9.0 → v1.10.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.9.0...v1.10.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Fixes #3744 (#3745) Co-authored-by: Andrzej Nagórko <> * Bump tqdm from 4.66.1 to 4.66.3 (#3746) Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.1 to 4.66.3. - [Release notes](https://github.com/tqdm/tqdm/releases) - [Commits](https://github.com/tqdm/tqdm/compare/v4.66.1...v4.66.3) --- updated-dependencies: - dependency-name: tqdm dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump jinja2 from 3.1.3 to 3.1.4 (#3750) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4) --- updated-dependencies: - dependency-name: jinja2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add typehints to `manim.utils.iterables` (#3751) * typehint iterables * organize typing hints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove any * Add overloads for tuplify * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Remove example * feedback * Make TypeVars accessible at runtime * Add hints for zip Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * typing -> collections.abc Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * try to make mypy happy * zip[tuple[T, ...]] instead of zip[T] --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * Let `SceneFileWriter` access `ffmpeg` via `av` instead of via external process (#3501) * added av as a dependency * make partial movie files use av instead of piping to external ffmpeg * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * opengl rendering: use av for movie files * no need to check for ffmpeg executable * refactor: *_movie_pipe -> *_partial_movie_stream * improve (oneline) documentation * pass more options to partial movie file rendering * move ffmpeg verbosity settings to config; renamed option dict * replaced call to ffmpeg in combine_files by using av Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * there was one examples saved as a gif? * chore(deps): re-order av * chore(lib): simplify `write_frame` method Reduces the overall code complexity * chore(lib): add audio * fix(lib): same issue for conversion * fix(lib): webm export * fix(lib): transparent export Though the output video is weird * try(lib): fix gif + TODOs * chore(deps): lower dep crit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * feat(lib): add support for GIF * fix(ci): rewrite tests * fix * chore(ci): prevent calling concat on empty list * add missing dot * fix(ci): update frame comparison ? * fix(log): add handler to libav logger * chore: add TODO * fix(lib): concat issue * Revert "fix(ci): update frame comparison ?" This reverts commit904cfb46ae. * fix(ci): make it pass tests * chore(lib/docs/ci): remove FFMPEG entirely This removes any reference to FFMPEG, except in translation files * added av as a dependency * make partial movie files use av instead of piping to external ffmpeg * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * opengl rendering: use av for movie files * no need to check for ffmpeg executable * refactor: *_movie_pipe -> *_partial_movie_stream * improve (oneline) documentation * pass more options to partial movie file rendering * move ffmpeg verbosity settings to config; renamed option dict * replaced call to ffmpeg in combine_files by using av Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * there was one examples saved as a gif? * chore(deps): re-order av * chore(lib): simplify `write_frame` method Reduces the overall code complexity * chore(lib): add audio * fix(lib): same issue for conversion * fix(lib): webm export * fix(lib): transparent export Though the output video is weird * try(lib): fix gif + TODOs * chore(deps): lower dep crit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * feat(lib): add support for GIF * fix(ci): rewrite tests * fix * chore(ci): prevent calling concat on empty list * add missing dot * fix(ci): update frame comparison ? * fix(log): add handler to libav logger * chore: add TODO * fix(lib): concat issue * Revert "fix(ci): update frame comparison ?" This reverts commit904cfb46ae. * fix(ci): make it pass tests * chore(lib/docs/ci): remove FFMPEG entirely This removes any reference to FFMPEG, except in translation files * chore(deps): update lockfile * chore(lib): rewrite ffprobe * fix typo * slightly more aggressive removal of ffmpeg in docs; minor language changes * fix gif output stream dimensions * minor style change * fix encoding of (transparent) mov files * fixed metadata / comment * set frame rate for --format=gif in output_stream * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * more video tests for different render settings, also test pix_fmt * improve default bitrate setting via crf * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * parametrized format/transparency rendering test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * context managers for (some) av.open * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update manim/utils/commands.py Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> * fixed segfault * update test data involving implicit functions (output improved!) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * explicity set pix_fmt for transparent webms * special-special case extracting frame from vp9-encoded file with transparency * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix transparent gifs, more special casing in parametrized video format test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * run tests on macos-latest again * removed old control data * Revert "run tests on macos-latest again" This reverts commitf50efa4b88. * added sound to codec test; fixed issue with sound track in gif (disabled) and webm (now via opus) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * manual wav -> ogg transcoding * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixed f-string * refactored codec test, split out gif * check for non-zero audio samples * more cleanup * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove ffmpeg from readthedocs apt_packages * round up run_time if positive and shorter than current frame rate * added more run_time tests * black * improve implementation of test * removed some unused imports * improve wording of logged warning Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> * move run_time checks from Animation.begin to Scene.get_run_time * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove unused import * flake: PT012 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> * Use --py39-plus in pre-commit (#3761) * Use --py39-plus in pre-commit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix indication.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Optimized `manim.utils.bezier.is_closed()` (#3768) * Optimized manim.utils.bezier.is_closed() * oops, that shouldn't have been there * Slightly optimized is_closed() even more * Added doctest for is_closed() * Created and optimized Bézier splitting functions such as `partial_bezier_points()` in `manim.utils.bezier` (#3766) * Optimized manim.utils.partial_bezier_points() * Added split_bezier, subdivide_bezier and bezier_remap, and tests * Use bezier_remap() in VMobject and OpenGLVMobject() * Note that partial_bezier_points is similar to calling split_bezier twice * Bump requests to 2.32.0 (#3776) updated-dependencies: - dependency-name: requests dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix assertions and improve error messages when adding submobjects (#3756) * Optimized AnimationGroup computation of start-end times with lag ratio * Added extra comment for init_run_time * Added full path to imports in composition.py * Optimized AnimationGroup.interpolate * Fixed final bugs * Removed accidental print * Final fix to AnimationGroup.interpolate * Fixed animations being skipped unintentionally * Fix and improve Mobject assertions when adding submobjects * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update examples in Mobject.add() and OpenGLMobject.add() docstrings * overriden -> overridden * Joined string in OpenGLMobject error message * Address requested changes * OpenGLVMObjects -> OpenGLVMobjects * Use tuplify in VGroup.__setitem__() --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add pyproject for ruff formatting (#3777) * Add pyproject for ruff * add black config back * Make only formatting * rearrange isort to undo diff * poetry lock * Feedback * style Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> --------- Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * pre-commit change to ruff (#3779) * pre-commit change to ruff * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixes * astral-sh ruff bump --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Ignore Ruff format in git blame (#3781) * Fixed `there_and_back_with_pause()` rate function behaviour with different `pause_ratio` values (#3778) Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> * Optimize VMobject methods which append to points (#3765) * Add `@` shorthand for `CoordinateSystem` methods `coords_to_point` (`c2p`) and `point_to_coords` (`p2c`) (#3754) * Add shorthand for axes * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add spacing Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * Convert CoordinateSystem example, and add to NumberLine * Add doctest for NumberLine * Add test * Fix typehint for c2p Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#3784) * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.4 → v0.4.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.4...v0.4.5) - [github.com/codespell-project/codespell: v2.2.6 → v2.3.0](https://github.com/codespell-project/codespell/compare/v2.2.6...v2.3.0) * Fix typo --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: JasonGrace2282 <aarush.deshpande@gmail.com> * [pre-commit.ci] pre-commit autoupdate (#3794) updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.5 → v0.4.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.5...v0.4.7) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add Ruff Lint (#3780) Adds Ruff Linting to CI, and replaces isort in the pre-commit config with Ruff's isort rules. Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * Replace Pyupgrade with Ruff rule (#3795) * Add config for pyupgrade * Fix pyupgrade errors * Unsafe-fixes * Nicer way of formatting Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Revert "Nicer way of formatting" This reverts commit48013f4a30. --------- Co-authored-by: Victorien <65306057+Viicos@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Bump tornado from 6.4 to 6.4.1 (#3796) Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4 to 6.4.1. - [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst) - [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.0...v6.4.1) --- updated-dependencies: - dependency-name: tornado dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update opengl_vectorized_mobject.py (#3790) The "insert_n_curves_to_point_list" function requires the "points" argument to be a numpy array, since it calls the "get_bezier_tuples_from_points" function, which requires "points" to be a numpy array because it has the "return points.reshape((-1, nppc, 3))" statement. Ordinary lists do not have a "reshape" method. So we need to convert "sp1" and "sp2" to numpy arrays before calling the "insert_n_curves_to_point_list" function. Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#3801) updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.7 → v0.4.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.7...v0.4.8) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add typings to `OpenGLMobject` (#3803) * Add typings to OpenGLMobject * Import typing_extensions * Add explicit returns to inner functions in .arrange_in_grid() * Add quotes to parameters in ValueError * Add some more typings * Address requested changes * Type apply_over_attr_arrays with TypeVar * Fix use of TypeVar * Add Vector3D typing in set_x, set_y and set_z * fix: importing manim should not trigger pygments.styles.get_all_styles (#3797) * fix: importing manim should not trigger pygments.styles.get_all_styles Removed the Code.styles_list attribute. Rewrote the documentation to say that a list of all styles can be generated by calling list(pygments.styles.get_all_styles()). The example in the docstring of Code was rewritten to use an explicit code style name. * fix: small change to documentation * Added potential class method to get available code styles. * Adding typehints to newly-added attributes. Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * Removing unnecessary lines. Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> --------- Co-authored-by: adeshpande <110117391+JasonGrace2282@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#3809) updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.8 → v0.4.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.8...v0.4.9) - [github.com/PyCQA/flake8: 7.0.0 → 7.1.0](https://github.com/PyCQA/flake8/compare/7.0.0...7.1.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Bump urllib3 from 2.2.1 to 2.2.2 (#3810) Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.1 to 2.2.2. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2) --- updated-dependencies: - dependency-name: urllib3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update macos packages (#3812) * Fixed infinite loop in OpenGL `BackgroundRectangle.get_color()` (#3732) Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> * Some fixes for interpolation --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Naveen M K <naveen521kk@gmail.com> Co-authored-by: Holly and Prosper <45610532+rongpenl@users.noreply.github.com> Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Naveen M K <naveen521kk@gmail.com> Co-authored-by: Anousheh Moonen <141789878+u7481690@users.noreply.github.com> Co-authored-by: Narahari Rao <narahari387@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Immanuel-Alvaro-Bhirawa <127812163+Immanuel-Alvaro-Bhirawa@users.noreply.github.com> Co-authored-by: Nikhil Iyer <iyer.h.nikhil@gmail.com> Co-authored-by: Harald Schilly <harald.schilly@gmail.com> Co-authored-by: Tristan Schulz <mrdiverlp@gmail.com> Co-authored-by: Alex Lembcke <alex.lembcke@gmail.com> Co-authored-by: Viicos <65306057+Viicos@users.noreply.github.com> Co-authored-by: Václav Blažej <6208643+vaclavblazej@users.noreply.github.com> Co-authored-by: Václav Blažej <vaclav.blazej@warwick.ac.uk> Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> Co-authored-by: Uwe Zimmermann <uwe.zimmermann@sciencetronics.com> Co-authored-by: Lawrence Qupty <80665382+Lawqup@users.noreply.github.com> Co-authored-by: JosephD <46393716+jcep@users.noreply.github.com> Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com> Co-authored-by: szchixy <szchixy@outlook.com> Co-authored-by: Melody Griesen <pikablue107@gmail.com> Co-authored-by: Melody Griesen <jvgriese@ncsu.edu> Co-authored-by: yuan <yuan_xin_yu@hotmail.com> Co-authored-by: Benjamín Ubilla <118409119+MathItYT@users.noreply.github.com> Co-authored-by: Doaa Muhammad <126016494+doaamuham@users.noreply.github.com> Co-authored-by: Robin Dimasin <robindimasin@gmail.com> Co-authored-by: Paul Uhlenbruck <48606747+pauluhlenbruck@users.noreply.github.com> Co-authored-by: Yash Mundada <F20210001@pilani.bits-pilani.ac.in> Co-authored-by: TheMathematicFanatic <63360493+TheMathematicFanatic@users.noreply.github.com> Co-authored-by: Václav Volhejn <8401624+vvolhejn@users.noreply.github.com> Co-authored-by: Hydromel Victor Doledji <victorvaddely@gmail.com> Co-authored-by: Dan Davison <dandavison7@gmail.com> Co-authored-by: Greg Rupp <gmrupp@gmail.com> Co-authored-by: NotWearingPants <26556598+NotWearingPants@users.noreply.github.com> Co-authored-by: Sparsh Goenka <43041139+sparshg@users.noreply.github.com> Co-authored-by: Said Taghadouini <84044788+staghado@users.noreply.github.com> Co-authored-by: Jason Villanueva <a@jsonvillanueva.com> Co-authored-by: Abulafia <44573666+abul4fia@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: Chin Zhe Ning <108804868+biinnnggggg@users.noreply.github.com> Co-authored-by: HairlessVillager <64526732+HairlessVillager@users.noreply.github.com> Co-authored-by: Pavel Zwerschke <pavelzw@gmail.com> Co-authored-by: Sir James Clark Maxwell <71722499+SirJamesClarkMaxwell@users.noreply.github.com> Co-authored-by: Daniel Zhu <danielfangzhu@gmail.com> Co-authored-by: Stefano Ottolenghi <stejey@gmail.com> Co-authored-by: MontroyJosh <122334909+MontroyJosh@users.noreply.github.com> Co-authored-by: Greg Rupp <greg.rupp@66degrees.com> Co-authored-by: Amirreza A <45117218+amrear@users.noreply.github.com> Co-authored-by: Jinchu Li <63861808+JinchuLi2002@users.noreply.github.com> Co-authored-by: VPC <111203113+VinhPhmCng@users.noreply.github.com> Co-authored-by: anagorko <3418166+anagorko@users.noreply.github.com> Co-authored-by: jkjkil4 <52841865+jkjkil4@users.noreply.github.com> Co-authored-by: yang-tsao <caoyang2005@outlook.com> Co-authored-by: Eddie Ruiz <eduardo.j.ruiz@gmail.com> Co-authored-by: Cameron Burdgick <156892808+camburd2@users.noreply.github.com>
This commit is contained in:
parent
e550c5586c
commit
08264dcf76
489 changed files with 12155 additions and 6699 deletions
|
|
@ -1 +0,0 @@
|
|||
<path id="nd" d="m 464.7,68.6 -1.1,2.8 .8,1.4 -.3,5.1 -.5,1.1 2.7,9.1 1.3,2.5 .7,14 1,2.7 -.4,5.8 2.9,7.4 .3,5.8 -.1,2.1 -29.5,-.4 -46,-2.1 -39.2,-2.9 5.2,-66.7 44.5,3.4 55.3,1.6 z">
|
||||
5
.codespell_ignorewords
Normal file
5
.codespell_ignorewords
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
nam
|
||||
sherif
|
||||
falsy
|
||||
medias
|
||||
strager
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[codespell]
|
||||
exclude-file=.codespell_ignorelines
|
||||
check-hidden=True
|
||||
ignore-words-list = nam,sherif,falsy
|
||||
check-hidden = True
|
||||
skip = .git,*.js,*.js.map,*.css,*.css.map,*.html,*.po,*.pot,poetry.lock,*.log,*.svg
|
||||
ignore-words = .codespell_ignorewords
|
||||
|
|
|
|||
15
.flake8
15
.flake8
|
|
@ -1,7 +1,8 @@
|
|||
[flake8]
|
||||
# Exclude the grpc generated code
|
||||
exclude = ./manim/grpc/gen/*
|
||||
max-complexity = 15
|
||||
exclude = ./manim/grpc/gen/*, __pycache__,.git,
|
||||
per-file-ignores = __init__.py:F401
|
||||
max-complexity = 29
|
||||
max-line-length = 88
|
||||
statistics = True
|
||||
# Prevents some flake8-rst-docstrings errors
|
||||
|
|
@ -9,7 +10,7 @@ rst-roles = attr,class,func,meth,mod,obj,ref,doc,exc
|
|||
rst-directives = manim, SEEALSO, seealso
|
||||
docstring-convention=numpy
|
||||
|
||||
select = A,A00,B,B9,C4,C90,D,E,F,F,PT,RST,SIM,W
|
||||
select = A,A00,B,B9,C4,C90,D,E,F,F,PT,RST,SIM,W,F401
|
||||
|
||||
# General Compatibility
|
||||
extend-ignore = E203, W503, D202, D212, D213, D404
|
||||
|
|
@ -17,6 +18,9 @@ extend-ignore = E203, W503, D202, D212, D213, D404
|
|||
# Misc
|
||||
F401, F403, F405, F841, E501, E731, E402, F811, F821,
|
||||
|
||||
# multiple statements on one line (overload)
|
||||
E704,
|
||||
|
||||
# Plug-in: flake8-builtins
|
||||
A001, A002, A003,
|
||||
|
||||
|
|
@ -26,9 +30,6 @@ extend-ignore = E203, W503, D202, D212, D213, D404
|
|||
# Plug-in: flake8-simplify
|
||||
SIM105, SIM106, SIM119,
|
||||
|
||||
# Plug-in: flake8-comprehensions
|
||||
C901
|
||||
|
||||
# Plug-in: flake8-pytest-style
|
||||
PT001, PT004, PT006, PT011, PT018, PT022, PT023,
|
||||
|
||||
|
|
@ -40,4 +41,4 @@ extend-ignore = E203, W503, D202, D212, D213, D404
|
|||
|
||||
# Plug-in: flake8-rst-docstrings
|
||||
RST201, RST203, RST210, RST212, RST213, RST215,
|
||||
RST301, RST303,
|
||||
RST301, RST303, RST499
|
||||
|
|
|
|||
2
.git-blame-ignore-revs
Normal file
2
.git-blame-ignore-revs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Switched to ruff format:
|
||||
24025b60d57301b0a59754c38d77bccd8ed69feb
|
||||
9
.github/ISSUE_TEMPLATE/bug_report.md
vendored
9
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -70,14 +70,5 @@ PASTE HERE
|
|||
<!-- output of `tlmgr list --only-installed` for TeX Live or a screenshot of the Packages page for MikTeX -->
|
||||
</details>
|
||||
|
||||
<details><summary>FFMPEG</summary>
|
||||
|
||||
Output of `ffmpeg -version`:
|
||||
|
||||
```
|
||||
PASTE HERE
|
||||
```
|
||||
</details>
|
||||
|
||||
## Additional comments
|
||||
<!-- Add further context that you think might be relevant for this issue here. -->
|
||||
|
|
|
|||
9
.github/ISSUE_TEMPLATE/installation_issue.md
vendored
9
.github/ISSUE_TEMPLATE/installation_issue.md
vendored
|
|
@ -53,14 +53,5 @@ PASTE HERE
|
|||
<!-- output of `tlmgr list --only-installed` for TeX Live or a screenshot of the Packages page for MikTeX -->
|
||||
</details>
|
||||
|
||||
<details><summary>FFMPEG</summary>
|
||||
|
||||
Output of `ffmpeg -version`:
|
||||
|
||||
```
|
||||
PASTE HERE
|
||||
```
|
||||
</details>
|
||||
|
||||
## Additional comments
|
||||
<!-- Add further context that you think might be relevant for this issue here. -->
|
||||
|
|
|
|||
10
.github/manimdependency.json
vendored
10
.github/manimdependency.json
vendored
|
|
@ -4,7 +4,10 @@
|
|||
"standalone",
|
||||
"preview",
|
||||
"doublestroke",
|
||||
"ms",
|
||||
"count1to",
|
||||
"multitoc",
|
||||
"prelim2e",
|
||||
"ragged2e",
|
||||
"everysel",
|
||||
"setspace",
|
||||
"rsfs",
|
||||
|
|
@ -29,7 +32,10 @@
|
|||
"standalone",
|
||||
"preview",
|
||||
"doublestroke",
|
||||
"ms",
|
||||
"count1to",
|
||||
"multitoc",
|
||||
"prelim2e",
|
||||
"ragged2e",
|
||||
"everysel",
|
||||
"setspace",
|
||||
"rsfs",
|
||||
|
|
|
|||
209
.github/scripts/ci_build_cairo.py
vendored
Normal file
209
.github/scripts/ci_build_cairo.py
vendored
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
# Logic is as follows:
|
||||
# 1. Download cairo source code: https://cairographics.org/releases/cairo-<version>.tar.xz
|
||||
# 2. Verify the downloaded file using the sha256sums file: https://cairographics.org/releases/cairo-<version>.tar.xz.sha256sum
|
||||
# 3. Extract the downloaded file.
|
||||
# 4. Create a virtual environment and install meson and ninja.
|
||||
# 5. Run meson build in the extracted directory. Also, set required prefix.
|
||||
# 6. Run meson compile -C build.
|
||||
# 7. Run meson install -C build.
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
import typing
|
||||
import urllib.request
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from sys import stdout
|
||||
|
||||
CAIRO_VERSION = "1.18.0"
|
||||
CAIRO_URL = f"https://cairographics.org/releases/cairo-{CAIRO_VERSION}.tar.xz"
|
||||
CAIRO_SHA256_URL = f"{CAIRO_URL}.sha256sum"
|
||||
|
||||
VENV_NAME = "meson-venv"
|
||||
BUILD_DIR = "build"
|
||||
INSTALL_PREFIX = Path(__file__).parent.parent.parent / "third_party" / "cairo"
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_ci():
|
||||
return os.getenv("CI", None) is not None
|
||||
|
||||
|
||||
def download_file(url, path):
|
||||
logger.info(f"Downloading {url} to {path}")
|
||||
block_size = 1024 * 1024
|
||||
with urllib.request.urlopen(url) as response, open(path, "wb") as file:
|
||||
while True:
|
||||
data = response.read(block_size)
|
||||
if not data:
|
||||
break
|
||||
file.write(data)
|
||||
|
||||
|
||||
def verify_sha256sum(path, sha256sum):
|
||||
with open(path, "rb") as file:
|
||||
file_hash = hashlib.sha256(file.read()).hexdigest()
|
||||
if file_hash != sha256sum:
|
||||
raise Exception("SHA256SUM does not match")
|
||||
|
||||
|
||||
def extract_tar_xz(path, directory):
|
||||
with tarfile.open(path) as file:
|
||||
file.extractall(directory)
|
||||
|
||||
|
||||
def run_command(command, cwd=None, env=None):
|
||||
process = subprocess.Popen(command, cwd=cwd, env=env)
|
||||
process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise Exception("Command failed")
|
||||
|
||||
|
||||
@contextmanager
|
||||
def gha_group(title: str) -> typing.Generator:
|
||||
if not is_ci():
|
||||
yield
|
||||
return
|
||||
print(f"\n::group::{title}")
|
||||
stdout.flush()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
print("::endgroup::")
|
||||
stdout.flush()
|
||||
|
||||
|
||||
def set_env_var_gha(name: str, value: str) -> None:
|
||||
if not is_ci():
|
||||
return
|
||||
env_file = os.getenv("GITHUB_ENV", None)
|
||||
if env_file is None:
|
||||
return
|
||||
with open(env_file, "a") as file:
|
||||
file.write(f"{name}={value}\n")
|
||||
stdout.flush()
|
||||
|
||||
|
||||
def get_ld_library_path(prefix: Path) -> str:
|
||||
# given a prefix, the ld library path can be found at
|
||||
# <prefix>/lib/* or sometimes just <prefix>/lib
|
||||
# this function returns the path to the ld library path
|
||||
|
||||
# first, check if the ld library path exists at <prefix>/lib/*
|
||||
ld_library_paths = list(prefix.glob("lib/*"))
|
||||
if len(ld_library_paths) == 1:
|
||||
return ld_library_paths[0].absolute().as_posix()
|
||||
|
||||
# if the ld library path does not exist at <prefix>/lib/*,
|
||||
# return <prefix>/lib
|
||||
ld_library_path = prefix / "lib"
|
||||
if ld_library_path.exists():
|
||||
return ld_library_path.absolute().as_posix()
|
||||
return ""
|
||||
|
||||
|
||||
def main():
|
||||
if sys.platform == "win32":
|
||||
logger.info("Skipping build on windows")
|
||||
return
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
with gha_group("Downloading and Extracting Cairo"):
|
||||
logger.info(f"Downloading cairo version {CAIRO_VERSION}")
|
||||
download_file(CAIRO_URL, os.path.join(tmpdir, "cairo.tar.xz"))
|
||||
|
||||
logger.info("Downloading cairo sha256sum")
|
||||
download_file(CAIRO_SHA256_URL, os.path.join(tmpdir, "cairo.sha256sum"))
|
||||
|
||||
logger.info("Verifying cairo sha256sum")
|
||||
with open(os.path.join(tmpdir, "cairo.sha256sum")) as file:
|
||||
sha256sum = file.read().split()[0]
|
||||
verify_sha256sum(os.path.join(tmpdir, "cairo.tar.xz"), sha256sum)
|
||||
|
||||
logger.info("Extracting cairo")
|
||||
extract_tar_xz(os.path.join(tmpdir, "cairo.tar.xz"), tmpdir)
|
||||
|
||||
with gha_group("Installing meson and ninja"):
|
||||
logger.info("Creating virtual environment")
|
||||
run_command([sys.executable, "-m", "venv", os.path.join(tmpdir, VENV_NAME)])
|
||||
|
||||
logger.info("Installing meson and ninja")
|
||||
run_command(
|
||||
[
|
||||
os.path.join(tmpdir, VENV_NAME, "bin", "pip"),
|
||||
"install",
|
||||
"meson",
|
||||
"ninja",
|
||||
]
|
||||
)
|
||||
|
||||
env_vars = {
|
||||
# add the venv bin directory to PATH so that meson can find ninja
|
||||
"PATH": f"{os.path.join(tmpdir, VENV_NAME, 'bin')}{os.pathsep}{os.environ['PATH']}",
|
||||
}
|
||||
|
||||
with gha_group("Building and Installing Cairo"):
|
||||
logger.info("Running meson setup")
|
||||
run_command(
|
||||
[
|
||||
os.path.join(tmpdir, VENV_NAME, "bin", "meson"),
|
||||
"setup",
|
||||
BUILD_DIR,
|
||||
f"--prefix={INSTALL_PREFIX.absolute().as_posix()}",
|
||||
"--buildtype=release",
|
||||
"-Dtests=disabled",
|
||||
],
|
||||
cwd=os.path.join(tmpdir, f"cairo-{CAIRO_VERSION}"),
|
||||
env=env_vars,
|
||||
)
|
||||
|
||||
logger.info("Running meson compile")
|
||||
run_command(
|
||||
[
|
||||
os.path.join(tmpdir, VENV_NAME, "bin", "meson"),
|
||||
"compile",
|
||||
"-C",
|
||||
BUILD_DIR,
|
||||
],
|
||||
cwd=os.path.join(tmpdir, f"cairo-{CAIRO_VERSION}"),
|
||||
env=env_vars,
|
||||
)
|
||||
|
||||
logger.info("Running meson install")
|
||||
run_command(
|
||||
[
|
||||
os.path.join(tmpdir, VENV_NAME, "bin", "meson"),
|
||||
"install",
|
||||
"-C",
|
||||
BUILD_DIR,
|
||||
],
|
||||
cwd=os.path.join(tmpdir, f"cairo-{CAIRO_VERSION}"),
|
||||
env=env_vars,
|
||||
)
|
||||
|
||||
logger.info(f"Successfully built cairo and installed it to {INSTALL_PREFIX}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "--set-env-vars" in sys.argv:
|
||||
with gha_group("Setting environment variables"):
|
||||
# append the pkgconfig directory to PKG_CONFIG_PATH
|
||||
set_env_var_gha(
|
||||
"PKG_CONFIG_PATH",
|
||||
f"{Path(get_ld_library_path(INSTALL_PREFIX), 'pkgconfig').as_posix()}{os.pathsep}"
|
||||
f'{os.getenv("PKG_CONFIG_PATH", "")}',
|
||||
)
|
||||
set_env_var_gha(
|
||||
"LD_LIBRARY_PATH",
|
||||
f"{get_ld_library_path(INSTALL_PREFIX)}{os.pathsep}"
|
||||
f'{os.getenv("LD_LIBRARY_PATH", "")}',
|
||||
)
|
||||
sys.exit(0)
|
||||
main()
|
||||
2
.github/workflows/cffconvert.yml
vendored
2
.github/workflows/cffconvert.yml
vendored
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out a copy of the repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check whether the citation metadata from CITATION.cff is valid
|
||||
uses: citation-file-format/cffconvert-github-action@2.0.0
|
||||
|
|
|
|||
49
.github/workflows/ci.yml
vendored
49
.github/workflows/ci.yml
vendored
|
|
@ -18,23 +18,24 @@ jobs:
|
|||
env:
|
||||
DISPLAY: :0
|
||||
PYTEST_ADDOPTS: "--color=yes" # colors in pytest
|
||||
PYTHONIOENCODING: "utf8"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, macos-latest, windows-latest]
|
||||
python: ["3.8", "3.9", "3.10", "3.11"]
|
||||
os: [ubuntu-22.04, macos-13, windows-latest]
|
||||
python: ["3.9", "3.10", "3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Poetry
|
||||
run: |
|
||||
pipx install "poetry==1.5.*"
|
||||
pipx install "poetry==1.7.*"
|
||||
poetry config virtualenvs.prefer-active-python true
|
||||
|
||||
- name: Setup Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
cache: "poetry"
|
||||
|
|
@ -50,22 +51,16 @@ jobs:
|
|||
run: |
|
||||
echo "date=$(/bin/date -u "+%m%w%Y")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install and cache ffmpeg (all OS)
|
||||
uses: FedericoCarboni/setup-ffmpeg@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
id: setup-ffmpeg
|
||||
|
||||
- name: Install system dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
with:
|
||||
packages: python3-opengl libpango1.0-dev xvfb
|
||||
packages: python3-opengl libpango1.0-dev xvfb freeglut3-dev
|
||||
version: 1.0
|
||||
|
||||
- name: Install Texlive (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
uses: teatimeguest/setup-texlive-action@v2
|
||||
uses: teatimeguest/setup-texlive-action@v3
|
||||
with:
|
||||
cache: true
|
||||
packages: scheme-basic fontspec inputenc fontenc tipa mathrsfs calligra xcolor standalone preview doublestroke ms everysel setspace rsfs relsize ragged2e fundus-calligra microtype wasysym physics dvisvgm jknapltx wasy cm-super babel-english gnu-freefont mathastext cbfonts-fd xetex
|
||||
|
|
@ -76,8 +71,24 @@ jobs:
|
|||
# start xvfb in background
|
||||
sudo /usr/bin/Xvfb $DISPLAY -screen 0 1280x1024x24 &
|
||||
|
||||
- name: Setup Cairo Cache
|
||||
uses: actions/cache@v4
|
||||
id: cache-cairo
|
||||
if: runner.os == 'Linux' || runner.os == 'macOS'
|
||||
with:
|
||||
path: ${{ github.workspace }}/third_party
|
||||
key: ${{ runner.os }}-dependencies-cairo-${{ hashFiles('.github/scripts/ci_build_cairo.py') }}
|
||||
|
||||
- name: Build and install Cairo (Linux and macOS)
|
||||
if: (runner.os == 'Linux' || runner.os == 'macOS') && steps.cache-cairo.outputs.cache-hit != 'true'
|
||||
run: python .github/scripts/ci_build_cairo.py
|
||||
|
||||
- name: Set env vars for Cairo (Linux and macOS)
|
||||
if: runner.os == 'Linux' || runner.os == 'macOS'
|
||||
run: python .github/scripts/ci_build_cairo.py --set-env-vars
|
||||
|
||||
- name: Setup macOS cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
id: cache-macos
|
||||
if: runner.os == 'macOS'
|
||||
with:
|
||||
|
|
@ -103,10 +114,6 @@ jobs:
|
|||
export PATH="$oriPath"
|
||||
echo "Completed TinyTeX"
|
||||
|
||||
- name: Install cairo (MacOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install cairo
|
||||
|
||||
- name: Add macOS dependencies to PATH
|
||||
if: runner.os == 'macOS'
|
||||
shell: bash
|
||||
|
|
@ -118,12 +125,12 @@ jobs:
|
|||
- name: Setup Windows cache
|
||||
id: cache-windows
|
||||
if: runner.os == 'Windows'
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}\ManimCache
|
||||
key: ${{ runner.os }}-dependencies-tinytex-${{ hashFiles('.github/manimdependency.json') }}-${{ steps.cache-vars.outputs.date }}-1
|
||||
|
||||
- uses: ssciwr/setup-mesa-dist-win@v1
|
||||
- uses: ssciwr/setup-mesa-dist-win@v2
|
||||
|
||||
- name: Install system dependencies (Windows)
|
||||
if: runner.os == 'Windows' && steps.cache-windows.outputs.cache-hit != 'true'
|
||||
|
|
@ -131,7 +138,7 @@ jobs:
|
|||
$tinyTexPackages = $(python -c "import json;print(' '.join(json.load(open('.github/manimdependency.json'))['windows']['tinytex']))") -Split ' '
|
||||
$OriPath = $env:PATH
|
||||
echo "Install Tinytex"
|
||||
Invoke-WebRequest "https://github.com/yihui/tinytex-releases/releases/download/daily/TinyTeX-1.zip" -O "$($env:TMP)\TinyTex.zip"
|
||||
Invoke-WebRequest "https://github.com/yihui/tinytex-releases/releases/download/daily/TinyTeX-1.zip" -OutFile "$($env:TMP)\TinyTex.zip"
|
||||
Expand-Archive -LiteralPath "$($env:TMP)\TinyTex.zip" -DestinationPath "$($PWD)\ManimCache\LatexWindows"
|
||||
$env:Path = "$($PWD)\ManimCache\LatexWindows\TinyTeX\bin\windows;$($env:PATH)"
|
||||
tlmgr update --self
|
||||
|
|
|
|||
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
|
|
@ -24,19 +24,19 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql.yml
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
|
|
|||
16
.github/workflows/publish-docker.yml
vendored
16
.github/workflows/publish-docker.yml
vendored
|
|
@ -13,19 +13,19 @@ jobs:
|
|||
if: github.event_name != 'release'
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/arm64,linux/amd64
|
||||
push: true
|
||||
|
|
@ -38,13 +38,13 @@ jobs:
|
|||
if: github.event_name == 'release'
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
|
@ -61,7 +61,7 @@ jobs:
|
|||
print(f"tag_name={ref_tag}", file=f)
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/arm64,linux/amd64
|
||||
push: true
|
||||
|
|
|
|||
10
.github/workflows/python-publish.yml
vendored
10
.github/workflows/python-publish.yml
vendored
|
|
@ -8,12 +8,12 @@ jobs:
|
|||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
- name: Set up Python 3.11
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: 3.11
|
||||
|
||||
- name: Install dependencies
|
||||
run: python -m pip install --upgrade poetry
|
||||
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
poetry build
|
||||
|
||||
- name: Store artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: dist/*.tar.gz
|
||||
name: manim.tar.gz
|
||||
|
|
|
|||
85
.github/workflows/release-publish-documentation.yml
vendored
Normal file
85
.github/workflows/release-publish-documentation.yml
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
name: Publish downloadable documentation
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-and-publish-htmldocs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.11
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.11
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt update && sudo apt install -y \
|
||||
pkg-config libcairo-dev libpango1.0-dev wget fonts-roboto
|
||||
wget -qO- "https://yihui.org/tinytex/install-bin-unix.sh" | sh
|
||||
echo ${HOME}/.TinyTeX/bin/x86_64-linux >> $GITHUB_PATH
|
||||
|
||||
- name: Install LaTeX and Python dependencies
|
||||
run: |
|
||||
tlmgr update --self
|
||||
tlmgr install \
|
||||
babel-english ctex doublestroke dvisvgm frcursive fundus-calligra jknapltx \
|
||||
mathastext microtype physics preview ragged2e relsize rsfs setspace standalone \
|
||||
wasy wasysym
|
||||
python -m pip install --upgrade poetry
|
||||
poetry install
|
||||
|
||||
- name: Build and package documentation
|
||||
run: |
|
||||
cd docs/
|
||||
poetry run make html
|
||||
cd build/html/
|
||||
tar -czvf ../html-docs.tar.gz *
|
||||
|
||||
- name: Store artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/docs/build/html-docs.tar.gz
|
||||
name: html-docs.tar.gz
|
||||
|
||||
- name: Install Dependency
|
||||
run: pip install requests
|
||||
|
||||
- name: Get Upload URL
|
||||
if: github.event == 'release'
|
||||
id: create_release
|
||||
shell: python
|
||||
env:
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag_act: ${{ github.ref }}
|
||||
run: |
|
||||
import requests
|
||||
import os
|
||||
ref_tag = os.getenv('tag_act').split('/')[-1]
|
||||
access_token = os.getenv('access_token')
|
||||
headers = {
|
||||
"Accept":"application/vnd.github.v3+json",
|
||||
"Authorization": f"token {access_token}"
|
||||
}
|
||||
url = f"https://api.github.com/repos/ManimCommunity/manim/releases/tags/{ref_tag}"
|
||||
c = requests.get(url,headers=headers)
|
||||
upload_url=c.json()['upload_url']
|
||||
with open(os.getenv('GITHUB_OUTPUT'), 'w') as f:
|
||||
print(f"upload_url={upload_url}", file=f)
|
||||
print(f"tag_name={ref_tag[1:]}", file=f)
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: github.event == 'release'
|
||||
id: upload-release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ${{ github.workspace }}/docs/build/html-docs.tar.gz
|
||||
asset_name: manim-htmldocs-${{ steps.create_release.outputs.tag_name }}.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -131,3 +131,6 @@ dist/
|
|||
|
||||
/media_dir.txt
|
||||
# ^TODO: Remove the need for this with a proper config file
|
||||
|
||||
# Ignore the built dependencies
|
||||
third_party/*
|
||||
|
|
|
|||
91
.mypy.ini
91
.mypy.ini
|
|
@ -1,91 +0,0 @@
|
|||
[mypy]
|
||||
show_error_codes = True
|
||||
|
||||
# ignore most files; should be checked once proper types have been implemented
|
||||
[mypy-manim.__main__]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim.camera.*]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim.scene.*]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim.cli.cfg.*]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim.mobject.*]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim._config.*]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim.utils.*]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-manim.utils.color]
|
||||
ignore_errors = False
|
||||
|
||||
[mypy-manim.animation.*]
|
||||
ignore_errors = True
|
||||
|
||||
# ---------------- We can't properly type this ------------------------
|
||||
|
||||
[mypy-manim.grpc.*]
|
||||
ignore_errors = True
|
||||
|
||||
# ---------------- Stubless imported Modules --------------------------
|
||||
|
||||
# We should be able to create stubs for this or type hint it
|
||||
[mypy-manimpango]
|
||||
ignore_missing_imports = True
|
||||
|
||||
# Has stubs in 3.8
|
||||
[mypy-numpy]
|
||||
ignore_missing_imports = True
|
||||
|
||||
# Has stubs in 3.8
|
||||
[mypy-pydub]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-matplotlib]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-scipy.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-networkx]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-git]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-moderngl.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-moderngl_window.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-colour]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-dearpygui.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-screeninfo]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-IPython.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-watchdog.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-tqdm]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-mapbox_earcut]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-click_default_group]
|
||||
ignore_missing_imports = True
|
||||
|
|
@ -3,7 +3,7 @@ fail_fast: false
|
|||
exclude: ^(manim/grpc/gen/|docs/i18n/)
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: check-ast
|
||||
name: Validate Python
|
||||
|
|
@ -12,39 +12,22 @@ repos:
|
|||
- id: end-of-file-fixer
|
||||
- id: check-toml
|
||||
name: Validate Poetry
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
- id: isort
|
||||
name: isort (cython)
|
||||
types: [cython]
|
||||
- id: isort
|
||||
name: isort (pyi)
|
||||
types: [pyi]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.10.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
name: Update code to new python versions
|
||||
args: [--py37-plus]
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.10.0
|
||||
hooks:
|
||||
- id: python-check-blanket-noqa
|
||||
name: Precision flake ignores
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.7.0
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.4.9
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/asottile/blacken-docs
|
||||
rev: 1.15.0
|
||||
hooks:
|
||||
- id: blacken-docs
|
||||
additional_dependencies: [black==22.3.0]
|
||||
- id: ruff
|
||||
name: ruff lint
|
||||
types: [python]
|
||||
args: [--exit-non-zero-on-fix]
|
||||
- id: ruff-format
|
||||
types: [python]
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.1.0
|
||||
rev: 7.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
|
|
@ -58,7 +41,7 @@ repos:
|
|||
flake8-simplify==0.14.1,
|
||||
]
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.4.1
|
||||
rev: v1.10.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
additional_dependencies:
|
||||
|
|
@ -69,9 +52,10 @@ repos:
|
|||
types-requests,
|
||||
types-setuptools,
|
||||
]
|
||||
files: ^manim/
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.5
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
files: ^.*\.(py|md|rst)$
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@ build:
|
|||
os: ubuntu-22.04
|
||||
|
||||
tools:
|
||||
python: "3.10"
|
||||
python: "3.11"
|
||||
|
||||
apt_packages:
|
||||
- libpango1.0-dev
|
||||
- ffmpeg
|
||||
- graphviz
|
||||
|
||||
python:
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ authors:
|
|||
-
|
||||
name: "The Manim Community Developers"
|
||||
cff-version: "1.2.0"
|
||||
date-released: 2023-04-06
|
||||
date-released: 2024-04-28
|
||||
license: MIT
|
||||
message: "We acknowledge the importance of good software to support research, and we note that research becomes more valuable when it is communicated effectively. To demonstrate the value of Manim, we ask that you cite Manim in your work."
|
||||
title: Manim – Mathematical Animation Framework
|
||||
url: "https://www.manim.community/"
|
||||
version: "v0.17.3"
|
||||
version: "v0.18.1"
|
||||
...
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021, the Manim Community Developers
|
||||
Copyright (c) 2024, the Manim Community Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
|
|
@ -5,12 +5,7 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
try:
|
||||
# https://github.com/moderngl/moderngl/issues/517
|
||||
import readline # required to prevent a segfault on Python 3.10
|
||||
except ModuleNotFoundError: # windows
|
||||
pass
|
||||
|
||||
import cairo
|
||||
import moderngl
|
||||
|
||||
# If it is running Doctest the current directory
|
||||
|
|
@ -39,6 +34,7 @@ def pytest_report_header(config):
|
|||
info = ctx.info
|
||||
ctx.release()
|
||||
return (
|
||||
f"\nCairo Version: {cairo.cairo_version()}",
|
||||
"\nOpenGL information",
|
||||
"------------------",
|
||||
f"vendor: {info['GL_VENDOR'].strip()}",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
FROM python:3.8-slim
|
||||
FROM python:3.11-slim
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
ffmpeg \
|
||||
build-essential \
|
||||
gcc \
|
||||
cmake \
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ msgid "This ``Scene`` illustrates the quirks of ``.animate``. When using ``.anim
|
|||
msgstr ""
|
||||
|
||||
#: ../../source/tutorials/quickstart.rst:344
|
||||
msgid "In ``DifferentRotations``, the difference between ``.animate``'s interpretation of rotation and the ``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 360 degrees are the same, so ``.animate`` tries to interpolate two identical objects and the result is the left square. If you find that your own usage of ``.animate`` is causing similar unwanted behavior, consider using conventional animation methods like the right square, which uses ``Rotate``."
|
||||
msgid "In ``DifferentRotations``, the difference between ``.animate``'s interpretation of rotation and the ``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 180 degrees are the same, so ``.animate`` tries to interpolate two identical objects and the result is the left square. If you find that your own usage of ``.animate`` is causing similar unwanted behavior, consider using conventional animation methods like the right square, which uses ``Rotate``."
|
||||
msgstr ""
|
||||
|
||||
#: ../../source/tutorials/quickstart.rst:353
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
furo
|
||||
myst-parser
|
||||
sphinx<5.1
|
||||
sphinx>=7.3
|
||||
sphinx-copybutton
|
||||
sphinxext-opengraph
|
||||
|
|
|
|||
0
docs/skip-manim
Normal file
0
docs/skip-manim
Normal file
|
|
@ -82,3 +82,22 @@ h4, h5, h6{
|
|||
.sidebar-tree a.internal.reference {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.manim-binder-button {
|
||||
text-transform: capitalize;
|
||||
padding: 10px 20px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.manim-binder-wrapper {
|
||||
background-color: var(--color-code-background);
|
||||
color: var(--color-code-foreground);
|
||||
}
|
||||
|
||||
.manim-binder-title {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.manim-binder-button-wrapper {
|
||||
margin: 0px 10px;
|
||||
}
|
||||
|
|
|
|||
3
docs/source/_static/manim-binder.min.js
vendored
Normal file
3
docs/source/_static/manim-binder.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
docs/source/_static/manim-binder.min.js.LICENSE.txt
Normal file
6
docs/source/_static/manim-binder.min.js.LICENSE.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
1
docs/source/_static/manim-binder.min.js.map
Normal file
1
docs/source/_static/manim-binder.min.js.map
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -4,16 +4,9 @@
|
|||
|
||||
.. automodule:: {{ fullname }}
|
||||
|
||||
{% block attributes %}
|
||||
{% if attributes %}
|
||||
.. rubric:: Module Attributes
|
||||
|
||||
.. autosummary::
|
||||
{% for item in attributes %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{# SEE manim.utils.docbuild.autoaliasattr_directive #}
|
||||
{# FOR INFORMATION ABOUT THE CUSTOM autoaliasattr DIRECTIVE! #}
|
||||
.. autoaliasattr:: {{ fullname }}
|
||||
|
||||
{% block classes %}
|
||||
{% if classes %}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,14 @@
|
|||
Changelog
|
||||
#########
|
||||
|
||||
This page contains a list of changes made between releases. Changes
|
||||
from versions that are not listed below (in particular patch-level
|
||||
releases since v0.18.0) are documented on our
|
||||
`GitHub release page <https://github.com/ManimCommunity/manim/releases/>`__.
|
||||
|
||||
.. toctree::
|
||||
|
||||
changelog/0.18.0-changelog
|
||||
changelog/0.17.3-changelog
|
||||
changelog/0.17.2-changelog
|
||||
changelog/0.17.1-changelog
|
||||
|
|
|
|||
294
docs/source/changelog/0.18.0-changelog.rst
Normal file
294
docs/source/changelog/0.18.0-changelog.rst
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
*******
|
||||
v0.18.0
|
||||
*******
|
||||
|
||||
:Date: November 11, 2023
|
||||
|
||||
Contributors
|
||||
============
|
||||
|
||||
A total of 41 people contributed to this
|
||||
release. People with a '+' by their names authored a patch for the first
|
||||
time.
|
||||
|
||||
* Abulafia +
|
||||
* Adhyyan Sekhsaria +
|
||||
* Adrien Ludwig +
|
||||
* Alex Kempen +
|
||||
* Andres Berejnoi +
|
||||
* Anousheh Moonen +
|
||||
* Benjamin Hackl
|
||||
* Francisco Manríquez Novoa
|
||||
* Harald Schilly +
|
||||
* Immanuel-Alvaro-Bhirawa +
|
||||
* Jason Grace +
|
||||
* Jason Villanueva
|
||||
* Jinchu Li
|
||||
* John Lynch +
|
||||
* Jérome Eertmans
|
||||
* Matt Turner +
|
||||
* Narahari Rao +
|
||||
* Naveen M K
|
||||
* Nikhil Iyer +
|
||||
* Ron Li +
|
||||
* Sujal Singh +
|
||||
* Tristan Schulz
|
||||
* Uwe Zimmermann +
|
||||
* Václav Blažej +
|
||||
* Zachary Winkeler +
|
||||
|
||||
|
||||
The patches included in this release have been reviewed by
|
||||
the following contributors.
|
||||
|
||||
* Alex Lembcke
|
||||
* Andres Berejnoi
|
||||
* Axel
|
||||
* Benjamin Hackl
|
||||
* Francisco Manríquez Novoa
|
||||
* Immanuel-Alvaro-Bhirawa
|
||||
* Jan-Hendrik Müller
|
||||
* Jason Grace
|
||||
* Jason Villanueva
|
||||
* Jinchu Li
|
||||
* John Lynch
|
||||
* Jérome Eertmans
|
||||
* Kevin Lubick
|
||||
* Narahari Rao
|
||||
* Naveen M K
|
||||
* NotWearingPants
|
||||
* SsNiPeR1
|
||||
* TheMathematicFanatic
|
||||
* Tristan Schulz
|
||||
* Uwe Zimmermann
|
||||
* Viicos
|
||||
* icedcoffeeee
|
||||
|
||||
Pull requests merged
|
||||
====================
|
||||
|
||||
A total of 59 pull requests were merged for this release.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
||||
* :pr:`3020`: Rewrote Manim's color system
|
||||
This change removed the ``colour`` library as a dependency
|
||||
of Manim and replaced the internal handling of colors with
|
||||
the newly added :class:`.ManimColor`. This also adds hundreds
|
||||
of new predefined colors, see :mod:`.utils.color` for more
|
||||
details.
|
||||
This should only be a breaking change if you have interacted
|
||||
directly with the ``colour`` module before. The general interface
|
||||
has been kept stable.
|
||||
|
||||
|
||||
Highlights
|
||||
----------
|
||||
|
||||
* :pr:`3299`: Added new ``manim checkhealth`` CLI subcommand
|
||||
This adds a new command line interface subcommand which can be used to check
|
||||
whether a local installation of Manim has been configured correctly, and all
|
||||
required (and optional) dependencies are available. To try it, run it via
|
||||
``manim checkhealth`` or ``python -m manim checkhealth``.
|
||||
|
||||
* :pr:`3427`: New feature: rendered examples in documentation can now be run directly via binder
|
||||
This adds a "Make interactive" button below the examples in our documentation
|
||||
that establishes a connection to binder such that examples can be modified and
|
||||
rerendered directly from your browser.
|
||||
|
||||
* :pr:`3086`: Introduced a new module :mod:`.typing` for type hints
|
||||
This also adds various type hints to integral parts of the code base.
|
||||
|
||||
* :pr:`3322`: Implemented auto-removal of auxiliary LaTeX files, enabled by default
|
||||
This automatically removes auxiliary files creating during the compilation of
|
||||
LaTeX documents like ``.aux`` or ``.dvi`` files. This behavior can be controlled
|
||||
via the newly introduced ``no_latex_cleanup`` config key (``False`` by default).
|
||||
On the command line, the autoremoval can be disabled via the ``--no_latex_cleanup``
|
||||
CLI flag.
|
||||
|
||||
* :pr:`3395`: Added support for Python 3.12
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
* :pr:`3361`: Added three new rate functions
|
||||
This adds the rate functions :func:`.smoothstep`, :func:`.smootherstep`,
|
||||
:func:`.smoothererstep` based on the SmoothStep sigmoid functions.
|
||||
|
||||
* :pr:`3264`: Added new mobjects :class:`.LabeledLine` and :class:`.LabeledArrow`
|
||||
|
||||
|
||||
Enhancements
|
||||
------------
|
||||
|
||||
* :pr:`3190`: Made :class:`.CurvesAsSubmobjects` mobjects compatible with :meth:`.input_to_graph_point`
|
||||
|
||||
|
||||
* :pr:`3226`: Avoid using a mobject as a default argument of :class:`.ArcBrace`
|
||||
|
||||
|
||||
* :pr:`3366`: Added spacing between values and unit in :class:`.DecimalNumber`
|
||||
This adds the new keyword argument ``unit_buff_per_font_unit`` (default: 0, for
|
||||
backwards compatibility). Setting it to some positive number creates additional
|
||||
space between the numeric value and the displayed unit.
|
||||
|
||||
Fixed bugs
|
||||
----------
|
||||
|
||||
* :pr:`3205`: Fixed type hint of ``angle`` in :class:`.Arc`
|
||||
|
||||
|
||||
* :pr:`3210`: Fixed :class:`.DecimalNumber` with ``show_ellipsis=True`` with the OpenGL renderer
|
||||
|
||||
|
||||
* :pr:`3211`: Fixed display issues with custom labels for :class:`.Axes` with the OpenGL renderer
|
||||
|
||||
|
||||
* :pr:`3298`: Fixed expand animation for :class:`.ManimBanner`
|
||||
|
||||
|
||||
* :pr:`3306`: Fixed IPython terminal history and embedded shell instantiation for scenes using :meth:`.Scene.interactive_embed`
|
||||
|
||||
|
||||
* :pr:`3315`: Fixed issue with parameter types in :meth:`.Scene.add_subcaption`
|
||||
|
||||
|
||||
* :pr:`3423`: Fixed incorrect submobject count of multi-part :class:`.Tex` mobjects
|
||||
This resolves various issues where formulas were not displayed completely,
|
||||
like it was the case with ``MathTex("1", "^{", "0")``.
|
||||
|
||||
* :pr:`3284`: Fixed ``LinearTransformationSceneExample`` in Jupyter notebooks
|
||||
|
||||
|
||||
* :pr:`3302`: Fixed typo in comparison in :meth:`.OpenGLVMobject.interpolate`
|
||||
|
||||
|
||||
* :pr:`3340`: Fixed incorrect computation of bounding box for rotated :class:`.ImageMobject`
|
||||
|
||||
|
||||
* :pr:`3343`: Fixed return value of :meth:`.TexTemplate.add_to_preamble` and :meth:`.TexTemplate.add_to_document`
|
||||
|
||||
|
||||
* :pr:`3282`: Ensure that :meth:`.ArrowVectorField.get_vector` does not modify the passed inputs
|
||||
|
||||
|
||||
* :pr:`3392`: Fixed behavior of elongated tick lines for :class:`.NumberLine`
|
||||
|
||||
|
||||
* :pr:`3430`: Fixed CSV reader adding empty lists in rendering summary during documentation build
|
||||
|
||||
|
||||
* :pr:`3404`: Properly raise an exception on empty inputs to :class:`.AddTextLetterByLetter`
|
||||
|
||||
|
||||
Documentation-related changes
|
||||
-----------------------------
|
||||
|
||||
* :pr:`3219`: Enabled social cards for links to documentation
|
||||
|
||||
|
||||
* :pr:`3274`: Replaced incorrect mentions of Python 3.7 as the minimally required version
|
||||
|
||||
|
||||
* :pr:`3297`: Improved arrow tip sowcase example for :class:`.ArrowTip`
|
||||
|
||||
|
||||
* :pr:`3312`: Added documentation for :func:`.always_redraw`
|
||||
|
||||
|
||||
* :pr:`3218`: Improved grammar in the :doc:`deep dive guide </guides/deep_dive>`
|
||||
|
||||
|
||||
* :pr:`3251`: Add LaTeX installation instructions for Fedora
|
||||
|
||||
|
||||
* :pr:`3290`: Updated required dependencies for MacOS installations
|
||||
|
||||
|
||||
* :pr:`3325`: Added documentation for functions in :mod:`.mobject_update_utils`
|
||||
This adds docstrings and typehints to :func:`.always_rotate`,
|
||||
:func:`.always_shift`, :func:`.turn_animation_into_updater`
|
||||
|
||||
* :pr:`3353`: Added documentation for :meth:`.Mobject.center`
|
||||
|
||||
|
||||
* :pr:`3355`: Temporarily enabled ``htmlzip`` build on ReadTheDocs
|
||||
|
||||
|
||||
* :pr:`3377`: Fixed a typo in the :doc:`deep dive guide </guides/deep_dive>`
|
||||
|
||||
|
||||
* :pr:`3389`: Removed superfluous curly braces in a LaTeX expression
|
||||
|
||||
|
||||
* :pr:`3417`: Replaced ``htmlzip`` ReadTheDocs build with workflow attaching downloadable documentation to GitHub releases
|
||||
|
||||
|
||||
Changes concerning the testing system
|
||||
-------------------------------------
|
||||
|
||||
* :pr:`3416`: Fixed tests to run on Cairo 1.18.0
|
||||
|
||||
|
||||
* :pr:`3257`: Fix a configuration error concerning poetry
|
||||
|
||||
|
||||
* :pr:`3419`: Fixed caching of Cairo builds on CI runners
|
||||
|
||||
|
||||
Code quality improvements and similar refactors
|
||||
-----------------------------------------------
|
||||
|
||||
* :pr:`3229`: Made docbuild errors easier to debug and fixed error from changed exception class
|
||||
|
||||
|
||||
* :pr:`3231`: Fixed errors reported by ``flake8``
|
||||
|
||||
|
||||
* :pr:`3232`: Upgrade ReadTheDocs build environment to use newer image
|
||||
|
||||
|
||||
* :pr:`3286`: Optimized :meth:`.Axes.coords_to_point`
|
||||
|
||||
|
||||
* :pr:`3224`: Replace final few occurrences of ``os.path`` by ``pathlib.Path``
|
||||
|
||||
|
||||
* :pr:`3236`: Return self in :meth:`.AbstractImageMobject.set_resampling_algorithm`
|
||||
|
||||
|
||||
* :pr:`3253`: Bump tornado from 6.3.1 to 6.3.2
|
||||
|
||||
|
||||
* :pr:`3272`: Bump docker/build-push-action from 3 to 4
|
||||
|
||||
|
||||
* :pr:`3287`: Bump cryptography from 41.0.1 to 41.0.2
|
||||
|
||||
|
||||
* :pr:`3350`: Added missing dependency ``typing-extensions``
|
||||
|
||||
|
||||
* :pr:`3431`: Bump teatimeguest/setup-texlive-action from 2 to 3
|
||||
|
||||
|
||||
* :pr:`3433`: Bump dependencies
|
||||
|
||||
|
||||
* :pr:`3399`: Updated several dependencies
|
||||
|
||||
|
||||
* :pr:`3397`: Several GitHub actions updates
|
||||
|
||||
|
||||
* :pr:`3405`: Updated manimpango version to fix error regarding type strictness
|
||||
|
||||
|
||||
* :pr:`3421`: Improved order of input checks when creating a tree graph
|
||||
|
||||
|
||||
New releases
|
||||
------------
|
||||
|
||||
* :pr:`3439`: Prepared new release: v0.18.0
|
||||
|
|
@ -176,7 +176,7 @@ Fixed bugs
|
|||
* :pr:`1782`: Fixed :class:`~.Tex` not working properly with the OpenGL renderer
|
||||
|
||||
|
||||
* :pr:`1783`: Fixed :meth:`~.OpenGLMobject.shuffle` function and added :meth:`~.invert` to OpenGL
|
||||
* :pr:`1783`: Fixed :meth:`~.OpenGLMobject.shuffle` function and added :meth:`~.Mobject.invert` to OpenGL
|
||||
|
||||
|
||||
* :pr:`1786`: Fixed :class:`~.DecimalNumber` not working properly when the number of digits changes
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ from __future__ import annotations
|
|||
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import manim
|
||||
from manim.utils.docbuild.module_parsing import parse_module_attributes
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
|
|
@ -24,7 +26,7 @@ sys.path.insert(0, os.path.abspath("."))
|
|||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "Manim"
|
||||
copyright = "2020-2022, The Manim Community Dev Team"
|
||||
copyright = f"2020-{datetime.now().year}, The Manim Community Dev Team"
|
||||
author = "The Manim Community Dev Team"
|
||||
|
||||
|
||||
|
|
@ -44,6 +46,7 @@ extensions = [
|
|||
"sphinxext.opengraph",
|
||||
"manim.utils.docbuild.manim_directive",
|
||||
"manim.utils.docbuild.autocolor_directive",
|
||||
"manim.utils.docbuild.autoaliasattr_directive",
|
||||
"sphinx.ext.graphviz",
|
||||
"sphinx.ext.inheritance_diagram",
|
||||
"sphinxcontrib.programoutput",
|
||||
|
|
@ -54,7 +57,14 @@ extensions = [
|
|||
autosummary_generate = True
|
||||
|
||||
# generate documentation from type hints
|
||||
ALIAS_DOCS_DICT = parse_module_attributes()[0]
|
||||
autodoc_typehints = "description"
|
||||
autodoc_type_aliases = {
|
||||
alias_name: f"~manim.{module}.{alias_name}"
|
||||
for module, module_dict in ALIAS_DOCS_DICT.items()
|
||||
for category_dict in module_dict.values()
|
||||
for alias_name in category_dict.keys()
|
||||
}
|
||||
autoclass_content = "both"
|
||||
|
||||
# controls whether functions documented by the autofunction directive
|
||||
|
|
@ -172,8 +182,6 @@ inheritance_edge_attrs = {
|
|||
"penwidth": 1,
|
||||
}
|
||||
|
||||
html_js_files = [
|
||||
"responsiveSvg.js",
|
||||
]
|
||||
html_js_files = ["responsiveSvg.js"]
|
||||
|
||||
graphviz_output_format = "svg"
|
||||
|
|
|
|||
|
|
@ -38,14 +38,10 @@ To get an overview of what our community is currently working on, check out
|
|||
Contributing can be confusing, so here are a few guides:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 3
|
||||
|
||||
contributing/development
|
||||
contributing/docstrings
|
||||
contributing/references
|
||||
contributing/examples
|
||||
contributing/typings
|
||||
contributing/admonitions
|
||||
contributing/docs
|
||||
contributing/testing
|
||||
contributing/performance
|
||||
contributing/internationalization
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ For first-time contributors
|
|||
#. Install Manim:
|
||||
|
||||
- Follow the steps in our :doc:`installation instructions
|
||||
<../installation>` to install **Manim's dependencies**,
|
||||
primarily ``ffmpeg`` and ``LaTeX``.
|
||||
<../installation>` to install **Manim's system dependencies**.
|
||||
We also recommend installing a LaTeX distribution.
|
||||
|
||||
- We recommend using `Poetry <https://python-poetry.org>`__ to manage your
|
||||
developer installation of Manim. Poetry is a tool for dependency
|
||||
|
|
@ -62,7 +62,7 @@ For first-time contributors
|
|||
managing virtual environments.
|
||||
|
||||
If you choose to use Poetry as well, follow `Poetry's installation
|
||||
guidelines <https://python-poetry.org/docs/master/#installation>`__
|
||||
guidelines <https://python-poetry.org/docs/master/#installing-with-pipx>`__
|
||||
to install it on your system, then run ``poetry install`` from
|
||||
your cloned repository. Poetry will then install Manim, as well
|
||||
as create and enter a virtual environment. You can always re-enter
|
||||
|
|
@ -147,7 +147,7 @@ Develop your contribution
|
|||
|
||||
Update the docstrings (the text in triple quotation marks) of any functions
|
||||
or classes you change and include them with any new functions you add.
|
||||
See the :doc:`documentation guide <docstrings>` for more information about how we
|
||||
See the :doc:`documentation guide <docs/docstrings>` for more information about how we
|
||||
prefer our code to be documented. The content of the docstrings will be
|
||||
rendered in the :doc:`reference manual <../reference>`.
|
||||
|
||||
|
|
@ -159,6 +159,8 @@ Develop your contribution
|
|||
As far as development on your local machine goes, these are the main steps you
|
||||
should follow.
|
||||
|
||||
.. _polishing-changes-and-submitting-a-pull-request:
|
||||
|
||||
Polishing Changes and Submitting a Pull Request
|
||||
-----------------------------------------------
|
||||
|
||||
|
|
@ -243,7 +245,8 @@ sticks to our coding conventions.
|
|||
a look at the built HTML files to see whether the formatting of the documentation
|
||||
you added looks as you intended. You can build the documentation locally
|
||||
by running ``make html`` from the ``docs`` directory. Make sure you have `Graphviz <https://graphviz.org/>`_
|
||||
installed locally in order to build the inheritance diagrams.
|
||||
installed locally in order to build the inheritance diagrams. See :doc:`docs` for
|
||||
more information.
|
||||
|
||||
Finally, if the pipeline passes and you are satisfied with your changes: wait for
|
||||
feedback and iterate over any requested changes. You will likely be asked to
|
||||
|
|
|
|||
83
docs/source/contributing/docs.rst
Normal file
83
docs/source/contributing/docs.rst
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
====================
|
||||
Adding Documentation
|
||||
====================
|
||||
|
||||
Building the documentation
|
||||
--------------------------
|
||||
|
||||
When you clone the Manim repository from GitHub, you can access the
|
||||
``docs/`` folder which contains the necessary files to build the
|
||||
documentation.
|
||||
|
||||
To build the docs locally, open a CLI, enter the ``docs/`` folder with the
|
||||
``cd`` command and execute the following depending on your OS:
|
||||
|
||||
- Windows: ``./make.bat html``
|
||||
- macOS and Linux: ``make html``
|
||||
|
||||
The first time you build the docs, the process will take several
|
||||
minutes because it needs to generate all the ``.rst`` (reST:
|
||||
reStructured Text) files from scratch by reading and parsing all the
|
||||
Manim content. The process becomes much shorter the next time, as it
|
||||
rebuilds only the parts which have changed.
|
||||
|
||||
|
||||
Sphinx library and extensions
|
||||
-----------------------------
|
||||
|
||||
Manim uses `Sphinx <https://www.sphinx-doc.org>`_ for building the
|
||||
docs. It also makes use of Sphinx extensions such as:
|
||||
|
||||
- `Autodoc: <https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html>`_
|
||||
imports Manim's Python source code, extracts its docstrings and
|
||||
generates documentation from them.
|
||||
- `Autosummary: <https://www.sphinx-doc.org/en/master/usage/extensions/autosummary.html>`_
|
||||
a complement to Autodoc which adds a special directive ``autosummary``,
|
||||
used in Manim to automatically document classes, methods,
|
||||
attributes, functions, module-level variables and exceptions.
|
||||
Autosummary makes use of `Jinja templates <https://jinja.palletsprojects.com/templates/>`_,
|
||||
which Manim defines for autosummarizing classes and modules
|
||||
inside ``docs/source/_templates/``.
|
||||
- `Graphviz extension for Sphinx: <https://www.sphinx-doc.org/en/master/usage/extensions/graphviz.html>`_
|
||||
embeds graphs generated by the `Graphviz <https://graphviz.org/>`_
|
||||
module, which must be installed in order to render the
|
||||
inheritance diagrams in the :doc:`/reference`.
|
||||
- `Napoleon: <https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html>`_
|
||||
enables Sphinx to read Google style docstrings and, in
|
||||
particular for Manim, `NumPy style docstrings <https://numpydoc.readthedocs.io/en/latest/format.html>`_
|
||||
- see :doc:`docs/docstrings` for more information.
|
||||
|
||||
|
||||
Sphinx theme
|
||||
------------
|
||||
|
||||
The theme used for this website is `Furo <https://sphinx-themes.org/sample-sites/furo/>`_.
|
||||
|
||||
|
||||
Custom Sphinx directives
|
||||
------------------------
|
||||
|
||||
Manim implements **custom directives** for use with Autodoc and Autosummary, which
|
||||
are defined in :mod:`~.docbuild`:
|
||||
|
||||
.. currentmodule:: manim.utils.docbuild
|
||||
|
||||
.. autosummary::
|
||||
|
||||
:toctree: ../reference
|
||||
autoaliasattr_directive
|
||||
autocolor_directive
|
||||
manim_directive
|
||||
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
docs/admonitions
|
||||
docs/docstrings
|
||||
docs/examples
|
||||
docs/references
|
||||
docs/typings
|
||||
|
|
@ -77,8 +77,7 @@ Example:
|
|||
The mobject linked to this instance.
|
||||
"""
|
||||
|
||||
def __init__(name: str, id: int, singleton: MyClass, mobj: Mobject = None):
|
||||
...
|
||||
def __init__(name: str, id: int, singleton: MyClass, mobj: Mobject = None): ...
|
||||
|
||||
2. The usage of ``Parameters`` on functions to specify how
|
||||
every parameter works and what it does. This should be excluded if
|
||||
148
docs/source/contributing/docs/typings.rst
Normal file
148
docs/source/contributing/docs/typings.rst
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
==============
|
||||
Adding Typings
|
||||
==============
|
||||
|
||||
.. warning::
|
||||
This section is still a work in progress.
|
||||
|
||||
Adding type hints to functions and parameters
|
||||
---------------------------------------------
|
||||
|
||||
Manim is currently in the process of adding type hints into the library. In this
|
||||
section, you will find information about the standards used and some general
|
||||
guidelines.
|
||||
|
||||
If you've never used type hints before, this is a good place to get started:
|
||||
https://realpython.com/python-type-checking/#hello-types.
|
||||
|
||||
Typing standards
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Manim uses `mypy`_ to type check its codebase. You will find a list of configuration values in the ``mypy.ini`` configuration file.
|
||||
To be able to use the newest typing features not available in the lowest
|
||||
supported Python version, make use of `typing_extensions`_.
|
||||
|
||||
To be able to use the new Union syntax (``|``) and builtins subscripting, use
|
||||
the ``from __future__ import annotations`` import.
|
||||
|
||||
.. _mypy: https://mypy-lang.org/
|
||||
.. _typing_extensions: https://pypi.org/project/typing-extensions/
|
||||
|
||||
Typing guidelines
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Manim has a dedicated :mod:`~.typing` module where type aliases are provided.
|
||||
Most of them may seem redundant, in particular the ones related to ``numpy``.
|
||||
This is in anticipation of the support for shape type hinting
|
||||
(`related issue <https://github.com/numpy/numpy/issues/16544>`_). Besides the
|
||||
pending shape support, using the correct type aliases will help users understand
|
||||
which shape should be used.
|
||||
|
||||
* For typings of generic collections, check out `this <https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes>`_
|
||||
link.
|
||||
|
||||
* Always use a type hint of ``None`` for functions that does not return
|
||||
a value (this also applies to ``__init__``), e.g.:
|
||||
|
||||
.. code:: py
|
||||
|
||||
def height(self, value) -> None:
|
||||
self.scale_to_fit_height(value)
|
||||
|
||||
* For variables representing paths, use the ``StrPath`` or ``StrOrBytesPath``
|
||||
type alias defined in the :mod:`~.typing` module.
|
||||
|
||||
* ``*args`` and ``**kwargs`` shouldn't be left untyped (in most cases you can
|
||||
use ``Any``).
|
||||
|
||||
* Following `PEP 484 <https://peps.python.org/pep-0484/#the-numeric-tower>`_,
|
||||
use ``float`` instead of ``int | float``.
|
||||
|
||||
* Use ``x | y`` instead of ``Union[x, y]``
|
||||
|
||||
* Mobjects have the typehint ``Mobject``, e.g.:
|
||||
|
||||
.. code:: py
|
||||
|
||||
def match_color(self, mobject: "Mobject"):
|
||||
"""Match the color with the color of another :class:`~.Mobject`."""
|
||||
return self.set_color(mobject.get_color())
|
||||
|
||||
* Always parametrize generics (``list[int]`` instead of ``list``,
|
||||
``type[Any]`` instead of ``type``, etc.). This also applies to callables.
|
||||
|
||||
.. code:: py
|
||||
|
||||
rate_func: Callable[[float], float] = lambda t: smooth(1 - t)
|
||||
|
||||
* Use ``TypeVar`` when you want to "link" type hints as being the same type.
|
||||
Consider ``Mobject.copy``, which returns a new instance of the same class.
|
||||
It would be type-hinted as:
|
||||
|
||||
.. code:: py
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def copy(self: T) -> T: ...
|
||||
|
||||
* Use ``typing.Iterable`` whenever the function works with *any* iterable, not a specific type.
|
||||
|
||||
* Prefer ``numpy.typing.NDArray`` over ``numpy.ndarray``
|
||||
|
||||
.. code:: py
|
||||
|
||||
import numpy as np
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import numpy.typing as npt
|
||||
|
||||
|
||||
def foo() -> npt.NDArray[float]:
|
||||
return np.array([1, 0, 1])
|
||||
|
||||
* If a method returns ``self``, use ``typing_extensions.Self``.
|
||||
|
||||
.. code:: py
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
|
||||
|
||||
class CustomMobject:
|
||||
def set_color(self, color: ManimColor) -> Self:
|
||||
...
|
||||
return self
|
||||
|
||||
* If the function returns a container of a specific length each time, consider using ``tuple`` instead of ``list``.
|
||||
|
||||
.. code:: py
|
||||
|
||||
def foo() -> tuple[float, float, float]:
|
||||
return (0, 0, 0)
|
||||
|
||||
* If a function works with a parameter as long as said parameter has a ``__getitem__``, ``__iter___`` and ``__len__`` method,
|
||||
the typehint of the parameter should be ``collections.abc.Mapping``. If it also supports ``__setitem__`` and/or ``__delitem__``, it
|
||||
should be marked as ``collections.abc.MutableMapping``.
|
||||
|
||||
* Typehinting something as ``object`` means that only attributes available on every Python object should be accessed,
|
||||
like ``__str__`` and so on. On the other hand, literally any attribute can be accessed on a variable with the ``Any`` typehint -
|
||||
it's more freeing than the ``object`` typehint, and makes mypy stop typechecking the variable. Note that whenever possible,
|
||||
try to keep typehints as specific as possible.
|
||||
|
||||
* If objects are imported purely for type hint purposes, keep it under an ``if typing.TYPE_CHECKING`` guard, to prevent them from
|
||||
being imported at runtime (helps library performance). Do not forget to use the ``from __future__ import annotations`` import to avoid having runtime ``NameError`` exceptions.
|
||||
|
||||
.. code:: py
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.typing import Vector3D
|
||||
# type stuff with Vector3D
|
||||
|
||||
Missing Sections for typehints are:
|
||||
-----------------------------------
|
||||
|
||||
* Mypy and numpy import errors: https://realpython.com/python-type-checking/#running-mypy
|
||||
* Explain ``mypy.ini`` (see above link)
|
||||
|
|
@ -28,7 +28,7 @@ Contributing
|
|||
|
||||
That being said, improving the documentation and making it more accessible is still highly encouraged.
|
||||
And even if your work gets outdated and requires change, you or someone else can simply adjust the translation.
|
||||
Your efforts are not in vail!
|
||||
Your efforts are not in vain!
|
||||
|
||||
|
||||
Voting
|
||||
|
|
|
|||
|
|
@ -5,6 +5,24 @@ If you are adding new features to manim, you should add appropriate tests for th
|
|||
manim from breaking at each change by checking that no other
|
||||
feature has been broken and/or been unintentionally modified.
|
||||
|
||||
.. warning::
|
||||
|
||||
The full tests suite requires Cairo 1.18 in order to run all tests.
|
||||
However, Cairo 1.18 may not be available from your package manager,
|
||||
like ``apt``, and it is very likely that you have an older version installed,
|
||||
e.g., 1.16. If you run tests with a version prior to 1.18,
|
||||
many tests will be skipped. Those tests are not skipped in the online CI.
|
||||
|
||||
If you want to run all tests locally, you need to install Cairo 1.18 or above.
|
||||
You can do so by compiling Cairo from source:
|
||||
|
||||
1. download ``cairo-1.18.0.tar.xz`` from
|
||||
`here <https://www.cairographics.org/releases/>`_.
|
||||
and uncompress it;
|
||||
2. open the INSTALL file and follow the instructions (you might need to install
|
||||
``meson`` and ``ninja``);
|
||||
3. run the tests suite and verify that the Cairo version is correct.
|
||||
|
||||
How Manim tests
|
||||
---------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
==============
|
||||
Adding Typings
|
||||
==============
|
||||
|
||||
Adding type hints to functions and parameters
|
||||
---------------------------------------------
|
||||
|
||||
.. warning::
|
||||
This section is still a work in progress.
|
||||
|
||||
If you've never used type hints before, this is a good place to get started:
|
||||
https://realpython.com/python-type-checking/#hello-types.
|
||||
|
||||
When adding type hints to manim, there are some guidelines that should be followed:
|
||||
|
||||
* Coordinates have the typehint ``Sequence[float]``, e.g.
|
||||
|
||||
.. code:: py
|
||||
|
||||
def set_points_as_corners(self, points: Sequence[float]) -> "VMobject":
|
||||
"""Given an array of points, set them as corner of the Vmobject."""
|
||||
|
||||
* ``**kwargs`` has no typehint
|
||||
|
||||
* Mobjects have the typehint "Mobject", e.g.
|
||||
|
||||
.. code:: py
|
||||
|
||||
def match_color(self, mobject: "Mobject"):
|
||||
"""Match the color with the color of another :class:`~.Mobject`."""
|
||||
return self.set_color(mobject.get_color())
|
||||
|
||||
* Colors have the typehint ``Color``, e.g.
|
||||
|
||||
.. code:: py
|
||||
|
||||
def set_color(self, color: Color = YELLOW_C, family: bool = True):
|
||||
"""Condition is function which takes in one arguments, (x, y, z)."""
|
||||
|
||||
* As ``float`` and ``Union[int, float]`` are the same, use only ``float``
|
||||
|
||||
* For numpy arrays use the typehint ``np.ndarray``
|
||||
|
||||
* Functions that does not return a value should get the type hint ``None``. (This annotations help catch the kinds of subtle bugs where you are trying to use a meaningless return value. )
|
||||
|
||||
.. code:: py
|
||||
|
||||
def height(self, value) -> None:
|
||||
self.scale_to_fit_height(value)
|
||||
|
||||
* Parameters that are None by default should get the type hint ``Optional``
|
||||
|
||||
.. code:: py
|
||||
|
||||
def rotate(
|
||||
self,
|
||||
angle,
|
||||
axis=OUT,
|
||||
about_point: Optional[Sequence[float]] = None,
|
||||
**kwargs,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
* The ``__init__()`` method always should have None as its return type.
|
||||
|
||||
* Functions and lambda functions should get the typehint ``Callable``
|
||||
|
||||
.. code:: py
|
||||
|
||||
rate_func: Callable[[float], float] = lambda t: smooth(1 - t)
|
||||
|
||||
|
||||
* Assuming that typical path objects are either Paths or strs, one can use the typehint ``typing.Union[str, pathlib.Path]``
|
||||
|
||||
.. note::
|
||||
As a helper for tool for typesets, you can use `typestring-parser
|
||||
<https://github.com/Dominik1123/typestring-parser>`_
|
||||
which can be accessed by first installing it via ``pip`` - ``pip install typestring-parser`` and
|
||||
then using ``from typestring_parser import parse``.
|
||||
|
||||
.. doctest::
|
||||
:options: +SKIP
|
||||
|
||||
>>> from typestring_parser import parse
|
||||
>>> parse("int")
|
||||
<class 'int'>
|
||||
>>> parse("int or str")
|
||||
typing.Union[int, str]
|
||||
>>> parse("list of str or str")
|
||||
typing.Union[typing.List[str], str]
|
||||
>>> parse("list of (int, str)")
|
||||
typing.List[typing.Tuple[int, str]]
|
||||
|
||||
Missing Sections for typehints are:
|
||||
-----------------------------------
|
||||
* Tools for typehinting
|
||||
* Link to MyPy
|
||||
* Mypy and numpy import errors: https://realpython.com/python-type-checking/#running-mypy
|
||||
* Where to find the alias
|
||||
* When to use Object and when to use "Object".
|
||||
* The use of a TypeVar on the type hints for copy().
|
||||
* The definition and use of Protocols (like Sized, or Sequence, or Iterable...)
|
||||
|
|
@ -94,7 +94,7 @@ Basic Concepts
|
|||
self.add(image, image.background_rectangle)
|
||||
|
||||
.. manim:: BooleanOperations
|
||||
:ref_classes: Union Intersection Exclusion
|
||||
:ref_classes: Union Intersection Exclusion Difference
|
||||
|
||||
class BooleanOperations(Scene):
|
||||
def construct(self):
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ and then record it during rendering:
|
|||
from manim_voiceover import VoiceoverScene
|
||||
from manim_voiceover.services.recorder import RecorderService
|
||||
|
||||
|
||||
# Simply inherit from VoiceoverScene instead of Scene to get all the
|
||||
# voiceover functionality.
|
||||
class RecorderExample(VoiceoverScene):
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ is imported and Python has read and defined the ``ToyExample`` class (but,
|
|||
read carefully: *no instance of this class has been created yet*).
|
||||
|
||||
At this point, the interpreter is about to enter the ``tempconfig`` context
|
||||
manager. Even if you have not seen Manim's ``tempconfig`` before, it's name
|
||||
manager. Even if you have not seen Manim's ``tempconfig`` before, its name
|
||||
already suggests what it does: it creates a copy of the current state of the
|
||||
configuration, applies the changes to the key-value pairs in the passed
|
||||
dictionary, and upon leaving the context the original version of the
|
||||
|
|
@ -266,7 +266,7 @@ The scene then asks its renderer to initialize the scene by calling
|
|||
|
||||
Inspecting both the default Cairo renderer and the OpenGL renderer shows that the ``init_scene``
|
||||
method effectively makes the renderer instantiate a :class:`.SceneFileWriter` object, which
|
||||
basically is Manim's interface to ``ffmpeg`` and actually writes the movie file. The Cairo
|
||||
basically is Manim's interface to ``libav`` (FFMPEG) and actually writes the movie file. The Cairo
|
||||
renderer (see the implementation `here <https://github.com/ManimCommunity/manim/blob/main/manim/renderer/cairo_renderer.py>`__) does not require any further initialization. The OpenGL renderer
|
||||
does some additional setup to enable the realtime rendering preview window, which we do not go
|
||||
into detail further here.
|
||||
|
|
@ -310,8 +310,8 @@ the order they are called, these customizable methods are:
|
|||
After these three methods are run, the animations have been fully rendered,
|
||||
and Manim calls :meth:`.CairoRenderer.scene_finished` to gracefully
|
||||
complete the rendering process. This checks whether any animations have been
|
||||
played -- and if so, it tells the :class:`.SceneFileWriter` to close the pipe
|
||||
to ``ffmpeg``. If not, Manim assumes that a static image should be output
|
||||
played -- and if so, it tells the :class:`.SceneFileWriter` to close the output
|
||||
file. If not, Manim assumes that a static image should be output
|
||||
which it then renders using the same strategy by calling the render loop
|
||||
(see below) once.
|
||||
|
||||
|
|
@ -762,10 +762,10 @@ to learn more, the :func:`.get_hash_from_play_call` function in the
|
|||
mechanism.
|
||||
|
||||
In the event that the animation has to be rendered, the renderer asks
|
||||
its :class:`.SceneFileWriter` to start a writing process. The process
|
||||
is started by a call to ``ffmpeg`` and opens a pipe to which rendered
|
||||
raw frames can be written. As long as the pipe is open, the process
|
||||
can be accessed via the ``writing_process`` attribute of the file writer.
|
||||
its :class:`.SceneFileWriter` to open an output container. The process
|
||||
is started by a call to ``libav`` and opens a container to which rendered
|
||||
raw frames can be written. As long as the output is open, the container
|
||||
can be accessed via the ``output_container`` attribute of the file writer.
|
||||
With the writing process in place, the renderer then asks the scene
|
||||
to "begin" the animations.
|
||||
|
||||
|
|
@ -815,7 +815,7 @@ time is extracted (3 seconds long) and stored in
|
|||
skip (it should not), then whether the animation is already
|
||||
cached (it is not). The corresponding animation hash value is
|
||||
determined and passed to the file writer, which then also calls
|
||||
``ffmpeg`` to start the writing process which waits for rendered
|
||||
``libav`` to start the writing process which waits for rendered
|
||||
frames from the library.
|
||||
|
||||
The scene then ``begin``\ s the animation: for the
|
||||
|
|
@ -1001,7 +1001,7 @@ and :meth:`.Animation.clean_up_from_scene` methods are called.
|
|||
In the end, the time progression is closed (which completes the displayed progress bar)
|
||||
in the terminal. With the closing of the time progression, the
|
||||
:meth:`.Scene.play_internal` call is completed, and we return to the renderer,
|
||||
which now orders the :class:`.SceneFileWriter` to close the movie pipe that has
|
||||
which now orders the :class:`.SceneFileWriter` to close the output container that has
|
||||
been opened for this animation: a partial movie file is written.
|
||||
|
||||
This pretty much concludes the walkthrough of a :class:`.Scene.play` call,
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ we have to add it manually.
|
|||
myTemplate = TexTemplate()
|
||||
myTemplate.add_to_preamble(r"\usepackage{mathrsfs}")
|
||||
tex = Tex(
|
||||
r"$\mathscr{H} \rightarrow \mathbb{H}$}",
|
||||
r"$\mathscr{H} \rightarrow \mathbb{H}$",
|
||||
tex_template=myTemplate,
|
||||
font_size=144,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ in the right place!
|
|||
You can also find information on Manim's docker images and (online)
|
||||
notebook environments there.
|
||||
- Want to try the library before installing it? Take a look at our
|
||||
interactive online playground at https://try.manim.community in form
|
||||
interactive online playground at https://try.manim.community in the form
|
||||
of a Jupyter notebook.
|
||||
- In our :doc:`Tutorials <tutorials/index>` section you will find a
|
||||
collection of resources that will teach you how to use Manim. In particular,
|
||||
|
|
@ -71,7 +71,7 @@ Here are some short summaries for all of the sections in this documentation:
|
|||
can be found in the :doc:`FAQ </faq/index>` section.
|
||||
- The :doc:`Reference Manual </reference>` contains a comprehensive list of all of Manim's
|
||||
(documented) modules, classes, and functions. If you are somewhat familiar with Manim's
|
||||
module structure feel free to browse the manual directly. If you are searching for
|
||||
module structure, feel free to browse the manual directly. If you are searching for
|
||||
something specific, feel free to use the documentation's search feature in the sidebar.
|
||||
Many classes and methods come with their own illustrated examples too!
|
||||
- The :doc:`Plugins </plugins>` page documents how to install, write, and distribute
|
||||
|
|
|
|||
|
|
@ -28,17 +28,25 @@ your system's Python, or via Docker).
|
|||
|
||||
.. _conda-installation:
|
||||
|
||||
Installing Manim in conda
|
||||
*************************
|
||||
Installing Manim via Conda and related environment managers
|
||||
***********************************************************
|
||||
|
||||
Conda is a package manager for Python that allows creating environments
|
||||
where all your dependencies are stored. Like this, you don't clutter up your PC with
|
||||
unwanted libraries and you can just delete the environment when you don't need it anymore.
|
||||
It is a good way to install manim since all dependencies like
|
||||
``ffmpeg``, ``pycairo``, etc. come with it.
|
||||
It is a good way to install manim since all dependencies like ``pycairo``, etc. come with it.
|
||||
Also, the installation steps are the same, no matter if you are
|
||||
on Windows, Linux, Intel Macs or on Apple Silicon.
|
||||
|
||||
.. NOTE::
|
||||
|
||||
There are various popular alternatives to Conda like
|
||||
`mamba <https://mamba.readthedocs.io/en/latest/>`__ /
|
||||
`micromamba <https://mamba.readthedocs.io/en/latest/user_guide/micromamba.html>`__,
|
||||
or `pixi <https://pixi.sh>`__.
|
||||
They all can be used to setup a suitable, isolated environment
|
||||
for your Manim projects.
|
||||
|
||||
The following pages show how to install Manim in a conda environment:
|
||||
|
||||
.. toctree::
|
||||
|
|
@ -54,12 +62,13 @@ Installing Manim locally
|
|||
************************
|
||||
|
||||
Manim is a Python library, and it can be
|
||||
`installed via pip <https://pypi.org/project/manim/>`__. However,
|
||||
installed via `pip <https://pypi.org/project/manim/>`__
|
||||
or `conda <https://anaconda.org/conda-forge/manim/>`__. However,
|
||||
in order for Manim to work properly, some additional system
|
||||
dependencies need to be installed first. The following pages have
|
||||
operating system specific instructions for you to follow.
|
||||
|
||||
Manim requires Python version ``3.8`` or above to run.
|
||||
Manim requires Python version ``3.9`` or above to run.
|
||||
|
||||
.. hint::
|
||||
|
||||
|
|
|
|||
|
|
@ -4,18 +4,21 @@ Conda
|
|||
Required Dependencies
|
||||
---------------------
|
||||
|
||||
To create a conda environment, you must first install
|
||||
`conda <https://docs.conda.io/projects/conda/en/latest/user-guide/install/download.html>`__
|
||||
or `mamba <https://mamba.readthedocs.io/en/latest/installation.html>`__,
|
||||
the two most popular conda clients.
|
||||
There are several package managers that work with conda packages,
|
||||
namely `conda <https://docs.conda.io/projects/conda/en/latest/user-guide/install/download.html>`__,
|
||||
`mamba <https://mamba.readthedocs.io>`__ and `pixi <https://pixi.sh>`__.
|
||||
|
||||
After installing conda, you can create a new environment and install ``manim`` inside by running
|
||||
After installing your package manager, you can create a new environment and install ``manim`` inside by running
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# using conda or mamba
|
||||
conda create -n my-manim-environment
|
||||
conda activate my-manim-environment
|
||||
conda install -c conda-forge manim
|
||||
# using pixi
|
||||
pixi init
|
||||
pixi add manim
|
||||
|
||||
Since all dependencies (except LaTeX) are handled by conda, you don't need to worry
|
||||
about needing to install additional dependencies.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ modify to your liking. First, run
|
|||
|
||||
.. code-block:: sh
|
||||
|
||||
docker run -it --name my-manim-container -v "/full/path/to/your/directory:/manim" manimcommunity/manim /bin/bash
|
||||
docker run -it --name my-manim-container -v "/full/path/to/your/directory:/manim" manimcommunity/manim bash
|
||||
|
||||
|
||||
to obtain an interactive shell inside your container allowing you
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ then execute it.
|
|||
.. code-block::
|
||||
|
||||
!sudo apt update
|
||||
!sudo apt install libcairo2-dev ffmpeg \
|
||||
!sudo apt install libcairo2-dev \
|
||||
texlive texlive-latex-extra texlive-fonts-extra \
|
||||
texlive-latex-recommended texlive-science \
|
||||
tipa libpango1.0-dev
|
||||
!pip install manim
|
||||
!pip install IPython --upgrade
|
||||
!pip install IPython==8.21.0
|
||||
|
||||
You should start to see Colab installing all the dependencies specified
|
||||
in these commands. After the execution has completed, you will be prompted
|
||||
|
|
|
|||
|
|
@ -5,10 +5,9 @@ The installation instructions depend on your particular operating
|
|||
system and package manager. If you happen to know exactly what you are doing,
|
||||
you can also simply ensure that your system has:
|
||||
|
||||
- a reasonably recent version of Python 3 (3.8 or above),
|
||||
- a reasonably recent version of Python 3 (3.9 or above),
|
||||
- with working Cairo bindings in the form of
|
||||
`pycairo <https://cairographics.org/pycairo/>`__,
|
||||
- FFmpeg accessible from the command line as ``ffmpeg``,
|
||||
- and `Pango <https://pango.gnome.org>`__ headers.
|
||||
|
||||
Then, installing Manim is just a matter of running:
|
||||
|
|
@ -33,13 +32,13 @@ Required Dependencies
|
|||
apt – Ubuntu / Mint / Debian
|
||||
****************************
|
||||
|
||||
To first update your sources, and then install Cairo, Pango, and FFmpeg
|
||||
To first update your sources, and then install Cairo and Pango
|
||||
simply run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt update
|
||||
sudo apt install build-essential python3-dev libcairo2-dev libpango1.0-dev ffmpeg
|
||||
sudo apt install build-essential python3-dev libcairo2-dev libpango1.0-dev
|
||||
|
||||
If you don't have python3-pip installed, install it via:
|
||||
|
||||
|
|
@ -72,14 +71,6 @@ need the Python development headers:
|
|||
|
||||
sudo dnf install python3-devel
|
||||
|
||||
FFmpeg is only available via the RPMfusion repository which you have to
|
||||
configure first – please consult https://rpmfusion.org/Configuration/ for
|
||||
instructions. Then, install FFmpeg:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo dnf install ffmpeg
|
||||
|
||||
At this point you have all required dependencies and can install
|
||||
Manim by running:
|
||||
|
||||
|
|
@ -100,12 +91,12 @@ pacman – Arch / Manjaro
|
|||
|
||||
If you don't want to use the packaged version from AUR, here is what
|
||||
you need to do manually: Update your package sources, then install
|
||||
Cairo, Pango, and FFmpeg:
|
||||
Cairo and Pango:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo pacman -Syu
|
||||
sudo pacman -S cairo pango ffmpeg
|
||||
sudo pacman -S cairo pango
|
||||
|
||||
If you don't have ``python-pip`` installed, get it by running:
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ follow `Homebrew's installation instructions <https://docs.brew.sh/Installation>
|
|||
Required Dependencies
|
||||
---------------------
|
||||
|
||||
To install all required dependencies for installing Manim (namely: ffmpeg, Python,
|
||||
To install all required dependencies for installing Manim (namely: Python,
|
||||
and some required Python packages), run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
brew install py3cairo ffmpeg
|
||||
brew install py3cairo
|
||||
|
||||
On *Apple Silicon* based machines (i.e., devices with the M1 chip or similar; if
|
||||
you are unsure which processor you have check by opening the Apple menu, select
|
||||
|
|
|
|||
|
|
@ -3,11 +3,8 @@ Windows
|
|||
|
||||
The easiest way of installing Manim and its dependencies is by using a
|
||||
package manager like `Chocolatey <https://chocolatey.org/>`__
|
||||
or `Scoop <https://scoop.sh>`__. If you are not afraid of editing
|
||||
your System's ``PATH``, a manual installation is also possible.
|
||||
In fact, if you already have an existing Python
|
||||
installation (3.8 or above), it might be the easiest way to get
|
||||
everything up and running.
|
||||
or `Scoop <https://scoop.sh>`__, especially if you need optional dependencies
|
||||
like LaTeX support.
|
||||
|
||||
If you choose to use one of the package managers, please follow
|
||||
their installation instructions
|
||||
|
|
@ -19,7 +16,7 @@ to make one of them available on your system.
|
|||
Required Dependencies
|
||||
---------------------
|
||||
|
||||
Manim requires a recent version of Python (3.8 or above) and ``ffmpeg``
|
||||
Manim requires a recent version of Python (3.9 or above)
|
||||
in order to work.
|
||||
|
||||
Chocolatey
|
||||
|
|
@ -34,53 +31,11 @@ Manim can be installed via Chocolatey simply by running:
|
|||
That's it, no further steps required. You can continue with installing
|
||||
the :ref:`optional dependencies <win-optional-dependencies>` below.
|
||||
|
||||
Scoop
|
||||
*****
|
||||
|
||||
While there is no recipe for installing Manim with Scoop directly,
|
||||
you can install all requirements by running:
|
||||
|
||||
.. code-block:: powershell
|
||||
|
||||
scoop install python ffmpeg
|
||||
|
||||
and then Manim can be installed by running:
|
||||
|
||||
.. code-block:: powershell
|
||||
|
||||
python -m pip install manim
|
||||
|
||||
Manim should now be installed on your system. Continue reading
|
||||
the :ref:`optional dependencies <win-optional-dependencies>` section
|
||||
below.
|
||||
|
||||
Winget
|
||||
******
|
||||
|
||||
While there is no recipe for installing Manim with Winget directly,
|
||||
you can install all requirements by running:
|
||||
|
||||
.. code-block:: powershell
|
||||
|
||||
winget install python
|
||||
winget install ffmpeg
|
||||
|
||||
and then Manim can be installed by running:
|
||||
|
||||
.. code-block:: powershell
|
||||
|
||||
python -m pip install manim
|
||||
|
||||
Manim should now be installed on your system. Continue reading
|
||||
the :ref:`optional dependencies <win-optional-dependencies>` section
|
||||
below.
|
||||
|
||||
|
||||
Manual Installation
|
||||
*******************
|
||||
Pip
|
||||
***
|
||||
|
||||
As mentioned above, Manim needs a reasonably recent version of
|
||||
Python 3 (3.8 or above) and FFmpeg.
|
||||
Python 3 (3.9 or above).
|
||||
|
||||
**Python:** Head over to https://www.python.org, download an installer
|
||||
for a recent version of Python, and follow its instructions to get Python
|
||||
|
|
@ -94,35 +49,16 @@ installed on your system.
|
|||
install Python directly from the
|
||||
`official website <https://www.python.org>`__.
|
||||
|
||||
**FFmpeg:** In order to install FFmpeg, you can get a
|
||||
pre-compiled and ready-to-use version from one of the resources
|
||||
linked at https://ffmpeg.org/download.html#build-windows, such as
|
||||
`the version available here
|
||||
<https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.7z>`__
|
||||
(recommended), or if you know exactly what you are doing
|
||||
you can alternatively get the source code
|
||||
from https://ffmpeg.org/download.html and compile it yourself.
|
||||
|
||||
|
||||
After downloading the pre-compiled archive,
|
||||
`unzip it <https://www.7-zip.org>`__ and, if you like, move the
|
||||
extracted directory to some more permanent place (e.g.,
|
||||
``C:\Program Files\``). Next, edit the ``PATH`` environment variable:
|
||||
first, visit ``Control Panel`` > ``System`` > ``System settings`` >
|
||||
``Environment Variables``, then add the full path to the ``bin``
|
||||
directory inside of the (moved) ffmpeg directory to the
|
||||
``PATH`` variable. Finally, save your changes and exit.
|
||||
|
||||
If you now open a new command line prompt (or PowerShell) and
|
||||
run ``ffmpeg``, the command should be recognized.
|
||||
|
||||
At this point, you have all the required dependencies and can now
|
||||
install Manim via
|
||||
Then, Manim can be installed via Pip simply by running:
|
||||
|
||||
.. code-block:: powershell
|
||||
|
||||
python -m pip install manim
|
||||
|
||||
Manim should now be installed on your system. Continue reading
|
||||
the :ref:`optional dependencies <win-optional-dependencies>` section
|
||||
below.
|
||||
|
||||
|
||||
.. _win-optional-dependencies:
|
||||
|
||||
|
|
|
|||
|
|
@ -99,40 +99,18 @@ directory structure, build system, and naming are completely up to your
|
|||
discretion as an author. The aforementioned template plugin is only a model
|
||||
using Poetry since this is the build system Manim uses. The plugin's `entry
|
||||
point <https://packaging.python.org/specifications/entry-points/>`_ can be
|
||||
specified in poetry as:
|
||||
specified in Poetry as:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.poetry.plugins."manim.plugins"]
|
||||
"name" = "object_reference"
|
||||
|
||||
Here ``name`` is the name of the module of the plugin.
|
||||
.. versionremoved:: 0.19.0
|
||||
|
||||
Here ``object_reference`` can point to either a function in a module or a module
|
||||
itself. For example,
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.poetry.plugins."manim.plugins"]
|
||||
"manim_plugintemplate" = "manim_plugintemplate"
|
||||
|
||||
Here a module is used as ``object_reference``, and when this plugin is enabled,
|
||||
Manim will look for ``__all__`` keyword defined in ``manim_plugintemplate`` and
|
||||
everything as a global variable one by one.
|
||||
|
||||
If ``object_reference`` is a function, Manim calls the function and expects the
|
||||
function to return a list of modules or functions that need to be defined globally.
|
||||
|
||||
For example,
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[tool.poetry.plugins."manim.plugins"]
|
||||
"manim_plugintemplate" = "manim_awesomeplugin.imports:setup_things"
|
||||
|
||||
Here, Manim will call the function ``setup_things`` defined in
|
||||
``manim_awesomeplugin.imports`` and calls that. It returns a list of function or
|
||||
modules which will be imported globally.
|
||||
Plugins should be imported explicitly to be usable in user code. The plugin
|
||||
system will probably be refactored in the future to provide a more structured
|
||||
interface.
|
||||
|
||||
A note on Renderer Compatibility
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -9,23 +9,25 @@ Module Index
|
|||
.. autosummary::
|
||||
:toctree: ../reference
|
||||
|
||||
constants
|
||||
~utils.bezier
|
||||
~utils.color
|
||||
~utils.commands
|
||||
~utils.config_ops
|
||||
~utils.deprecation
|
||||
constants
|
||||
~utils.debug
|
||||
~utils.deprecation
|
||||
~utils.docbuild
|
||||
~utils.hashing
|
||||
~utils.ipython_magic
|
||||
~utils.images
|
||||
~utils.ipython_magic
|
||||
~utils.iterables
|
||||
~utils.paths
|
||||
~utils.rate_functions
|
||||
~utils.simple_functions
|
||||
~utils.sounds
|
||||
~utils.space_ops
|
||||
~utils.testing
|
||||
~utils.tex
|
||||
~utils.tex_templates
|
||||
~utils.tex_file_writing
|
||||
~utils.tex_templates
|
||||
typing
|
||||
|
|
|
|||
|
|
@ -376,13 +376,13 @@ and :meth:`~.Mobject.get_start`. Here is an example of some important coordinate
|
|||
|
||||
class MobjectExample(Scene):
|
||||
def construct(self):
|
||||
p1= [-1,-1,0]
|
||||
p2= [1,-1,0]
|
||||
p3= [1,1,0]
|
||||
p4= [-1,1,0]
|
||||
a = Line(p1,p2).append_points(Line(p2,p3).points).append_points(Line(p3,p4).points)
|
||||
point_start= a.get_start()
|
||||
point_end = a.get_end()
|
||||
p1 = [-1,-1, 0]
|
||||
p2 = [ 1,-1, 0]
|
||||
p3 = [ 1, 1, 0]
|
||||
p4 = [-1, 1, 0]
|
||||
a = Line(p1,p2).append_points(Line(p2,p3).points).append_points(Line(p3,p4).points)
|
||||
point_start = a.get_start()
|
||||
point_end = a.get_end()
|
||||
point_center = a.get_center()
|
||||
self.add(Text(f"a.get_start() = {np.round(point_start,2).tolist()}", font_size=24).to_edge(UR).set_color(YELLOW))
|
||||
self.add(Text(f"a.get_end() = {np.round(point_end,2).tolist()}", font_size=24).next_to(self.mobjects[-1],DOWN).set_color(RED))
|
||||
|
|
@ -425,8 +425,8 @@ function of numpy:
|
|||
self.camera.background_color = WHITE
|
||||
m1a = Square().set_color(RED).shift(LEFT)
|
||||
m1b = Circle().set_color(RED).shift(LEFT)
|
||||
m2a= Square().set_color(BLUE).shift(RIGHT)
|
||||
m2b= Circle().set_color(BLUE).shift(RIGHT)
|
||||
m2a = Square().set_color(BLUE).shift(RIGHT)
|
||||
m2b = Circle().set_color(BLUE).shift(RIGHT)
|
||||
|
||||
points = m2a.points
|
||||
points = np.roll(points, int(len(points)/4), axis=0)
|
||||
|
|
|
|||
|
|
@ -276,25 +276,28 @@ When executing the command
|
|||
|
||||
manim -pql scene.py SquareToCircle
|
||||
|
||||
it was necessary to specify which ``Scene`` class to render. This is because a
|
||||
single file can contain more than one ``Scene`` class. If your file contains
|
||||
multiple ``Scene`` classes, and you want to render them all, you can use the
|
||||
``-a`` flag.
|
||||
it specifies the scene to render. This is not necessary now. When a single
|
||||
file contains only one ``Scene`` class, it will just render the ``Scene``
|
||||
class. When a single file contains more than one ``Scene`` class, manim will
|
||||
let you choose a ``Scene`` class. If your file contains multiple ``Scene``
|
||||
classes, and you want to render them all, you can use the ``-a`` flag.
|
||||
|
||||
As discussed previously, the ``-ql`` specifies low render quality. This does
|
||||
not look very good, but is very useful for rapid prototyping and testing. The
|
||||
other options that specify render quality are ``-qm``, ``-qh``, and ``-qk`` for
|
||||
medium, high, and 4k quality, respectively.
|
||||
As discussed previously, the ``-ql`` specifies low render quality (854x480
|
||||
15FPS). This does not look very good, but is very useful for rapid
|
||||
prototyping and testing. The other options that specify render quality are
|
||||
``-qm``, ``-qh``, ``-qp`` and ``-qk`` for medium (1280x720 30FPS), high
|
||||
(1920x1080 60FPS), 2k (2560x1440 60FPS) and 4k quality (3840x2160 60FPS),
|
||||
respectively.
|
||||
|
||||
The ``-p`` flag plays the animation once it is rendered. If you want to open
|
||||
the file browser at the location of the animation instead of playing it, you
|
||||
can use the ``-f`` flag. You can also omit these two flags.
|
||||
|
||||
Finally, by default manim will output .mp4 files. If you want your animations
|
||||
in .gif format instead, use the ``-i`` flag. The output files will be in the
|
||||
same folder as the .mp4 files, and with the same name, but a different file
|
||||
extension.
|
||||
in .gif format instead, use the ``--format gif`` flag. The output files will
|
||||
be in the same folder as the .mp4 files, and with the same name, but a
|
||||
different file extension.
|
||||
|
||||
This was a quick review of some of the most frequent command-line flags. For a
|
||||
thorough review of all flags available, see the
|
||||
:doc:`thematic guide on Manim's configuration system </guides/configuration>`.
|
||||
This was a quick review of some of the most frequent command-line flags.
|
||||
For a thorough review of all flags available, see the :doc:`thematic guide on
|
||||
Manim's configuration system </guides/configuration>`.
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ Now let's look at the next two lines:
|
|||
|
||||
class CreateCircle(Scene):
|
||||
def construct(self):
|
||||
...
|
||||
[...]
|
||||
|
||||
Most of the time, the code for scripting an animation is entirely contained within
|
||||
the :meth:`~.Scene.construct` method of a :class:`.Scene` class.
|
||||
|
|
@ -268,11 +268,9 @@ and animating those method calls with ``.animate``.
|
|||
|
||||
self.play(Create(square)) # show the square on screen
|
||||
self.play(square.animate.rotate(PI / 4)) # rotate the square
|
||||
self.play(Transform(square, circle)) # transform the square into a circle
|
||||
self.play(
|
||||
ReplacementTransform(square, circle)
|
||||
) # transform the square into a circle
|
||||
self.play(
|
||||
circle.animate.set_fill(PINK, opacity=0.5)
|
||||
square.animate.set_fill(PINK, opacity=0.5)
|
||||
) # color the circle on screen
|
||||
|
||||
2. Render ``AnimatedSquareToCircle`` by running the following command in the command line:
|
||||
|
|
@ -293,8 +291,8 @@ The following animation will render:
|
|||
|
||||
self.play(Create(square)) # show the square on screen
|
||||
self.play(square.animate.rotate(PI / 4)) # rotate the square
|
||||
self.play(ReplacementTransform(square, circle)) # transform the square into a circle
|
||||
self.play(circle.animate.set_fill(PINK, opacity=0.5)) # color the circle on screen
|
||||
self.play(Transform(square, circle)) # transform the square into a circle
|
||||
self.play(square.animate.set_fill(PINK, opacity=0.5)) # color the circle on screen
|
||||
|
||||
The first ``self.play`` creates the square. The second animates rotating it 45 degrees.
|
||||
The third transforms the square into a circle, and the last colors the circle pink.
|
||||
|
|
@ -342,12 +340,61 @@ the corners of the square appear to contract slightly as they move into the posi
|
|||
for the first square to transform into the second one.
|
||||
|
||||
In ``DifferentRotations``, the difference between ``.animate``'s interpretation of rotation and the
|
||||
``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 360 degrees
|
||||
``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 180 degrees
|
||||
are the same, so ``.animate`` tries to interpolate two identical objects and the result is the left square.
|
||||
If you find that your own usage of ``.animate`` is causing similar unwanted behavior, consider
|
||||
using conventional animation methods like the right square, which uses ``Rotate``.
|
||||
|
||||
|
||||
``Transform`` vs ``ReplacementTransform``
|
||||
*****************************************
|
||||
The difference between ``Transform`` and ``ReplacementTransform`` is that ``Transform(mob1, mob2)`` transforms the points
|
||||
(as well as other attributes like color) of ``mob1`` into the points/attributes of ``mob2``.
|
||||
|
||||
``ReplacementTransform(mob1, mob2)`` on the other hand literally replaces ``mob1`` on the scene with ``mob2``.
|
||||
|
||||
The use of ``ReplacementTransform`` or ``Transform`` is mostly up to personal preference. They can be used to accomplish the same effect, as shown below.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class TwoTransforms(Scene):
|
||||
def transform(self):
|
||||
a = Circle()
|
||||
b = Square()
|
||||
c = Triangle()
|
||||
self.play(Transform(a, b))
|
||||
self.play(Transform(a, c))
|
||||
self.play(FadeOut(a))
|
||||
|
||||
def replacement_transform(self):
|
||||
a = Circle()
|
||||
b = Square()
|
||||
c = Triangle()
|
||||
self.play(ReplacementTransform(a, b))
|
||||
self.play(ReplacementTransform(b, c))
|
||||
self.play(FadeOut(c))
|
||||
|
||||
def construct(self):
|
||||
self.transform()
|
||||
self.wait(0.5) # wait for 0.5 seconds
|
||||
self.replacement_transform()
|
||||
|
||||
|
||||
However, in some cases it is more beneficial to use ``Transform``, like when you are transforming several mobjects one after the other.
|
||||
The code below avoids having to keep a reference to the last mobject that was transformed.
|
||||
|
||||
.. manim:: TransformCycle
|
||||
|
||||
class TransformCycle(Scene):
|
||||
def construct(self):
|
||||
a = Circle()
|
||||
t1 = Square()
|
||||
t2 = Triangle()
|
||||
self.add(a)
|
||||
self.wait()
|
||||
for t in [t1,t2]:
|
||||
self.play(Transform(a,t))
|
||||
|
||||
************
|
||||
You're done!
|
||||
************
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ class SpiralInExample(Scene):
|
|||
],
|
||||
color=PURPLE_B,
|
||||
fill_opacity=1,
|
||||
stroke_width=0
|
||||
stroke_width=0,
|
||||
).shift(UP + 2 * RIGHT)
|
||||
shapes = VGroup(triangle, square, circle, pentagon, pi)
|
||||
self.play(SpiralIn(shapes, fade_in_fraction=0.9))
|
||||
|
|
@ -167,8 +167,8 @@ Triangle.set_default(stroke_width=20)
|
|||
class LineJoints(Scene):
|
||||
def construct(self):
|
||||
t1 = Triangle()
|
||||
t2 = Triangle(line_join=LineJointType.ROUND)
|
||||
t3 = Triangle(line_join=LineJointType.BEVEL)
|
||||
t2 = Triangle(joint_type=LineJointType.ROUND)
|
||||
t3 = Triangle(joint_type=LineJointType.BEVEL)
|
||||
|
||||
grp = VGroup(t1, t2, t3).arrange(RIGHT)
|
||||
grp.set(width=config.frame_width - 1)
|
||||
|
|
|
|||
|
|
@ -2,24 +2,18 @@ import time
|
|||
|
||||
import numpy as np
|
||||
import pyglet
|
||||
from PIL import Image
|
||||
from pyglet import shapes
|
||||
from pyglet.gl import Config
|
||||
from pyglet.window import Window
|
||||
|
||||
import manim.utils.color.manim_colors as col
|
||||
from manim._config import config, tempconfig
|
||||
from manim.animation.creation import Create, DrawBorderThenFill, Write
|
||||
from manim.animation.fading import FadeIn
|
||||
from manim.animation.transform import Transform
|
||||
from manim._config import tempconfig
|
||||
from manim.animation.creation import DrawBorderThenFill
|
||||
from manim.camera.camera import Camera
|
||||
from manim.constants import LEFT, OUT, RIGHT, UP
|
||||
from manim.mobject.geometry.arc import Circle
|
||||
from manim.mobject.geometry.polygram import Square
|
||||
from manim.mobject.logo import ManimBanner
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
|
||||
from manim.mobject.text.numbers import DecimalNumber
|
||||
from manim.mobject.text.text_mobject import Text
|
||||
from manim.renderer.opengl_renderer import OpenGLRenderer
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ class InteractiveDevelopment(Scene):
|
|||
self.play(Create(square))
|
||||
self.wait()
|
||||
|
||||
# This opens an iPython termnial where you can keep writing
|
||||
# This opens an iPython terminal where you can keep writing
|
||||
# lines as if they were part of this construct method.
|
||||
# In particular, 'square', 'circle' and 'self' will all be
|
||||
# part of the local namespace in that terminal.
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
import time
|
||||
|
||||
import numpy as np
|
||||
import pyglet
|
||||
from PIL import Image
|
||||
from pyglet import shapes
|
||||
from pyglet.gl import Config
|
||||
from pyglet.window import Window
|
||||
|
||||
import manim.utils.color.manim_colors as col
|
||||
from manim._config import config, tempconfig
|
||||
from manim.camera.camera import OpenGLCamera, OpenGLCameraFrame
|
||||
from manim._config import tempconfig
|
||||
from manim.camera.camera import OpenGLCameraFrame
|
||||
from manim.constants import OUT, RIGHT, UP
|
||||
from manim.mobject.geometry.arc import Circle
|
||||
from manim.mobject.geometry.polygram import Square
|
||||
from manim.mobject.logo import ManimBanner
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
|
||||
from manim.mobject.text.numbers import DecimalNumber
|
||||
from manim.mobject.text.text_mobject import Text
|
||||
from manim.renderer.opengl_renderer import OpenGLRenderer
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pkg_resources
|
||||
from importlib.metadata import version
|
||||
|
||||
__version__: str = pkg_resources.get_distribution(__name__).version
|
||||
__version__ = version(__name__)
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
# isort: off
|
||||
|
||||
# Importing the config module should be the first thing we do, since other
|
||||
|
|
@ -20,6 +16,7 @@ from ._config import *
|
|||
from .utils.commands import *
|
||||
|
||||
# isort: on
|
||||
import numpy as np
|
||||
|
||||
from .animation.animation import *
|
||||
from .animation.changing import *
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
import click
|
||||
import cloup
|
||||
|
||||
|
|
@ -10,18 +8,20 @@ from .cli.cfg.group import cfg
|
|||
from .cli.checkhealth.commands import checkhealth
|
||||
from .cli.default_group import DefaultGroup
|
||||
from .cli.init.commands import init
|
||||
from .cli.new.group import new
|
||||
from .cli.plugins.commands import plugins
|
||||
from .cli.render.commands import render
|
||||
from .constants import EPILOG
|
||||
|
||||
|
||||
def exit_early(ctx, param, value):
|
||||
def show_splash(ctx, param, value):
|
||||
if value:
|
||||
sys.exit()
|
||||
console.print(f"Manim Community [green]v{__version__}[/green]\n")
|
||||
|
||||
|
||||
console.print(f"Manim Community [green]v{__version__}[/green]\n")
|
||||
def print_version_and_exit(ctx, param, value):
|
||||
show_splash(ctx, param, value)
|
||||
if value:
|
||||
ctx.exit()
|
||||
|
||||
|
||||
@cloup.group(
|
||||
|
|
@ -35,15 +35,24 @@ console.print(f"Manim Community [green]v{__version__}[/green]\n")
|
|||
"is specified. Run 'manim render --help' if you would like to know what the "
|
||||
f"'-ql' or '-p' flags do, for example.\n\n{EPILOG}",
|
||||
)
|
||||
@click.option(
|
||||
@cloup.option(
|
||||
"--version",
|
||||
is_flag=True,
|
||||
help="Show version and exit.",
|
||||
callback=exit_early,
|
||||
callback=print_version_and_exit,
|
||||
is_eager=True,
|
||||
expose_value=False,
|
||||
)
|
||||
@click.pass_context
|
||||
@click.option(
|
||||
"--show-splash/--hide-splash",
|
||||
is_flag=True,
|
||||
default=True,
|
||||
help="Print splash message with version information.",
|
||||
callback=show_splash,
|
||||
is_eager=True,
|
||||
expose_value=False,
|
||||
)
|
||||
@cloup.pass_context
|
||||
def main(ctx):
|
||||
"""The entry point for manim."""
|
||||
pass
|
||||
|
|
@ -53,7 +62,6 @@ main.add_command(checkhealth)
|
|||
main.add_command(cfg)
|
||||
main.add_command(plugins)
|
||||
main.add_command(init)
|
||||
main.add_command(new)
|
||||
main.add_command(render)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from contextlib import _GeneratorContextManager, contextmanager
|
||||
from collections.abc import Generator
|
||||
from contextlib import contextmanager
|
||||
from typing import Any
|
||||
|
||||
from .cli_colors import parse_cli_ctx
|
||||
from .logger_utils import make_logger
|
||||
|
|
@ -20,7 +22,6 @@ __all__ = [
|
|||
]
|
||||
|
||||
parser = make_config_parser()
|
||||
logger: logging.Logger
|
||||
|
||||
# The logger can be accessed from anywhere as manim.logger, or as
|
||||
# logging.getLogger("manim"). The console must be accessed as manim.console.
|
||||
|
|
@ -36,12 +37,14 @@ logging.getLogger("PIL").setLevel(logging.INFO)
|
|||
logging.getLogger("matplotlib").setLevel(logging.INFO)
|
||||
|
||||
config = ManimConfig().digest_parser(parser)
|
||||
# TODO: to be used in the future - see PR #620
|
||||
# https://github.com/ManimCommunity/manim/pull/620
|
||||
frame = ManimFrame(config)
|
||||
|
||||
|
||||
# This has to go here because it needs access to this module's config
|
||||
@contextmanager
|
||||
def tempconfig(temp: ManimConfig | dict) -> _GeneratorContextManager:
|
||||
def tempconfig(temp: ManimConfig | dict[str, Any]) -> Generator[None, None, None]:
|
||||
"""Context manager that temporarily modifies the global ``config`` object.
|
||||
|
||||
Inside the ``with`` statement, the modified config will be used. After
|
||||
|
|
@ -65,7 +68,6 @@ def tempconfig(temp: ManimConfig | dict) -> _GeneratorContextManager:
|
|||
8.0
|
||||
>>> with tempconfig({"frame_height": 100.0}):
|
||||
... print(config["frame_height"])
|
||||
...
|
||||
100.0
|
||||
>>> config["frame_height"]
|
||||
8.0
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
|
||||
from cloup import Context, HelpFormatter, HelpTheme, Style
|
||||
|
||||
__all__ = ["parse_cli_ctx"]
|
||||
|
||||
def parse_cli_ctx(parser: configparser.ConfigParser) -> Context:
|
||||
formatter_settings = {
|
||||
|
||||
def parse_cli_ctx(parser: configparser.SectionProxy) -> Context:
|
||||
formatter_settings: dict[str, str | int] = {
|
||||
"indent_increment": int(parser["indent_increment"]),
|
||||
"width": int(parser["width"]),
|
||||
"col1_max_width": int(parser["col1_max_width"]),
|
||||
|
|
@ -30,16 +34,19 @@ def parse_cli_ctx(parser: configparser.ConfigParser) -> Context:
|
|||
formatter = {}
|
||||
theme = parser["theme"] if parser["theme"] else None
|
||||
if theme is None:
|
||||
formatter = HelpFormatter().settings(
|
||||
theme=HelpTheme(**theme_settings), **formatter_settings
|
||||
formatter = HelpFormatter.settings(
|
||||
theme=HelpTheme(**theme_settings),
|
||||
**formatter_settings, # type: ignore[arg-type]
|
||||
)
|
||||
elif theme.lower() == "dark":
|
||||
formatter = HelpFormatter().settings(
|
||||
theme=HelpTheme.dark().with_(**theme_settings), **formatter_settings
|
||||
formatter = HelpFormatter.settings(
|
||||
theme=HelpTheme.dark().with_(**theme_settings),
|
||||
**formatter_settings, # type: ignore[arg-type]
|
||||
)
|
||||
elif theme.lower() == "light":
|
||||
formatter = HelpFormatter().settings(
|
||||
theme=HelpTheme.light().with_(**theme_settings), **formatter_settings
|
||||
formatter = HelpFormatter.settings(
|
||||
theme=HelpTheme.light().with_(**theme_settings),
|
||||
**formatter_settings, # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
return Context.settings(
|
||||
|
|
|
|||
|
|
@ -221,9 +221,7 @@ repr_number = green
|
|||
# Uncomment the following line to manually set the loglevel for ffmpeg. See
|
||||
# ffmpeg manpage for accepted values
|
||||
loglevel = ERROR
|
||||
# defaults to the one present in path
|
||||
ffmpeg_executable = ffmpeg
|
||||
|
||||
[jupyter]
|
||||
media_embed =
|
||||
media_embed = False
|
||||
media_width = 60%%
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ Both ``logger`` and ``console`` use the ``rich`` library to produce rich text
|
|||
format.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import copy
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from rich import color, errors
|
||||
|
|
@ -26,6 +26,9 @@ from rich.theme import Theme
|
|||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
__all__ = ["make_logger", "parse_theme", "set_file_logger", "JSONFormatter"]
|
||||
|
||||
HIGHLIGHTED_KEYWORDS = [ # these keywords are highlighted specially
|
||||
"Played",
|
||||
"animations",
|
||||
|
|
@ -49,9 +52,9 @@ Loading the default color configuration.[/logging.level.error]
|
|||
|
||||
|
||||
def make_logger(
|
||||
parser: configparser.ConfigParser,
|
||||
parser: configparser.SectionProxy,
|
||||
verbosity: str,
|
||||
) -> tuple[logging.Logger, Console]:
|
||||
) -> tuple[logging.Logger, Console, Console]:
|
||||
"""Make the manim logger and console.
|
||||
|
||||
Parameters
|
||||
|
|
@ -83,14 +86,13 @@ def make_logger(
|
|||
theme = parse_theme(parser)
|
||||
console = Console(theme=theme)
|
||||
|
||||
# With rich 9.5.0+ we could pass stderr=True instead
|
||||
error_console = Console(theme=theme, file=sys.stderr)
|
||||
error_console = Console(theme=theme, stderr=True)
|
||||
|
||||
# set the rich handler
|
||||
RichHandler.KEYWORDS = HIGHLIGHTED_KEYWORDS
|
||||
rich_handler = RichHandler(
|
||||
console=console,
|
||||
show_time=parser.getboolean("log_timestamps"),
|
||||
keywords=HIGHLIGHTED_KEYWORDS,
|
||||
)
|
||||
|
||||
# finally, the logger
|
||||
|
|
@ -98,10 +100,14 @@ def make_logger(
|
|||
logger.addHandler(rich_handler)
|
||||
logger.setLevel(verbosity)
|
||||
|
||||
if not (libav_logger := logging.getLogger()).hasHandlers():
|
||||
libav_logger.addHandler(rich_handler)
|
||||
libav_logger.setLevel(verbosity)
|
||||
|
||||
return logger, console, error_console
|
||||
|
||||
|
||||
def parse_theme(parser: configparser.ConfigParser) -> Theme:
|
||||
def parse_theme(parser: configparser.SectionProxy) -> Theme:
|
||||
"""Configure the rich style of logger and console output.
|
||||
|
||||
Parameters
|
||||
|
|
@ -177,7 +183,7 @@ class JSONFormatter(logging.Formatter):
|
|||
|
||||
"""
|
||||
|
||||
def format(self, record: dict) -> str:
|
||||
def format(self, record: logging.LogRecord) -> str:
|
||||
"""Format the record in a custom JSON format."""
|
||||
record_c = copy.deepcopy(record)
|
||||
if record_c.args:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,5 @@
|
|||
"""Animate mobjects."""
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
|
||||
|
|
@ -16,8 +15,11 @@ from .scene_buffer import SceneBuffer
|
|||
|
||||
__all__ = ["Animation", "Wait", "override_animation"]
|
||||
|
||||
from collections.abc import Iterable, Sequence
|
||||
from copy import deepcopy
|
||||
from typing import TYPE_CHECKING, Callable, Iterable, Sequence, TypeVar
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
from typing_extensions import Self, TypeVar
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Self
|
||||
|
|
@ -113,7 +115,7 @@ class Animation(AnimationProtocol):
|
|||
*args,
|
||||
use_override=True,
|
||||
**kwargs,
|
||||
):
|
||||
) -> Self:
|
||||
if isinstance(mobject, Mobject) and use_override:
|
||||
func = mobject.animation_override_for(cls)
|
||||
if func is not None:
|
||||
|
|
@ -393,6 +395,7 @@ class Animation(AnimationProtocol):
|
|||
self.run_time = run_time
|
||||
return self
|
||||
|
||||
# TODO: is this getter even necessary?
|
||||
def get_run_time(self) -> float:
|
||||
"""Get the run time of the animation.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ if TYPE_CHECKING:
|
|||
import numpy as np
|
||||
|
||||
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
|
||||
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup as VGroup
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
|
||||
from manim.utils.color import (
|
||||
BLUE_B,
|
||||
BLUE_D,
|
||||
|
|
|
|||
|
|
@ -1,26 +1,29 @@
|
|||
"""Tools for displaying multiple animations at once."""
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Callable, Sequence
|
||||
from collections.abc import Iterable, Sequence
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
from manim import config, logger
|
||||
from manim._config import config
|
||||
from manim.animation.animation import Animation, prepare_animation
|
||||
from manim.constants import RendererType
|
||||
from manim.mobject.mobject import Group, Mobject
|
||||
from manim.mobject.opengl.opengl_mobject import OpenGLGroup
|
||||
from manim.utils.iterables import remove_list_redundancies
|
||||
from manim.utils.parameter_parsing import flatten_iterable_parameters
|
||||
from manim.utils.rate_functions import linear
|
||||
|
||||
from ..animation.animation import Animation, prepare_animation
|
||||
from ..constants import RendererType
|
||||
from ..mobject.mobject import Group, Mobject
|
||||
from ..utils.iterables import remove_list_redundancies
|
||||
from ..utils.rate_functions import linear
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup
|
||||
from manim.mobject.types.vectorized_mobject import VGroup
|
||||
|
||||
from ..mobject.types.vectorized_mobject import VGroup
|
||||
from .scene_buffer import SceneBuffer
|
||||
|
||||
__all__ = ["AnimationGroup", "Succession", "LaggedStart", "LaggedStartMap"]
|
||||
|
||||
|
|
@ -54,14 +57,15 @@ class AnimationGroup(Animation):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
*animations: Animation,
|
||||
*animations: Animation | Iterable[Animation],
|
||||
group: Group | VGroup | OpenGLGroup | OpenGLVGroup | None = None,
|
||||
run_time: float | None = None,
|
||||
rate_func: Callable[[float], float] = linear,
|
||||
lag_ratio: float = 0,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
self.animations = [prepare_animation(anim) for anim in animations]
|
||||
arg_anim = flatten_iterable_parameters(animations)
|
||||
self.animations = [prepare_animation(anim) for anim in arg_anim]
|
||||
self.rate_func = rate_func
|
||||
self.group = group
|
||||
if self.group is None:
|
||||
|
|
@ -84,14 +88,21 @@ class AnimationGroup(Animation):
|
|||
for anim in self.animations:
|
||||
anim.begin()
|
||||
self.process_subanimation_buffer(anim.buffer)
|
||||
if not self.animations:
|
||||
raise ValueError(
|
||||
f"Trying to play {self} without animations, this is not supported. "
|
||||
"Please add at least one subanimation."
|
||||
)
|
||||
|
||||
self.anim_group_time = 0.0
|
||||
if self.suspend_mobject_updating:
|
||||
self.group.suspend_updating()
|
||||
|
||||
def finish(self) -> None:
|
||||
self.interpolate(1)
|
||||
self.anims_begun[:] = True
|
||||
self.anims_begun[:] = True
|
||||
for anim in self.animations:
|
||||
if self.remover:
|
||||
anim.remover = self.remover
|
||||
anim.finish()
|
||||
self.process_subanimation_buffer(anim.buffer)
|
||||
|
||||
if self.suspend_mobject_updating:
|
||||
|
|
@ -99,7 +110,9 @@ class AnimationGroup(Animation):
|
|||
self._on_finish(self.buffer)
|
||||
|
||||
def update_mobjects(self, dt: float) -> None:
|
||||
for anim in self.animations:
|
||||
for anim in self.anims_with_timings["anim"][
|
||||
self.anims_begun & ~self.anims_finished
|
||||
]:
|
||||
anim.update_mobjects(dt)
|
||||
|
||||
def init_run_time(self, run_time) -> float:
|
||||
|
|
@ -116,25 +129,30 @@ class AnimationGroup(Animation):
|
|||
The duration of the animation in seconds.
|
||||
"""
|
||||
self.build_animations_with_timings()
|
||||
if self.anims_with_timings:
|
||||
self.max_end_time = np.max([awt[2] for awt in self.anims_with_timings])
|
||||
else:
|
||||
self.max_end_time = 0
|
||||
# Note: if lag_ratio < 1, then not necessarily the final animation's
|
||||
# end time will be the max end time! Therefore we must calculate the
|
||||
# maximum over all the end times, and not just take the last one.
|
||||
# Example: if you want to play 2 animations of 10s and 1s with a
|
||||
# lag_ratio of 0.1, the 1st one will end at t=10 and the 2nd one will
|
||||
# end at t=2, so the AnimationGroup will end at t=10.
|
||||
self.max_end_time = max(self.anims_with_timings["end"], default=0)
|
||||
return self.max_end_time if run_time is None else run_time
|
||||
|
||||
def build_animations_with_timings(self) -> None:
|
||||
"""Creates a list of triplets of the form (anim, start_time, end_time)."""
|
||||
run_times = np.array([anim.run_time for anim in self.animations])
|
||||
num_animations = run_times.shape[0]
|
||||
dtype = [("anim", "O"), ("start", "f8"), ("end", "f8")]
|
||||
self.anims_with_timings = np.zeros(num_animations, dtype=dtype)
|
||||
self.anims_begun = np.zeros(num_animations, dtype=bool)
|
||||
self.anims_finished = np.zeros(num_animations, dtype=bool)
|
||||
if num_animations == 0:
|
||||
return
|
||||
|
||||
self.anims_with_timings = []
|
||||
"""List of tuple[Animation, start_time, end_time]"""
|
||||
|
||||
curr_time: float = 0
|
||||
for anim in self.animations:
|
||||
start_time: float = curr_time
|
||||
end_time: float = start_time + anim.get_run_time()
|
||||
self.anims_with_timings.append((anim, start_time, end_time))
|
||||
# Start time of next animation is based on the lag_ratio
|
||||
curr_time = (1 - self.lag_ratio) * start_time + self.lag_ratio * end_time
|
||||
lags = run_times[:-1] * self.lag_ratio
|
||||
self.anims_with_timings["anim"] = self.animations
|
||||
self.anims_with_timings["start"][1:] = np.add.accumulate(lags)
|
||||
self.anims_with_timings["end"] = self.anims_with_timings["start"] + run_times
|
||||
|
||||
def interpolate(self, alpha: float) -> None:
|
||||
# Note, if the run_time of AnimationGroup has been
|
||||
|
|
@ -142,14 +160,30 @@ class AnimationGroup(Animation):
|
|||
# times might not correspond to actual times,
|
||||
# e.g. of the surrounding scene. Instead they'd
|
||||
# be a rescaled version. But that's okay!
|
||||
time = self.rate_func(alpha) * self.max_end_time
|
||||
for anim, start_time, end_time in self.anims_with_timings:
|
||||
anim_time = end_time - start_time
|
||||
if anim_time == 0:
|
||||
sub_alpha = 0
|
||||
else:
|
||||
sub_alpha = np.clip((time - start_time) / anim_time, 0, 1)
|
||||
anim.interpolate(sub_alpha)
|
||||
anim_group_time = self.rate_func(alpha) * self.max_end_time
|
||||
time_goes_back = anim_group_time < self.anim_group_time
|
||||
|
||||
# Only update ongoing animations
|
||||
awt = self.anims_with_timings
|
||||
new_begun = anim_group_time >= awt["start"]
|
||||
new_finished = anim_group_time > awt["end"]
|
||||
to_update = awt[
|
||||
(self.anims_begun | new_begun) & (~self.anims_finished | ~new_finished)
|
||||
]
|
||||
|
||||
run_times = to_update["end"] - to_update["start"]
|
||||
sub_alphas = (anim_group_time - to_update["start"]) / run_times
|
||||
if time_goes_back:
|
||||
sub_alphas[sub_alphas < 0] = 0
|
||||
else:
|
||||
sub_alphas[sub_alphas > 1] = 1
|
||||
|
||||
for anim_to_update, sub_alpha in zip(to_update["anim"], sub_alphas):
|
||||
anim_to_update.interpolate(sub_alpha)
|
||||
|
||||
self.anim_group_time = anim_group_time
|
||||
self.anims_begun = new_begun
|
||||
self.anims_finished = new_finished
|
||||
|
||||
|
||||
class Succession(AnimationGroup):
|
||||
|
|
@ -193,7 +227,11 @@ class Succession(AnimationGroup):
|
|||
super().__init__(*animations, lag_ratio=lag_ratio, **kwargs)
|
||||
|
||||
def begin(self) -> None:
|
||||
assert len(self.animations) > 0
|
||||
if not self.animations:
|
||||
raise ValueError(
|
||||
f"Trying to play {self} without animations, this is not supported. "
|
||||
"Please add at least one subanimation."
|
||||
)
|
||||
self.update_active_animation(0)
|
||||
|
||||
for anim in self.animations:
|
||||
|
|
@ -219,8 +257,8 @@ class Succession(AnimationGroup):
|
|||
self.active_animation.begin()
|
||||
self.process_subanimation_buffer(self.active_animation.buffer)
|
||||
self.apply_buffer = True
|
||||
self.active_start_time = self.anims_with_timings[index][1]
|
||||
self.active_end_time = self.anims_with_timings[index][2]
|
||||
self.active_start_time = self.anims_with_timings[index]["start"]
|
||||
self.active_end_time = self.anims_with_timings[index]["end"]
|
||||
|
||||
def next_animation(self) -> None:
|
||||
"""Proceeds to the next animation.
|
||||
|
|
@ -238,7 +276,7 @@ class Succession(AnimationGroup):
|
|||
self.next_animation()
|
||||
if self.active_animation is not None and self.active_start_time is not None:
|
||||
elapsed = current_time - self.active_start_time
|
||||
active_run_time = self.active_animation.get_run_time()
|
||||
active_run_time = self.active_animation.run_time
|
||||
subalpha = elapsed / active_run_time if active_run_time != 0.0 else 1.0
|
||||
self.active_animation.interpolate(subalpha)
|
||||
|
||||
|
|
|
|||
|
|
@ -70,11 +70,14 @@ __all__ = [
|
|||
"RemoveTextLetterByLetter",
|
||||
"ShowSubmobjectsOneByOne",
|
||||
"AddTextWordByWord",
|
||||
"TypeWithCursor",
|
||||
"UntypeWithCursor",
|
||||
]
|
||||
|
||||
|
||||
import itertools as it
|
||||
from typing import TYPE_CHECKING, Callable, Iterable, Sequence
|
||||
from collections.abc import Iterable, Sequence
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
|
@ -82,17 +85,18 @@ if TYPE_CHECKING:
|
|||
from typing_extensions import Self
|
||||
|
||||
from manim.mobject.text.text_mobject import Text
|
||||
from manim.scene.scene import Scene
|
||||
|
||||
from manim.constants import RIGHT, TAU
|
||||
from manim.mobject.opengl.opengl_surface import OpenGLSurface
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject
|
||||
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject as VMobject
|
||||
from manim.utils.color import ManimColor
|
||||
|
||||
from .. import config
|
||||
from ..animation.animation import Animation
|
||||
from ..animation.composition import Succession
|
||||
from ..constants import TAU
|
||||
from ..mobject.mobject import Group, Mobject
|
||||
from ..mobject.types.vectorized_mobject import VMobject
|
||||
from ..utils.bezier import integer_interpolate
|
||||
from ..utils.rate_functions import double_smooth, linear
|
||||
|
||||
|
|
@ -358,18 +362,15 @@ class Write(DrawBorderThenFill):
|
|||
lag_ratio = min(4.0 / max(1.0, length), 0.2)
|
||||
return run_time, lag_ratio
|
||||
|
||||
def reverse_submobjects(self) -> None:
|
||||
self.mobject.invert(recursive=True)
|
||||
|
||||
def begin(self) -> None:
|
||||
if self.reverse:
|
||||
self.reverse_submobjects()
|
||||
self.mobject.reverse_submobjects(recursive=True)
|
||||
super().begin()
|
||||
|
||||
def finish(self) -> None:
|
||||
super().finish()
|
||||
if self.reverse:
|
||||
self.reverse_submobjects()
|
||||
self.mobject.reverse_submobjects(recursive=True)
|
||||
|
||||
|
||||
class Unwrite(Write):
|
||||
|
|
@ -459,7 +460,7 @@ class SpiralIn(Animation):
|
|||
fade_in_fraction=0.3,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
self.shapes = shapes
|
||||
self.shapes = shapes.copy()
|
||||
self.scale_factor = scale_factor
|
||||
self.shape_center = shapes.get_center()
|
||||
self.fade_in_fraction = fade_in_fraction
|
||||
|
|
@ -476,15 +477,21 @@ class SpiralIn(Animation):
|
|||
|
||||
def interpolate_mobject(self, alpha: float) -> None:
|
||||
alpha = self.rate_func(alpha)
|
||||
for shape in self.shapes:
|
||||
for original_shape, shape in zip(self.shapes, self.mobject):
|
||||
shape.restore()
|
||||
shape.save_state()
|
||||
opacity = shape.get_fill_opacity()
|
||||
new_opacity = min(opacity, alpha * opacity / self.fade_in_fraction)
|
||||
fill_opacity = original_shape.get_fill_opacity()
|
||||
stroke_opacity = original_shape.get_stroke_opacity()
|
||||
new_fill_opacity = min(
|
||||
fill_opacity, alpha * fill_opacity / self.fade_in_fraction
|
||||
)
|
||||
new_stroke_opacity = min(
|
||||
stroke_opacity, alpha * stroke_opacity / self.fade_in_fraction
|
||||
)
|
||||
shape.shift((shape.final_position - shape.initial_position) * alpha)
|
||||
shape.rotate(TAU * alpha, about_point=self.shape_center)
|
||||
shape.rotate(-TAU * alpha, about_point=shape.get_center_of_mass())
|
||||
shape.set_opacity(new_opacity)
|
||||
shape.set_fill(opacity=new_fill_opacity)
|
||||
shape.set_stroke(opacity=new_stroke_opacity)
|
||||
|
||||
|
||||
class ShowIncreasingSubsets(Animation):
|
||||
|
|
@ -566,6 +573,11 @@ class AddTextLetterByLetter(ShowIncreasingSubsets):
|
|||
**kwargs,
|
||||
) -> None:
|
||||
self.time_per_char = time_per_char
|
||||
# Check for empty text using family_members_with_points()
|
||||
if not text.family_members_with_points():
|
||||
raise ValueError(
|
||||
f"The text mobject {text} does not seem to contain any characters."
|
||||
)
|
||||
if run_time is None:
|
||||
# minimum time per character is 1/frame_rate, otherwise
|
||||
# the animation does not finish.
|
||||
|
|
@ -666,3 +678,176 @@ class AddTextWordByWord(Succession):
|
|||
)
|
||||
)
|
||||
super().__init__(*anims, **kwargs)
|
||||
|
||||
|
||||
class TypeWithCursor(AddTextLetterByLetter):
|
||||
"""Similar to :class:`~.AddTextLetterByLetter` , but with an additional cursor mobject at the end.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
time_per_char
|
||||
Frequency of appearance of the letters.
|
||||
cursor
|
||||
:class:`~.Mobject` shown after the last added letter.
|
||||
buff
|
||||
Controls how far away the cursor is to the right of the last added letter.
|
||||
keep_cursor_y
|
||||
If ``True``, the cursor's y-coordinate is set to the center of the ``Text`` and remains the same throughout the animation. Otherwise, it is set to the center of the last added letter.
|
||||
leave_cursor_on
|
||||
Whether to show the cursor after the animation.
|
||||
|
||||
.. tip::
|
||||
This is currently only possible for class:`~.Text` and not for class:`~.MathTex`.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. manim:: InsertingTextExample
|
||||
:ref_classes: Blink
|
||||
|
||||
class InsertingTextExample(Scene):
|
||||
def construct(self):
|
||||
text = Text("Inserting", color=PURPLE).scale(1.5).to_edge(LEFT)
|
||||
cursor = Rectangle(
|
||||
color = GREY_A,
|
||||
fill_color = GREY_A,
|
||||
fill_opacity = 1.0,
|
||||
height = 1.1,
|
||||
width = 0.5,
|
||||
).move_to(text[0]) # Position the cursor
|
||||
|
||||
self.play(TypeWithCursor(text, cursor))
|
||||
self.play(Blink(cursor, blinks=2))
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
text: Text,
|
||||
cursor: Mobject,
|
||||
buff: float = 0.1,
|
||||
keep_cursor_y: bool = True,
|
||||
leave_cursor_on: bool = True,
|
||||
time_per_char: float = 0.1,
|
||||
reverse_rate_function=False,
|
||||
introducer=True,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
self.cursor = cursor
|
||||
self.buff = buff
|
||||
self.keep_cursor_y = keep_cursor_y
|
||||
self.leave_cursor_on = leave_cursor_on
|
||||
super().__init__(
|
||||
text,
|
||||
time_per_char=time_per_char,
|
||||
reverse_rate_function=reverse_rate_function,
|
||||
introducer=introducer,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def begin(self) -> None:
|
||||
self.y_cursor = self.cursor.get_y()
|
||||
self.cursor.initial_position = self.mobject.get_center()
|
||||
if self.keep_cursor_y:
|
||||
self.cursor.set_y(self.y_cursor)
|
||||
|
||||
self.cursor.set_opacity(0)
|
||||
self.mobject.add(self.cursor)
|
||||
super().begin()
|
||||
|
||||
def finish(self) -> None:
|
||||
if self.leave_cursor_on:
|
||||
self.cursor.set_opacity(1)
|
||||
else:
|
||||
self.cursor.set_opacity(0)
|
||||
self.mobject.remove(self.cursor)
|
||||
super().finish()
|
||||
|
||||
def clean_up_from_scene(self, scene: Scene) -> None:
|
||||
if not self.leave_cursor_on:
|
||||
scene.remove(self.cursor)
|
||||
super().clean_up_from_scene(scene)
|
||||
|
||||
def update_submobject_list(self, index: int) -> None:
|
||||
for mobj in self.all_submobs[:index]:
|
||||
mobj.set_opacity(1)
|
||||
|
||||
for mobj in self.all_submobs[index:]:
|
||||
mobj.set_opacity(0)
|
||||
|
||||
if index != 0:
|
||||
self.cursor.next_to(
|
||||
self.all_submobs[index - 1], RIGHT, buff=self.buff
|
||||
).set_y(self.cursor.initial_position[1])
|
||||
else:
|
||||
self.cursor.move_to(self.all_submobs[0]).set_y(
|
||||
self.cursor.initial_position[1]
|
||||
)
|
||||
|
||||
if self.keep_cursor_y:
|
||||
self.cursor.set_y(self.y_cursor)
|
||||
self.cursor.set_opacity(1)
|
||||
|
||||
|
||||
class UntypeWithCursor(TypeWithCursor):
|
||||
"""Similar to :class:`~.RemoveTextLetterByLetter` , but with an additional cursor mobject at the end.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
time_per_char
|
||||
Frequency of appearance of the letters.
|
||||
cursor
|
||||
:class:`~.Mobject` shown after the last added letter.
|
||||
buff
|
||||
Controls how far away the cursor is to the right of the last added letter.
|
||||
keep_cursor_y
|
||||
If ``True``, the cursor's y-coordinate is set to the center of the ``Text`` and remains the same throughout the animation. Otherwise, it is set to the center of the last added letter.
|
||||
leave_cursor_on
|
||||
Whether to show the cursor after the animation.
|
||||
|
||||
.. tip::
|
||||
This is currently only possible for class:`~.Text` and not for class:`~.MathTex`.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. manim:: DeletingTextExample
|
||||
:ref_classes: Blink
|
||||
|
||||
class DeletingTextExample(Scene):
|
||||
def construct(self):
|
||||
text = Text("Deleting", color=PURPLE).scale(1.5).to_edge(LEFT)
|
||||
cursor = Rectangle(
|
||||
color = GREY_A,
|
||||
fill_color = GREY_A,
|
||||
fill_opacity = 1.0,
|
||||
height = 1.1,
|
||||
width = 0.5,
|
||||
).move_to(text[0]) # Position the cursor
|
||||
|
||||
self.play(UntypeWithCursor(text, cursor))
|
||||
self.play(Blink(cursor, blinks=2))
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
text: Text,
|
||||
cursor: VMobject | None = None,
|
||||
time_per_char: float = 0.1,
|
||||
reverse_rate_function=True,
|
||||
introducer=False,
|
||||
remover=True,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
super().__init__(
|
||||
text,
|
||||
cursor=cursor,
|
||||
time_per_char=time_per_char,
|
||||
reverse_rate_function=reverse_rate_function,
|
||||
introducer=introducer,
|
||||
remover=remover,
|
||||
**kwargs,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
"""
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = [
|
||||
|
|
@ -31,7 +30,7 @@ from ..constants import ORIGIN
|
|||
from ..mobject.mobject import Group, Mobject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..scene import Scene
|
||||
pass
|
||||
|
||||
|
||||
class _Fade(Transform):
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ Examples
|
|||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = [
|
||||
"FocusOn",
|
||||
"Indicate",
|
||||
|
|
@ -34,9 +36,11 @@ __all__ = [
|
|||
"ApplyWave",
|
||||
"Circumscribe",
|
||||
"Wiggle",
|
||||
"Blink",
|
||||
]
|
||||
|
||||
from typing import Callable, Iterable, Optional, Type, Union
|
||||
from collections.abc import Iterable
|
||||
from typing import Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
|
@ -52,12 +56,12 @@ from ..animation.creation import Create, ShowPartial, Uncreate
|
|||
from ..animation.fading import FadeIn, FadeOut
|
||||
from ..animation.movement import Homotopy
|
||||
from ..animation.transform import Transform
|
||||
from ..animation.updaters.update import UpdateFromFunc
|
||||
from ..constants import *
|
||||
from ..mobject.mobject import Mobject
|
||||
from ..mobject.types.vectorized_mobject import VGroup, VMobject
|
||||
from ..utils.bezier import interpolate, inverse_interpolate
|
||||
from ..utils.color import GREY, YELLOW, ParsableManimColor
|
||||
from ..utils.deprecation import deprecated
|
||||
from ..utils.rate_functions import smooth, there_and_back, wiggle
|
||||
from ..utils.space_ops import normalize
|
||||
|
||||
|
|
@ -75,8 +79,6 @@ class FocusOn(Transform):
|
|||
The color of the spotlight.
|
||||
run_time
|
||||
The duration of the animation.
|
||||
kwargs
|
||||
Additional arguments to be passed to the :class:`~.Succession` constructor
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
|
@ -92,11 +94,11 @@ class FocusOn(Transform):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
focus_point: Union[np.ndarray, Mobject],
|
||||
focus_point: np.ndarray | Mobject,
|
||||
opacity: float = 0.2,
|
||||
color: str = GREY,
|
||||
run_time: float = 2,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
) -> None:
|
||||
self.focus_point = focus_point
|
||||
self.color = color
|
||||
|
|
@ -129,7 +131,7 @@ class Indicate(Transform):
|
|||
color
|
||||
The color the mobject temporally takes.
|
||||
rate_func
|
||||
The function definig the animation progress at every point in time.
|
||||
The function defining the animation progress at every point in time.
|
||||
kwargs
|
||||
Additional arguments to be passed to the :class:`~.Succession` constructor
|
||||
|
||||
|
|
@ -146,17 +148,17 @@ class Indicate(Transform):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
mobject: "Mobject",
|
||||
mobject: Mobject,
|
||||
scale_factor: float = 1.2,
|
||||
color: str = YELLOW,
|
||||
rate_func: Callable[[float, Optional[float]], np.ndarray] = there_and_back,
|
||||
**kwargs
|
||||
rate_func: Callable[[float, float | None], np.ndarray] = there_and_back,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
self.color = color
|
||||
self.scale_factor = scale_factor
|
||||
super().__init__(mobject, rate_func=rate_func, **kwargs)
|
||||
|
||||
def create_target(self) -> "Mobject":
|
||||
def create_target(self) -> Mobject:
|
||||
target = self.mobject.copy()
|
||||
target.scale(self.scale_factor)
|
||||
target.set_color(self.color)
|
||||
|
|
@ -216,7 +218,7 @@ class Flash(AnimationGroup):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
point: Union[np.ndarray, Mobject],
|
||||
point: np.ndarray | Mobject,
|
||||
line_length: float = 0.2,
|
||||
num_lines: int = 12,
|
||||
flash_radius: float = 0.1,
|
||||
|
|
@ -224,7 +226,7 @@ class Flash(AnimationGroup):
|
|||
color: str = YELLOW,
|
||||
time_width: float = 1,
|
||||
run_time: float = 1.0,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
) -> None:
|
||||
if isinstance(point, Mobject):
|
||||
self.point = point.get_center()
|
||||
|
|
@ -254,7 +256,7 @@ class Flash(AnimationGroup):
|
|||
lines.set_stroke(width=self.line_stroke_width)
|
||||
return lines
|
||||
|
||||
def create_line_anims(self) -> Iterable["ShowPassingFlash"]:
|
||||
def create_line_anims(self) -> Iterable[ShowPassingFlash]:
|
||||
return [
|
||||
ShowPassingFlash(
|
||||
line,
|
||||
|
|
@ -300,7 +302,7 @@ class ShowPassingFlash(ShowPartial):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, mobject: "VMobject", time_width: float = 0.1, **kwargs) -> None:
|
||||
def __init__(self, mobject: VMobject, time_width: float = 0.1, **kwargs) -> None:
|
||||
self.time_width = time_width
|
||||
super().__init__(mobject, remover=True, introducer=True, **kwargs)
|
||||
|
||||
|
|
@ -385,14 +387,14 @@ class ApplyWave(Homotopy):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
mobject: "Mobject",
|
||||
mobject: Mobject,
|
||||
direction: np.ndarray = UP,
|
||||
amplitude: float = 0.2,
|
||||
wave_func: Callable[[float], float] = smooth,
|
||||
time_width: float = 1,
|
||||
ripples: int = 1,
|
||||
run_time: float = 2,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
) -> None:
|
||||
x_min = mobject.get_left()[0]
|
||||
x_max = mobject.get_right()[0]
|
||||
|
|
@ -403,7 +405,7 @@ class ApplyWave(Homotopy):
|
|||
# This wave is build up as follows:
|
||||
# The time is split into 2*ripples phases. In every phase the amplitude
|
||||
# either rises to one or goes down to zero. Consecutive ripples will have
|
||||
# their amplitudes in oppising directions (first ripple from 0 to 1 to 0,
|
||||
# their amplitudes in opposing directions (first ripple from 0 to 1 to 0,
|
||||
# second from 0 to -1 to 0 and so on). This is how two ripples would be
|
||||
# divided into phases:
|
||||
|
||||
|
|
@ -442,7 +444,7 @@ class ApplyWave(Homotopy):
|
|||
return wave_func(t * phases)
|
||||
elif phase == phases - 1:
|
||||
# last ripple. Rising or falling depending on the number of ripples
|
||||
# The (ripples % 2)-term is used to make this destinction.
|
||||
# The (ripples % 2)-term is used to make this distinction.
|
||||
t -= phase / phases # Time relative to the phase
|
||||
return (1 - wave_func(t * phases)) * (2 * (ripples % 2) - 1)
|
||||
else:
|
||||
|
|
@ -504,14 +506,14 @@ class Wiggle(Animation):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
mobject: "Mobject",
|
||||
mobject: Mobject,
|
||||
scale_value: float = 1.1,
|
||||
rotation_angle: float = 0.01 * TAU,
|
||||
n_wiggles: int = 6,
|
||||
scale_about_point: Optional[np.ndarray] = None,
|
||||
rotate_about_point: Optional[np.ndarray] = None,
|
||||
scale_about_point: np.ndarray | None = None,
|
||||
rotate_about_point: np.ndarray | None = None,
|
||||
run_time: float = 2,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
) -> None:
|
||||
self.scale_value = scale_value
|
||||
self.rotation_angle = rotation_angle
|
||||
|
|
@ -532,8 +534,8 @@ class Wiggle(Animation):
|
|||
|
||||
def interpolate_submobject(
|
||||
self,
|
||||
submobject: "Mobject",
|
||||
starting_submobject: "Mobject",
|
||||
submobject: Mobject,
|
||||
starting_submobject: Mobject,
|
||||
alpha: float,
|
||||
) -> None:
|
||||
submobject.points[:, :] = starting_submobject.points
|
||||
|
|
@ -556,7 +558,7 @@ class Circumscribe(Succession):
|
|||
mobject
|
||||
The mobject to be circumscribed.
|
||||
shape
|
||||
The shape with which to surrond the given mobject. Should be either
|
||||
The shape with which to surround the given mobject. Should be either
|
||||
:class:`~.Rectangle` or :class:`~.Circle`
|
||||
fade_in
|
||||
Whether to make the surrounding shape to fade in. It will be drawn otherwise.
|
||||
|
|
@ -593,7 +595,7 @@ class Circumscribe(Succession):
|
|||
def __init__(
|
||||
self,
|
||||
mobject: Mobject,
|
||||
shape: Type = Rectangle,
|
||||
shape: type = Rectangle,
|
||||
fade_in=False,
|
||||
fade_out=False,
|
||||
time_width=0.3,
|
||||
|
|
@ -601,7 +603,7 @@ class Circumscribe(Succession):
|
|||
color: ParsableManimColor = YELLOW,
|
||||
run_time=1,
|
||||
stroke_width=DEFAULT_STROKE_WIDTH,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
):
|
||||
if shape is Rectangle:
|
||||
frame = SurroundingRectangle(
|
||||
|
|
@ -643,3 +645,68 @@ class Circumscribe(Succession):
|
|||
super().__init__(
|
||||
ShowPassingFlash(frame, time_width, run_time=run_time), **kwargs
|
||||
)
|
||||
|
||||
|
||||
class Blink(Succession):
|
||||
"""Blink the mobject.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mobject
|
||||
The mobject to be blinked.
|
||||
time_on
|
||||
The duration that the mobject is shown for one blink.
|
||||
time_off
|
||||
The duration that the mobject is hidden for one blink.
|
||||
blinks
|
||||
The number of blinks
|
||||
hide_at_end
|
||||
Whether to hide the mobject at the end of the animation.
|
||||
kwargs
|
||||
Additional arguments to be passed to the :class:`~.Succession` constructor.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. manim:: BlinkingExample
|
||||
|
||||
class BlinkingExample(Scene):
|
||||
def construct(self):
|
||||
text = Text("Blinking").scale(1.5)
|
||||
self.add(text)
|
||||
self.play(Blink(text, blinks=3))
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
mobject: Mobject,
|
||||
time_on: float = 0.5,
|
||||
time_off: float = 0.5,
|
||||
blinks: int = 1,
|
||||
hide_at_end: bool = False,
|
||||
**kwargs,
|
||||
):
|
||||
animations = [
|
||||
UpdateFromFunc(
|
||||
mobject,
|
||||
update_function=lambda mob: mob.set_opacity(1.0),
|
||||
run_time=time_on,
|
||||
),
|
||||
UpdateFromFunc(
|
||||
mobject,
|
||||
update_function=lambda mob: mob.set_opacity(0.0),
|
||||
run_time=time_off,
|
||||
),
|
||||
] * blinks
|
||||
|
||||
if not hide_at_end:
|
||||
animations.append(
|
||||
UpdateFromFunc(
|
||||
mobject,
|
||||
update_function=lambda mob: mob.set_opacity(1.0),
|
||||
run_time=time_on,
|
||||
),
|
||||
)
|
||||
|
||||
super().__init__(*animations, **kwargs)
|
||||
|
|
|
|||
|
|
@ -137,8 +137,7 @@ class PhaseFlow(Animation):
|
|||
|
||||
class MoveAlongPath(Animation):
|
||||
"""Make one mobject move along the path of another mobject.
|
||||
Example
|
||||
--------
|
||||
|
||||
.. manim:: MoveAlongPathExample
|
||||
|
||||
class MoveAlongPathExample(Scene):
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Protocol, Sequence
|
||||
from typing import TYPE_CHECKING, Protocol
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .animation import Animation
|
||||
from .scene_buffer import SceneBuffer
|
||||
|
||||
|
||||
|
|
@ -14,17 +13,12 @@ class AnimationProtocol(Protocol):
|
|||
buffer: SceneBuffer
|
||||
apply_buffer: bool
|
||||
|
||||
def begin(self) -> None:
|
||||
...
|
||||
def begin(self) -> None: ...
|
||||
|
||||
def finish(self) -> None:
|
||||
...
|
||||
def finish(self) -> None: ...
|
||||
|
||||
def update_mobjects(self, dt: float) -> None:
|
||||
...
|
||||
def update_mobjects(self, dt: float) -> None: ...
|
||||
|
||||
def interpolate(self, alpha: float) -> None:
|
||||
...
|
||||
def interpolate(self, alpha: float) -> None: ...
|
||||
|
||||
def get_run_time(self) -> float:
|
||||
...
|
||||
def get_run_time(self) -> float: ...
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ from __future__ import annotations
|
|||
|
||||
__all__ = ["Rotating", "Rotate"]
|
||||
|
||||
from typing import TYPE_CHECKING, Callable, Sequence
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
|
@ -59,7 +60,7 @@ class Rotate(Transform):
|
|||
about_point
|
||||
The rotation center.
|
||||
about_edge
|
||||
If ``about_point``is ``None``, this argument specifies
|
||||
If ``about_point`` is ``None``, this argument specifies
|
||||
the direction of the bounding box point to be taken as
|
||||
the rotation center.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import final
|
||||
|
||||
from manim.mobject.opengl.opengl_mobject import OpenGLMobject as Mobject
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ from __future__ import annotations
|
|||
|
||||
__all__ = ["Broadcast"]
|
||||
|
||||
from typing import Any, Sequence
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from manim.animation.transform import Restore
|
||||
|
||||
|
|
@ -84,7 +85,7 @@ class Broadcast(LaggedStart):
|
|||
|
||||
mob.move_to(self.focal_point)
|
||||
mob.save_state()
|
||||
mob.set_width(self.initial_width)
|
||||
mob.set(width=self.initial_width)
|
||||
|
||||
if fill_o:
|
||||
mob.set_opacity(self.initial_opacity)
|
||||
|
|
|
|||
|
|
@ -2,16 +2,20 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import types
|
||||
from typing import Callable
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
from numpy import piecewise
|
||||
|
||||
from manim.utils.simple_functions import get_parameters
|
||||
|
||||
from ..animation.animation import Animation, Wait, prepare_animation
|
||||
from ..animation.composition import AnimationGroup
|
||||
from ..mobject.mobject import Mobject, Updater, _AnimationBuilder
|
||||
from ..mobject.mobject import Mobject, _AnimationBuilder
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..mobject.mobject import Updater
|
||||
|
||||
__all__ = ["ChangeSpeed"]
|
||||
|
||||
|
||||
class ChangeSpeed(Animation):
|
||||
|
|
@ -259,8 +263,7 @@ class ChangeSpeed(Animation):
|
|||
:class:`.ChangeSpeed`
|
||||
:meth:`.Mobject.add_updater`
|
||||
"""
|
||||
parameters = get_parameters(update_function)
|
||||
if "dt" in parameters:
|
||||
if "dt" in inspect.signature(update_function).parameters:
|
||||
mobject.add_updater(
|
||||
lambda mob, dt: update_function(
|
||||
mob, ChangeSpeed.dt if ChangeSpeed.is_changing_dt else dt
|
||||
|
|
|
|||
|
|
@ -28,27 +28,26 @@ __all__ = [
|
|||
|
||||
import inspect
|
||||
import types
|
||||
from typing import TYPE_CHECKING, Any, Callable, Iterable, Sequence
|
||||
from collections.abc import Iterable, Sequence
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
from manim.mobject.opengl.opengl_mobject import OpenGLGroup, OpenGLMobject
|
||||
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
|
||||
|
||||
from .. import config
|
||||
from ..animation.animation import Animation
|
||||
from ..constants import (
|
||||
DEFAULT_POINTWISE_FUNCTION_RUN_TIME,
|
||||
DEGREES,
|
||||
ORIGIN,
|
||||
OUT,
|
||||
RendererType,
|
||||
)
|
||||
from ..mobject.mobject import Group, Mobject
|
||||
from ..utils.paths import path_along_arc, path_along_circles
|
||||
from ..utils.rate_functions import smooth, squish_rate_func
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..scene.scene import Scene
|
||||
pass
|
||||
|
||||
|
||||
class Transform(Animation):
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ from __future__ import annotations
|
|||
|
||||
__all__ = ["TransformMatchingShapes", "TransformMatchingTex"]
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
|
@ -223,7 +222,7 @@ class TransformMatchingShapes(TransformMatchingAbstractBase):
|
|||
def get_mobject_key(mobject: Mobject) -> int:
|
||||
mobject.save_state()
|
||||
mobject.center()
|
||||
mobject.set_height(1)
|
||||
mobject.set(height=1)
|
||||
result = hash(np.round(mobject.points, 3).tobytes())
|
||||
mobject.restore()
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -15,22 +15,26 @@ __all__ = [
|
|||
|
||||
|
||||
import inspect
|
||||
from collections.abc import Callable
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
import numpy as np
|
||||
|
||||
from manim.constants import DEGREES, RIGHT
|
||||
from manim.mobject.mobject import Mobject
|
||||
from manim.opengl import OpenGLMobject
|
||||
from manim.utils.space_ops import normalize
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.animation.animation import Animation
|
||||
|
||||
|
||||
def assert_is_mobject_method(method):
|
||||
def assert_is_mobject_method(method: Callable) -> None:
|
||||
assert inspect.ismethod(method)
|
||||
mobject = method.__self__
|
||||
assert isinstance(mobject, (Mobject, OpenGLMobject))
|
||||
|
||||
|
||||
def always(method, *args, **kwargs):
|
||||
def always(method: Callable, *args, **kwargs) -> Mobject:
|
||||
assert_is_mobject_method(method)
|
||||
mobject = method.__self__
|
||||
func = method.__func__
|
||||
|
|
@ -38,7 +42,7 @@ def always(method, *args, **kwargs):
|
|||
return mobject
|
||||
|
||||
|
||||
def f_always(method, *arg_generators, **kwargs):
|
||||
def f_always(method: Callable[[Mobject], None], *arg_generators, **kwargs) -> Mobject:
|
||||
"""
|
||||
More functional version of always, where instead
|
||||
of taking in args, it takes in functions which output
|
||||
|
|
@ -80,16 +84,18 @@ def always_redraw(func: Callable[[], Mobject]) -> Mobject:
|
|||
sine = ax.plot(np.sin, color=RED)
|
||||
alpha = ValueTracker(0)
|
||||
point = always_redraw(
|
||||
lambda: Dot(
|
||||
sine.point_from_proportion(alpha.get_value()),
|
||||
color=BLUE)
|
||||
lambda: Dot(
|
||||
sine.point_from_proportion(alpha.get_value()),
|
||||
color=BLUE
|
||||
)
|
||||
)
|
||||
tangent = always_redraw(
|
||||
lambda: TangentLine(
|
||||
sine,
|
||||
alpha=alpha.get_value(),
|
||||
color=YELLOW,
|
||||
length=4)
|
||||
length=4
|
||||
)
|
||||
)
|
||||
self.add(ax, sine, point, tangent)
|
||||
self.play(alpha.animate.set_value(1), rate_func=linear, run_time=2)
|
||||
|
|
@ -99,36 +105,110 @@ def always_redraw(func: Callable[[], Mobject]) -> Mobject:
|
|||
return mob
|
||||
|
||||
|
||||
def always_shift(mobject, direction=RIGHT, rate=0.1):
|
||||
def normalize(v):
|
||||
norm = np.linalg.norm(v)
|
||||
if norm == 0:
|
||||
return v
|
||||
return v / norm
|
||||
def always_shift(
|
||||
mobject: Mobject, direction: np.ndarray[np.float64] = RIGHT, rate: float = 0.1
|
||||
) -> Mobject:
|
||||
"""A mobject which is continuously shifted along some direction
|
||||
at a certain rate.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mobject
|
||||
The mobject to shift.
|
||||
direction
|
||||
The direction to shift. The vector is normalized, the specified magnitude
|
||||
is not relevant.
|
||||
rate
|
||||
Length in Manim units which the mobject travels in one
|
||||
second along the specified direction.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. manim:: ShiftingSquare
|
||||
|
||||
class ShiftingSquare(Scene):
|
||||
def construct(self):
|
||||
sq = Square().set_fill(opacity=1)
|
||||
tri = Triangle()
|
||||
VGroup(sq, tri).arrange(LEFT)
|
||||
|
||||
# construct a square which is continuously
|
||||
# shifted to the right
|
||||
always_shift(sq, RIGHT, rate=5)
|
||||
|
||||
self.add(sq)
|
||||
self.play(tri.animate.set_fill(opacity=1))
|
||||
"""
|
||||
mobject.add_updater(lambda m, dt: m.shift(dt * rate * normalize(direction)))
|
||||
return mobject
|
||||
|
||||
|
||||
def always_rotate(mobject, rate=20 * DEGREES, **kwargs):
|
||||
def always_rotate(mobject: Mobject, rate: float = 20 * DEGREES, **kwargs) -> Mobject:
|
||||
"""A mobject which is continuously rotated at a certain rate.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mobject
|
||||
The mobject to be rotated.
|
||||
rate
|
||||
The angle which the mobject is rotated by
|
||||
over one second.
|
||||
kwags
|
||||
Further arguments to be passed to :meth:`.Mobject.rotate`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. manim:: SpinningTriangle
|
||||
|
||||
class SpinningTriangle(Scene):
|
||||
def construct(self):
|
||||
tri = Triangle().set_fill(opacity=1).set_z_index(2)
|
||||
sq = Square().to_edge(LEFT)
|
||||
|
||||
# will keep spinning while there is an animation going on
|
||||
always_rotate(tri, rate=2*PI, about_point=ORIGIN)
|
||||
|
||||
self.add(tri, sq)
|
||||
self.play(sq.animate.to_edge(RIGHT), rate_func=linear, run_time=1)
|
||||
"""
|
||||
mobject.add_updater(lambda m, dt: m.rotate(dt * rate, **kwargs))
|
||||
return mobject
|
||||
|
||||
|
||||
def turn_animation_into_updater(animation, cycle=False, **kwargs):
|
||||
def turn_animation_into_updater(
|
||||
animation: Animation, cycle: bool = False, **kwargs
|
||||
) -> Mobject:
|
||||
"""
|
||||
Add an updater to the animation's mobject which applies
|
||||
the interpolation and update functions of the animation
|
||||
|
||||
If cycle is True, this repeats over and over. Otherwise,
|
||||
the updater will be popped upon completion
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. manim:: WelcomeToManim
|
||||
|
||||
class WelcomeToManim(Scene):
|
||||
def construct(self):
|
||||
words = Text("Welcome to")
|
||||
banner = ManimBanner().scale(0.5)
|
||||
VGroup(words, banner).arrange(DOWN)
|
||||
|
||||
turn_animation_into_updater(Write(words, run_time=0.9))
|
||||
self.add(words)
|
||||
self.wait(0.5)
|
||||
self.play(banner.expand(), run_time=0.5)
|
||||
"""
|
||||
mobject = animation.mobject
|
||||
animation.suspend_mobject_updating = False
|
||||
animation.begin()
|
||||
animation.total_time = 0
|
||||
|
||||
def update(m, dt):
|
||||
def update(m: Mobject, dt: float):
|
||||
run_time = animation.get_run_time()
|
||||
time_ratio = animation.total_time / run_time
|
||||
if cycle:
|
||||
|
|
@ -147,5 +227,5 @@ def turn_animation_into_updater(animation, cycle=False, **kwargs):
|
|||
return mobject
|
||||
|
||||
|
||||
def cycle_animation(animation, **kwargs):
|
||||
def cycle_animation(animation: Animation, **kwargs) -> Mobject:
|
||||
return turn_animation_into_updater(animation, cycle=True, **kwargs)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ from __future__ import annotations
|
|||
|
||||
import itertools as it
|
||||
import math
|
||||
import sys
|
||||
from typing import Any, Iterable
|
||||
from collections.abc import Iterable
|
||||
from typing import Any
|
||||
|
||||
import moderngl
|
||||
import numpy as np
|
||||
|
|
@ -16,7 +16,6 @@ from manim.renderer.shader_wrapper import ShaderWrapper
|
|||
from manim.utils.color import BLACK, color_to_rgba
|
||||
|
||||
from ..constants import *
|
||||
from ..constants import RADIANS
|
||||
from ..utils.simple_functions import fdiv
|
||||
from ..utils.space_ops import normalize
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ cfg``. Here you can specify options, subcommands, and subgroups for the cfg
|
|||
group.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from ast import literal_eval
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
import cloup
|
||||
from rich.errors import StyleSyntaxError
|
||||
from rich.style import Style
|
||||
|
|
@ -28,6 +27,17 @@ If left empty, the default colour will be used.[/red]
|
|||
"""
|
||||
RICH_NON_STYLE_ENTRIES: str = ["log.width", "log.height", "log.timestamps"]
|
||||
|
||||
__all__ = [
|
||||
"value_from_string",
|
||||
"value_from_string",
|
||||
"is_valid_style",
|
||||
"replace_keys",
|
||||
"cfg",
|
||||
"write",
|
||||
"show",
|
||||
"export",
|
||||
]
|
||||
|
||||
|
||||
def value_from_string(value: str) -> str | int | bool:
|
||||
"""Extracts the literal of proper datatype from a string.
|
||||
|
|
@ -123,21 +133,21 @@ def replace_keys(default: dict) -> dict:
|
|||
epilog=EPILOG,
|
||||
help="Manages Manim configuration files.",
|
||||
)
|
||||
@click.pass_context
|
||||
@cloup.pass_context
|
||||
def cfg(ctx):
|
||||
"""Responsible for the cfg subcommand."""
|
||||
pass
|
||||
|
||||
|
||||
@cfg.command(context_settings=cli_ctx_settings, no_args_is_help=True)
|
||||
@click.option(
|
||||
@cloup.option(
|
||||
"-l",
|
||||
"--level",
|
||||
type=click.Choice(["user", "cwd"], case_sensitive=False),
|
||||
type=cloup.Choice(["user", "cwd"], case_sensitive=False),
|
||||
default="cwd",
|
||||
help="Specify if this config is for user or the working directory.",
|
||||
)
|
||||
@click.option("-o", "--open", "openfile", is_flag=True)
|
||||
@cloup.option("-o", "--open", "openfile", is_flag=True)
|
||||
def write(level: str = None, openfile: bool = False) -> None:
|
||||
config_paths = config_file_paths()
|
||||
console.print(
|
||||
|
|
@ -258,8 +268,8 @@ def show():
|
|||
|
||||
|
||||
@cfg.command(context_settings=cli_ctx_settings)
|
||||
@click.option("-d", "--directory", default=Path.cwd())
|
||||
@click.pass_context
|
||||
@cloup.option("-d", "--directory", default=Path.cwd())
|
||||
@cloup.pass_context
|
||||
def export(ctx, directory):
|
||||
directory_path = Path(directory)
|
||||
if directory_path.absolute == Path.cwd().absolute:
|
||||
|
|
|
|||
|
|
@ -5,10 +5,9 @@ from __future__ import annotations
|
|||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
from typing import Callable
|
||||
|
||||
from ..._config import config
|
||||
__all__ = ["HEALTH_CHECKS"]
|
||||
|
||||
HEALTH_CHECKS = []
|
||||
|
||||
|
|
@ -102,45 +101,6 @@ def is_manim_executable_associated_to_this_library():
|
|||
return b"manim.__main__" in manim_exec or b'"%~dp0\\manim"' in manim_exec
|
||||
|
||||
|
||||
@healthcheck(
|
||||
description="Checking whether ffmpeg is available",
|
||||
recommendation=(
|
||||
"Manim does not work without ffmpeg. Please follow our "
|
||||
"installation instructions "
|
||||
"at https://docs.manim.community/en/stable/installation.html "
|
||||
"to download ffmpeg. Then, either ...\n\n"
|
||||
"(a) ... make the ffmpeg executable available to your system's PATH,\n"
|
||||
"(b) or, alternatively, use <manim cfg write --open> to create a "
|
||||
"custom configuration and set the ffmpeg_executable variable to the "
|
||||
"full absolute path to the ffmpeg executable."
|
||||
),
|
||||
)
|
||||
def is_ffmpeg_available():
|
||||
path_to_ffmpeg = shutil.which(config.ffmpeg_executable)
|
||||
return path_to_ffmpeg is not None and os.access(path_to_ffmpeg, os.X_OK)
|
||||
|
||||
|
||||
@healthcheck(
|
||||
description="Checking whether ffmpeg is working",
|
||||
recommendation=(
|
||||
"Your installed version of ffmpeg does not support x264 encoding, "
|
||||
"which manim requires. Please follow our installation instructions "
|
||||
"at https://docs.manim.community/en/stable/installation.html "
|
||||
"to download and install a newer version of ffmpeg."
|
||||
),
|
||||
skip_on_failed=[is_ffmpeg_available],
|
||||
)
|
||||
def is_ffmpeg_working():
|
||||
ffmpeg_version = subprocess.run(
|
||||
[config.ffmpeg_executable, "-version"],
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout.decode()
|
||||
return (
|
||||
ffmpeg_version.startswith("ffmpeg version")
|
||||
and "--enable-libx264" in ffmpeg_version
|
||||
)
|
||||
|
||||
|
||||
@healthcheck(
|
||||
description="Checking whether latex is available",
|
||||
recommendation=(
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import cloup
|
|||
|
||||
from .checks import HEALTH_CHECKS
|
||||
|
||||
__all__ = ["checkhealth"]
|
||||
|
||||
|
||||
@cloup.command(
|
||||
context_settings=None,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
"""DefaultGroup allows a subcommand to act as the main command
|
||||
"""``DefaultGroup`` allows a subcommand to act as the main command.
|
||||
|
||||
In particular, this class is what allows ``manim`` to act as ``manim render``.
|
||||
"""
|
||||
import cloup
|
||||
|
||||
from .. import logger
|
||||
.. note::
|
||||
This is a vendored version of https://github.com/click-contrib/click-default-group/
|
||||
under the BSD 3-Clause "New" or "Revised" License.
|
||||
|
||||
This library isn't used as a dependency as we need to inherit from ``cloup.Group`` instead
|
||||
of ``click.Group``.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import warnings
|
||||
|
||||
import cloup
|
||||
|
||||
__all__ = ["DefaultGroup"]
|
||||
|
||||
|
|
@ -54,8 +64,8 @@ class DefaultGroup(cloup.Group):
|
|||
decorator = super().command(*args, **kwargs)
|
||||
if not default:
|
||||
return decorator
|
||||
logger.log(
|
||||
"Use default param of DefaultGroup or " "set_default_command() instead",
|
||||
warnings.warn(
|
||||
"Use default param of DefaultGroup or set_default_command() instead",
|
||||
DeprecationWarning,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ init``. Here you can specify options, subcommands, and subgroups for the init
|
|||
group.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
|
|
@ -30,6 +31,8 @@ CFG_DEFAULTS = {
|
|||
"resolution": (854, 480),
|
||||
}
|
||||
|
||||
__all__ = ["select_resolution", "update_cfg", "project", "scene"]
|
||||
|
||||
|
||||
def select_resolution():
|
||||
"""Prompts input of type click.Choice from user. Presents options from QUALITIES constant.
|
||||
|
|
@ -47,7 +50,7 @@ def select_resolution():
|
|||
resolution_options.pop()
|
||||
choice = click.prompt(
|
||||
"\nSelect resolution:\n",
|
||||
type=click.Choice([f"{i[0]}p" for i in resolution_options]),
|
||||
type=cloup.Choice([f"{i[0]}p" for i in resolution_options]),
|
||||
show_default=False,
|
||||
default="480p",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,189 +0,0 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
import cloup
|
||||
|
||||
from ... import console
|
||||
from ...constants import CONTEXT_SETTINGS, EPILOG, QUALITIES
|
||||
from ...utils.file_ops import (
|
||||
add_import_statement,
|
||||
copy_template_files,
|
||||
get_template_names,
|
||||
get_template_path,
|
||||
)
|
||||
|
||||
CFG_DEFAULTS = {
|
||||
"frame_rate": 30,
|
||||
"background_color": "BLACK",
|
||||
"background_opacity": 1,
|
||||
"scene_names": "Default",
|
||||
"resolution": (854, 480),
|
||||
}
|
||||
|
||||
|
||||
def select_resolution():
|
||||
"""Prompts input of type click.Choice from user. Presents options from QUALITIES constant.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`tuple`
|
||||
Tuple containing height and width.
|
||||
"""
|
||||
resolution_options = []
|
||||
for quality in QUALITIES.items():
|
||||
resolution_options.append(
|
||||
(quality[1]["pixel_height"], quality[1]["pixel_width"]),
|
||||
)
|
||||
resolution_options.pop()
|
||||
choice = click.prompt(
|
||||
"\nSelect resolution:\n",
|
||||
type=click.Choice([f"{i[0]}p" for i in resolution_options]),
|
||||
show_default=False,
|
||||
default="480p",
|
||||
)
|
||||
return [res for res in resolution_options if f"{res[0]}p" == choice][0]
|
||||
|
||||
|
||||
def update_cfg(cfg_dict: dict, project_cfg_path: Path):
|
||||
"""Updates the manim.cfg file after reading it from the project_cfg_path.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cfg_dict
|
||||
values used to update manim.cfg found project_cfg_path.
|
||||
project_cfg_path
|
||||
Path of manim.cfg file.
|
||||
"""
|
||||
config = configparser.ConfigParser()
|
||||
config.read(project_cfg_path)
|
||||
cli_config = config["CLI"]
|
||||
for key, value in cfg_dict.items():
|
||||
if key == "resolution":
|
||||
cli_config["pixel_height"] = str(value[0])
|
||||
cli_config["pixel_width"] = str(value[1])
|
||||
else:
|
||||
cli_config[key] = str(value)
|
||||
|
||||
with project_cfg_path.open("w") as conf:
|
||||
config.write(conf)
|
||||
|
||||
|
||||
@cloup.command(
|
||||
context_settings=CONTEXT_SETTINGS,
|
||||
epilog=EPILOG,
|
||||
)
|
||||
@cloup.argument("project_name", type=Path, required=False)
|
||||
@cloup.option(
|
||||
"-d",
|
||||
"--default",
|
||||
"default_settings",
|
||||
is_flag=True,
|
||||
help="Default settings for project creation.",
|
||||
nargs=1,
|
||||
)
|
||||
def project(default_settings, **args):
|
||||
"""Creates a new project.
|
||||
|
||||
PROJECT_NAME is the name of the folder in which the new project will be initialized.
|
||||
"""
|
||||
if args["project_name"]:
|
||||
project_name = args["project_name"]
|
||||
else:
|
||||
project_name = click.prompt("Project Name", type=Path)
|
||||
|
||||
# in the future when implementing a full template system. Choices are going to be saved in some sort of config file for templates
|
||||
template_name = click.prompt(
|
||||
"Template",
|
||||
type=click.Choice(get_template_names(), False),
|
||||
default="Default",
|
||||
)
|
||||
|
||||
if project_name.is_dir():
|
||||
console.print(
|
||||
f"\nFolder [red]{project_name}[/red] exists. Please type another name\n",
|
||||
)
|
||||
else:
|
||||
project_name.mkdir()
|
||||
new_cfg = {}
|
||||
new_cfg_path = Path.resolve(project_name / "manim.cfg")
|
||||
|
||||
if not default_settings:
|
||||
for key, value in CFG_DEFAULTS.items():
|
||||
if key == "scene_names":
|
||||
new_cfg[key] = template_name + "Template"
|
||||
elif key == "resolution":
|
||||
new_cfg[key] = select_resolution()
|
||||
else:
|
||||
new_cfg[key] = click.prompt(f"\n{key}", default=value)
|
||||
|
||||
console.print("\n", new_cfg)
|
||||
if click.confirm("Do you want to continue?", default=True, abort=True):
|
||||
copy_template_files(project_name, template_name)
|
||||
update_cfg(new_cfg, new_cfg_path)
|
||||
else:
|
||||
copy_template_files(project_name, template_name)
|
||||
update_cfg(CFG_DEFAULTS, new_cfg_path)
|
||||
|
||||
|
||||
@cloup.command(
|
||||
context_settings=CONTEXT_SETTINGS,
|
||||
no_args_is_help=True,
|
||||
epilog=EPILOG,
|
||||
)
|
||||
@cloup.argument("scene_name", type=str, required=True)
|
||||
@cloup.argument("file_name", type=str, required=False)
|
||||
def scene(**args):
|
||||
"""Inserts a SCENE to an existing FILE or creates a new FILE.
|
||||
|
||||
SCENE is the name of the scene that will be inserted.
|
||||
|
||||
FILE is the name of file in which the SCENE will be inserted.
|
||||
"""
|
||||
if not Path("main.py").exists():
|
||||
raise FileNotFoundError(f"{Path('main.py')} : Not a valid project directory.")
|
||||
|
||||
template_name = click.prompt(
|
||||
"template",
|
||||
type=click.Choice(get_template_names(), False),
|
||||
default="Default",
|
||||
)
|
||||
scene = (get_template_path() / f"{template_name}.mtp").resolve().read_text()
|
||||
scene = scene.replace(template_name + "Template", args["scene_name"], 1)
|
||||
|
||||
if args["file_name"]:
|
||||
file_name = Path(args["file_name"] + ".py")
|
||||
|
||||
if file_name.is_file():
|
||||
# file exists so we are going to append new scene to that file
|
||||
with file_name.open("a") as f:
|
||||
f.write("\n\n\n" + scene)
|
||||
else:
|
||||
# file does not exist so we create a new file, append the scene and prepend the import statement
|
||||
file_name.write_text("\n\n\n" + scene)
|
||||
|
||||
add_import_statement(file_name)
|
||||
else:
|
||||
# file name is not provided so we assume it is main.py
|
||||
# if main.py does not exist we do not continue
|
||||
with Path("main.py").open("a") as f:
|
||||
f.write("\n\n\n" + scene)
|
||||
|
||||
|
||||
@cloup.group(
|
||||
context_settings=CONTEXT_SETTINGS,
|
||||
invoke_without_command=True,
|
||||
no_args_is_help=True,
|
||||
epilog=EPILOG,
|
||||
help="Create a new project or insert a new scene.",
|
||||
deprecated=True,
|
||||
)
|
||||
@cloup.pass_context
|
||||
def new(ctx):
|
||||
pass
|
||||
|
||||
|
||||
new.add_command(project)
|
||||
new.add_command(scene)
|
||||
|
|
@ -5,6 +5,7 @@ plugin``. Here you can specify options, subcommands, and subgroups for the plugi
|
|||
group.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import cloup
|
||||
|
|
@ -12,6 +13,8 @@ import cloup
|
|||
from ...constants import CONTEXT_SETTINGS, EPILOG
|
||||
from ...plugins.plugins_flags import list_plugins
|
||||
|
||||
__all__ = ["plugins"]
|
||||
|
||||
|
||||
@cloup.command(
|
||||
context_settings=CONTEXT_SETTINGS,
|
||||
|
|
|
|||
|
|
@ -5,15 +5,18 @@ Manim's render subcommand is accessed in the command-line interface via
|
|||
can specify options, and arguments for the render command.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import http.client
|
||||
import json
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
|
||||
import click
|
||||
import cloup
|
||||
import requests
|
||||
|
||||
from ... import __version__, config, console, error_console, logger
|
||||
from ..._config import tempconfig
|
||||
|
|
@ -24,14 +27,16 @@ from .global_options import global_options
|
|||
from .output_options import output_options
|
||||
from .render_options import render_options
|
||||
|
||||
__all__ = ["render"]
|
||||
|
||||
|
||||
@cloup.command(
|
||||
context_settings=None,
|
||||
no_args_is_help=True,
|
||||
epilog=EPILOG,
|
||||
)
|
||||
@click.argument("file", type=Path, required=True)
|
||||
@click.argument("scene_names", required=False, nargs=-1)
|
||||
@cloup.argument("file", type=Path, required=True)
|
||||
@cloup.argument("scene_names", required=False, nargs=-1)
|
||||
@global_options
|
||||
@output_options
|
||||
@render_options # type: ignore
|
||||
|
|
@ -110,13 +115,26 @@ def render(
|
|||
if config.notify_outdated_version:
|
||||
manim_info_url = "https://pypi.org/pypi/manim/json"
|
||||
warn_prompt = "Cannot check if latest release of manim is installed"
|
||||
req_info = {}
|
||||
|
||||
try:
|
||||
req_info = requests.get(manim_info_url, timeout=10)
|
||||
req_info.raise_for_status()
|
||||
|
||||
stable = req_info.json()["info"]["version"]
|
||||
with urllib.request.urlopen(
|
||||
urllib.request.Request(manim_info_url),
|
||||
timeout=10,
|
||||
) as response:
|
||||
response = cast(http.client.HTTPResponse, response)
|
||||
json_data = json.loads(response.read())
|
||||
except urllib.error.HTTPError:
|
||||
logger.debug("HTTP Error: %s", warn_prompt)
|
||||
except urllib.error.URLError:
|
||||
logger.debug("URL Error: %s", warn_prompt)
|
||||
except json.JSONDecodeError:
|
||||
logger.debug(
|
||||
"Error while decoding JSON from %r: %s", manim_info_url, warn_prompt
|
||||
)
|
||||
except Exception:
|
||||
logger.debug("Something went wrong: %s", warn_prompt)
|
||||
else:
|
||||
stable = json_data["info"]["version"]
|
||||
if stable != __version__:
|
||||
console.print(
|
||||
f"You are using manim version [red]v{__version__}[/red], but version [green]v{stable}[/green] is available.",
|
||||
|
|
@ -124,16 +142,5 @@ def render(
|
|||
console.print(
|
||||
"You should consider upgrading via [yellow]pip install -U manim[/yellow]",
|
||||
)
|
||||
except requests.exceptions.HTTPError:
|
||||
logger.debug(f"HTTP Error: {warn_prompt}")
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.debug(f"Connection Error: {warn_prompt}")
|
||||
except requests.exceptions.Timeout:
|
||||
logger.debug(f"Timed Out: {warn_prompt}")
|
||||
except json.JSONDecodeError:
|
||||
logger.debug(warn_prompt)
|
||||
logger.debug(f"Error decoding JSON from {manim_info_url}")
|
||||
except Exception:
|
||||
logger.debug(f"Something went wrong: {warn_prompt}")
|
||||
|
||||
return args
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import click
|
||||
from cloup import option, option_group
|
||||
from cloup import Choice, option, option_group
|
||||
|
||||
__all__ = ["ease_of_access_options"]
|
||||
|
||||
ease_of_access_options = option_group(
|
||||
"Ease of access options",
|
||||
|
|
@ -9,7 +10,7 @@ ease_of_access_options = option_group(
|
|||
"--progress_bar",
|
||||
default=None,
|
||||
show_default=False,
|
||||
type=click.Choice(
|
||||
type=Choice(
|
||||
["display", "leave", "none"],
|
||||
case_sensitive=False,
|
||||
),
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue