最近更新时间: 2022-10-10
manim是大佬3Blue1Brown 开发的动画引擎,他使用 manim 创作出了许多直观、美丽的数学科普内容。
它在B站也有也有账号3Blue1Brown。
目前 Manim 主要有三个版本: manim-master (3b1b 新版), ManimCommunity (社区版), manim-cairo-backend (3b1b 旧版)
这篇文章学习以社区版即manimce为主,以及有关于manimce的学习也可以去看社区版的官方文档https://docs.manim.community/。
首先manim本身是一个python项目,安装python是必不可少的,这里默认大家都会。
然后,manim的运行环境的组成分为三个部分:manim、ffmpeg、latex发行版
为了项目的整体可迁移性,我选择了pipenv虚拟环境并安装了以下包:
pip install manim
pip install ffmpeg
latex发行版可以选择Texlive-full
、MiKTeX
manim的工作流程是由好几个部分组成的。
简单的来说,就是以下几步:
在manim里,可以在屏幕里显示的对象,都被称之为Mobject
Mobject是很多其他类的父类:
VMobject十分灵活多变,本质上是贝塞尔曲线,可以展现各式各样的矢量图形,在manim里,文本也是VMobject。
ImageMobject本质上是像素的矩阵。
Group/VGroup这两个可以作为容器包含多个对象,Group可以包含任何Mobject,VGroup只能包含VMobject或VMobject的子类实例
manim中动画Animations抽象类
可以分为两大类,Scene.play
动画、Updaters
动画。
play动画可以播放类动画(Class动画)或者方法动画(method动画),实质二者并没有什么差别,因为方法动画是类动画的子类型。
而Updaters是动画每一帧都会调用的函数,Updaters有三种不同类型:Simple updaters、α updaters、dt updaters
所有的Class动画都是继承自Animations抽象类
。
它有以下几个重要特性:
run_time
表示动画的运行时长rate_func
动画速率函数remover
如果改参数为true,那么相应的Mobject将在动画运行结束后从屏幕中删除方法名 | 作用 |
---|---|
Scene.add | 立即向屏幕中添加一个或多个Mobject(无需设置持续时间) |
Scene.remove | 立即从屏幕中删除一个或多个Mobject |
Scene.wait | 动画暂停时长,默认1秒 |
Scene.play | 在同一个Scene.play方法中可以有多个Class动画,所有动画将在同一时间开始运行 |
move_to | 接受一个三维向量,将对象移动到该位置。也可以接受一个对象,移动到该对象的位置 |
to_edge | 移动到屏幕边沿,另外可以传递一个buff参数,表示与边沿的距离 |
to_corner | 移动到屏幕的一个角,也接受buff参数 |
shift | 相对当前位置移动 |
next_to | 移动到对象附件,接受两个可选参数,buff距离,alinged_edge,对齐方式 |
alinged_edge | 将一个对象对齐于另一个对象 |
set_z_index | 设置对象上下顺序,所有对象创建时默认z_index为0,这个方法不能使用"animate"属性调用动画 |
set_opacity | 传入一个α,设置绝对数值来设置不透明度 |
set_fade | 以相对数值来设置不透明度 |
绝对定位,以屏幕为参考坐标,原点位置在屏幕中心
默认情况下,所有的Mobject都创建在屏幕正中心的位置
.move_to
.to_edge
to_corner
相对定位,以某个对象或是某个点为参考而相对移动位置
.shift
.next_to
.aligned_edge
需要注意的是,以上方法是立即生效的,如果需要移动动画,可以调用animation属性
# 立即生效
c.move_to(UR)
self.wait()
c.to_edge(RIGHT)
self.wait()
c.align_ti(s.RIGHT)
self.wait()
# 移动动画
self.play(c.animate.move_to(UR))
self.wait()
self.play(c.animate.to_edge(RIGHT))
self.wait()
self.play(
c.animate(run_time=3)
.align_to(s.RIGHT)
)
self.wait()
所有的对象都有默认的大小,几乎所有的Mobject动画都可以使用animate
属性调用
tips:
.rotate()
和.flip()
这两个方法属于特殊情况
Mobjects变形方法可以分为三类
Without stretch | With stretch | Rotation |
---|---|---|
.set() | .stretch_to_fit_width() | .rotate() |
.scale_to_fit_width() | .stretch_to_fit_height() | .filp() |
.scale_to_fit_height() | ||
.match_width() | ||
.match_height() |
也可以通过控制缩放因子.scale()
来变形缩放
以上变换都可以使用.apply_matrix()
实现
Getter就是可以从对象上获取各种信息的方法,这些方法的名字大多都是以get前缀开始的。
Setter方法可以用来更改对象的属性
属性名 | 属性 |
---|---|
stroke_color | 描边颜色 |
stroke_width | 描边宽度 |
stroke_opacity | 描边不透明度 |
fill_color | 填充颜色 |
fill_opacity | 填充区域不透明度 |
background_stroke_color | 描边背景颜色 |
background_stroke_width | 描边背景宽度 |
background_stroke_opacity | 描边背景不透明度 |
manim提供了三种方法给我们自定义配置:config.cfg文件
、CLI(命令行接口)
、CONFIG字典对象
manim所有的默认配置可以用以下命令查看:
manim cfg show
我们可以通过创建自己的cfg文件来启用自己想要的配置。
cfg文件中可以配置的选项可以分为五个类别:[CLI]
、custom_folders
、[logger]
、[ffmpeg]
、[jupyter]
使用以下的命令格式就可以使用自己指定的配置文件,不使用-c默认使用当前目录下的manim.cfg
:
manim <scripts.py> <scene-name> <quality-flag> -c <config-file.cfg>
使用下列命令可以很容易的生成配置文件:
manim cfg write -o
tips: 如果当前目录已存在manim.cfg,这个命令会覆盖当前的manim.cfg!
[CLI]
background = #000000
# debug相关
preview = False
verbosity = INFO
# = [DEBUG|INFO|WARNING|ERROR|CRITICAL]
progress_bar = display
# = [display|leave|none]
# caching相关
max_files_cached = 100
disable_caching = False
disable_caching_warning = False
# folders相关
media_dir = ./media
assets_dir = ./
video_dir = {media_dir}/videos/{module_name}/{quality}
images_dir = {media_dir}/images/{module_name}
tex_dir = {media_dir}/Tex
text_dir = {media_dir}/texts
partial_movie_dir = {video_dir}/partial_movie_files/{scene_name}
个人在用配置:
media_dir = ./exports
assets_dir = ./assets
video_dir = {media_dir}/videos/{module_name}/{quality}
images_dir = {media_dir}/images/{module_name}/{quality}
tex_dir = ./tmp/Tex
text_dir = ./tmp/texts
partial_movie_dir = ./tmp/partial_movie_files/{module_name}/{quality}/{scene_name}
以及我们可以定义[custom_folders]
:
[custom_folders]
media_dir = custom_export
assets_dir = {media_dir}
section_dir = {medeia_dir}
images_dir = {media_dir}
tex_dir = {media_dir}/temp_files
text_dir = {media_dir}/temp_files
log_dir = {media_dir}/temp_files
partial_movie_dir = {media_dir}/partial_movie_files/{scene_name}
只有在使用--custom_folders
命令行选项参数才可与激活这种文件夹结构,同时[CLI]
结构里的属性会被忽略,比较适合用来临时测试
仅列出较为常用的
# config,指定使用的.cfg文件
-c file.cfg
# preview,渲染完成后打开预览
-p
# quality,质量参数,可选对应质量渲染
# -l 480p 15fps, -m 720p 30fps, -h 1080p 60fps, -p 1440p 60fps, -k 2160p 60fps
-q
# 自定义分辨率
--fps=SOME_FPS
-r WIDTH,HEIGHT
# 将帧一帧帧输出格式为png
--format=png
# 输出格式为gif
--format=gif
# 默认输出格式,输出格式为mp4
--format=mp4
# 输出格式为webm,浏览器里特有的格式
--format=webm
# 输出格式为mov,这个选项是输出质量最好的,它不会压缩视频,所以输出文件会比其他选项要大得多
--format=mov
# 将最后一帧渲染为图片
-s
# 渲染有透明背景的视频或图片
-t
这是manim中的全局变量
,包含有manim项目的各种配置信息。
这个字典变量里包含的各种属性和通过[CLI(命令行接口)]或是.cfg配置文件里配置的选项是一样的。
修改它十分简单,修改方式和python修改字典对象的方式是一样的:
config.property = VALUE
config["property"] = VAlUE
代码中可以获取config字典的属性值
这三种方式,CONGFIG字典的优先级是最高的
CONFIG 字典
CLI(命令行接口)
.cfg 配置文件
可以传入0~1之间的参数t,可以定义其他参数,只要其他参数有默认值即可
def parabola(t, amp=0.5):
return (1-(2*t-2)**2)*amp
circle = Circle()
self.play(ScaleInPlace(
circle, 3,
run_time=5,
rate_func=parabola
)
)
grp = Group(mob1, mob2, ..., mobn)
grp.add(other_mob) # 添加到最上层
grp.add_to_back(other_mob) # 添加到最底层
grp.remove(other_mob)
manim中并不实际存在文本对象。
本质上,manim中的文本包括latex都是svg图形。
manim通过调用一个名为Pango的工具将文本转化为svg,然后将其导入(通过哈希值确定其唯一命名)
可以使用这段命令行查看已安装的字体:
python -c "import manimpango; from pprint import pprint; pprint(manimpango.list_fonts())"
Transform
是一个父类,所有其他的变形动画类都继承自该类,它也是一个动画类。
Transform(base_object, target)
ReplacementTransform(base_object, target)