input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字...

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第1张图片

花里胡哨的文字

前两篇介绍了基本几何图形外形、位置及动作的定义。

3Blue1Brown 动画制作教程(1)​zhuanlan.zhihu.com
input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第2张图片
3Blue1Brown 动画制作教程(2)​zhuanlan.zhihu.com
input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第3张图片

本文主要涉及与图形相辅相成的文字的外形、位置及动作的定义。

美观、灵动的文字亦是 3B1B 动画的一大亮点,文字对象通常由一个称为 TextMobject (Text Math object) 的类实例化得到,TextMobject 类继承于前面图形所属的 VMobject (Vectorized Math object) 类,强调这一点的原因是:由这种继承关系可知前两篇适用于图形对象的那些方法同样也适用于文字对象。

现在打开 manim 根目录下的 manim_tutorial_P37.py 教程文件,找到其中名为 AddingText 的类:

1. class AddingText(Scene):
2.     #Adding text on the screen
3.     def construct(self):
4.         my_first_text=TextMobject("Writing with manim is fun")
5.         second_line=TextMobject("and easy to do!")
6.         second_line.next_to(my_first_text,DOWN)
7.         third_line=TextMobject("for me and you!")
8.         third_line.next_to(my_first_text,DOWN)
9.
10.        self.add(my_first_text, second_line)
11.        self.wait(2)
12.        self.play(Transform(second_line,third_line))
13.        self.wait(2)
14.        second_line.shift(3*DOWN)
15.        self.play(ApplyMethod(my_first_text.shift,3*UP))

为了实现这段由文字组成的对话,可以用之前的指令格式,以管理员模式打开 Anaconda Prompt ,跳转到 manim 的根目录,由于动画分辨率低文字可能显示不佳,所以可以把最后一个参数改为“-p”:

 python -m manim manim_tutorial_P37.py AddingText -p

或者用一种简化命令:

python -m manim manim_tutorial_P37.py -pl

该命令只有前四个参数及最后一个输出调整参数,输入回车后会显示脚本中所有的类,只需要输入对应的编号就能实例化对应的类,这里输入数字 2 后回车即可。

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第4张图片

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第5张图片

注释:如果生成文字的过程当中出现 .svg 文件无法生成的情况,以管理员模式分别运行一下几条命令之后再运行上述命令(如果没有出现错误则不必了):

  • regsvr32 MiKTeX209-core-PS.dll
  • regsvr32 MiKTeX209-core.dll
  • regsvr32 MiKTeX209-packagemanager-PS.dll
  • regsvr32 MiKTeX209-packagemanager.dll

现在分析一下代码内容,前3行就不多说了,前两篇已经说得很清楚了,直接看第4行到第8行:

4.        my_first_text=TextMobject("Writing with manim is fun")
5.        second_line=TextMobject("and easy to do!")
6.        second_line.next_to(my_first_text,DOWN)
7.        third_line=TextMobject("for me and you!")
8.        third_line.next_to(my_first_text,DOWN)

4、5、8行分别通过实例化 TextMobject 类得到三条文字,如果不加其他设定,文字在显示的时候默认是置于画面中心的,为了使得文字按需放置,第6行和第8行应用 next_to() 方法将第二条文字与第三条文字均置于第一条文字的正下方,之间的距离都是1个单位,因为 参数 “DOWN” 对应的是(0,-1,0)向量,在教程(2)中已经说过。这样文字对象的内容及其初始位置都定义好了,接下来就是定义如何去显示这些文字。

10.        self.add(my_first_text, second_line)
11.        self.wait(2)
12.        self.play(Transform(second_line,third_line))
13.        self.wait(2)
14.        second_line.shift(3*DOWN)
15.        self.play(ApplyMethod(my_first_text.shift,3*UP))
  • 第10行:将第一条和第二条文字添加到画面中;
  • 第11行和第13行:整个画面停顿2秒;
  • 第12行:将第二条文字切换为第三条文字;
  • 第14行:将第二条文字以原始位置为基准往下移动三个单位;
  • 第15行:通过对运动过程补帧,将第一条文字网上移动三个单位。

为了方便查看效果,在这里再放一次动画:

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第6张图片

细心的朋友一定会发现这里面需要注意好几个点:

首先文字的添加与动作命令与前面定义图形时的方法是完全一致的,妙啊;

然后,第12行虽然将第二条文字的切换为了第三条文字,但是第14行移动的依然是对 second_line 进行操作,也就是说,Transform() 方法是在将其中输入的第二个参数所指代对象的所有属性赋予给了第一个参数所指代对象,但并没有改变第一个参数所指代对象的名称;

最后,直接使用 shift() 方法和借用 ApplyMethod() 间接实现 shift() 方法的本质不同在于,shift() 是直接实现图形或文字对象在两个坐标之间的跳转,而 ApplyMethod() 则可以实现在两个位置之间切换时的补帧动画,格式是 ApplyMethod(对象名.定位方法名, 定位向量) ,注意在 ApplyMethod() 中输入参数的时候,定位方法名后面是没有小括号的。

接着,介绍更多关于文字的操作,找到 manim_tutorial_P37.py 脚本文件中名为 AddingMoreText 的类:

1. class AddingMoreText(Scene):
2.     #Playing around with text properties
3.     def construct(self):
4.         quote = TextMobject("Imagination is more important than knowledge")
5.         quote.set_color(RED)
6.         quote.to_edge(UP)
7.         quote2 = TextMobject("A person who never made a mistake never tried anything new")
8.         quote2.set_color(YELLOW)
9.         author=TextMobject("-Albert Einstein")
10.        author.scale(0.75)
11.        author.next_to(quote.get_corner(DOWN+RIGHT),DOWN)
12.
13.        self.add(quote)
14.        self.add(author)
15.        self.wait(2)
16.        self.play(Transform(quote,quote2),ApplyMethod(author.move_to,quote2.get_corner(DOWN+RIGHT)+DOWN+2*LEFT))
17.        self.play(ApplyMethod(author.scale,1.5))
18.        author.match_color(quote2)
19.        self.play(FadeOut(quote))

这里主要的新内容有:

  • set_color() 方法,用来定义文字的颜色,各种颜色关键字定义位于 ~manimmanimlibconstants.py 文件中。
  • match_color() 方法,除了直接设定颜色,也可以通过匹配颜色将一个图形或文字的颜色赋给另一个图形或文字。
  • to_edge() 方法,输入参数有 UP、DOWN、LEFT、RIGHT,可以将图形或文字与画面的上、下、左、右边界的中心对齐。
  • get_corner() 方法,任意所有图形或文字都处于一个矩形边界框之中,该边界框可能不显示出来,但一定存在,那么就会有四个角点与之对应,通过 get_corner() 方法就可以得到角点的位置坐标,其输入参数有四种 UP+LEFT、UP+RIGHT、DOWN+LEFT 和 DOWN+RIGHT,分别用来指定边界框的四个角点。
  • scale() 方法,缩放图形或文字,输入参数即为缩放的倍数,大于1是放大,小于1是缩小。

以管理员模式打开 Anaconda Prompt ,跳转到 manim 的根目录,输入:

python -m manim manim_tutorial_P37.py AddingMoreText -p

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第7张图片

对于其中的展示部分的解释:

13.        self.add(quote)
14.        self.add(author)
15.        self.wait(2)
16.        self.play(Transform(quote,quote2),ApplyMethod(author.move_to,quote2.get_corner(DOWN+RIGHT)+DOWN+2*LEFT))
17.        self.play(ApplyMethod(author.scale,1.5))
18.        author.match_color(quote2)
19.        self.play(FadeOut(quote))
  • 第13行:将名为 quote 的文字添加到画面;
  • 第14行:将名为 author 的文字添加到画面;
  • 第15行:停顿2秒;
  • 第16行:将 quote 中的文字内容和位置变为 quote2 中的文字内容和位置,由于 quote2 没有定义过位置,所以默认位置在画面中心;
  • 第17行:放大 author 为原来的1.5倍;
  • 第18行:将 author 的颜色匹配为 quote2 的颜色;
  • 第19行:quota 淡出画面。

除此之外,还可以定义文字的旋转和高亮显示。找到 manim_tutorial_P37.py 脚本文件中名为 RotateAndHighlight 的类:

1. class RotateAndHighlight(Scene):
2.     #Rotation of text and highlighting with surrounding geometries
3.     def construct(self):
4.         square=Square(side_length=5,fill_color=YELLOW, fill_opacity=1)
5.         label=TextMobject("Text at an angle")
6.         label.bg=BackgroundRectangle(label,fill_opacity=1)
7.         label_group=VGroup(label.bg,label)  #Order matters
8.         label_group.rotate(TAU/8)
9.         label2=TextMobject("Boxed text",color=BLACK)
10.        label2.bg=SurroundingRectangle(label2,color=BLUE,fill_color=RED, fill_opacity=.5)
11.        label2_group=VGroup(label2,label2.bg)
12.        label2_group.next_to(label_group,DOWN)
13.        label3=TextMobject("Rainbow")
14.        label3.scale(2)
15.        label3.set_color_by_gradient(RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE)
16.        label3.to_edge(DOWN)
17.
18.        self.add(square)
19.        self.play(FadeIn(label_group))
20.        self.play(FadeIn(label2_group))
21.        self.play(FadeIn(label3))

新内容主要在文字对象的定义部分:

  • 第4行:定义一个边长为5个单位的正方形填充颜色为黄色且不透明;
  • 第5行:定义一段名为 label 的文字;
  • 第6行:依据 label 的背景定义一个名为 label.bg 的矩形并设置为不透明(默认是黑色但透明);
  • 第7行:用 VGroup() 方法定义组合,将 label.bg 矩形和 label 文字设置为一个组合 label_group,注意参数的先后顺序将决定层,先输入的在下层,后输入的在上层;
  • 第8行:将组合 label_group 中的所有图形或文字绕中心逆时针旋转
    ,也就是逆时针转45°,因为TAU值的为
    ;
  • 第9行:定义一段名为 label2 的文字,颜色为黑;
  • 第10行:依据 label2 的边界框定义一个名为 label2.bg 的矩形框,矩形框的颜色为蓝色,填充为红色,透明度为0.5;
  • 第11行: 将 label2 文字和 label2.bg 矩形设置为一个组合 label2_group;
  • 第12行:将 label2_group 组合置于 label1_group 组合的下方,距离为一个单位长度;
  • 第13行:定义一段名为 label3 的文字;
  • 第14行:将 label3 文字的大小设为默认大小的两倍;
  • 第15行:将 label3 文字的颜色按照字母顺序设为不同的颜色;
  • 第16行:将 label3 文字与画面的底部对齐。

这里关键在于组合的概念及层的概念,由于图形文字之间有重叠部分,要记住的是,先展现出来的图形、文字在下层,后展现的图形、文字在上层。

另外,用BackgroundRectangle() 定义出来的矩形默认是不显示边框的,而SurroundingRectangle() 定义出来的则是矩形框。

以管理员模式打开 Anaconda Prompt ,跳转到 manim 的根目录,输入:

python -m manim manim_tutorial_P37.py RotateAndHighlight -p

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第8张图片

——

有知友 @Raion 问能不能渲染中文,是可以的,而且方法很简单,只需要将~manimmanimlibconstants.py 文件中的 TEX_USE_CTEX = False 改为 TEX_USE_CTEX = True 即可,甚至也适用于日文:

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第9张图片
class Chinese(Scene):
    def construct(self):
        line1=TextMobject("你好")
        line2=TextMobject("こんにちは")
        line2.shift(DOWN)
        self.play(Write(line1))
        self.play(Write(line2))
        self.wait(2)

将上面的代码添加到教程代码 manim_tutorial_P37.py 中然后以管理员模式启用 Anaconda prompt ,跳转到 manim 的根目录,输入:

python -m manim manim_tutorial_P37.py Chinese -p

由于 LaTeX 的安装配置的一些不明原因,可能会导致有的用户字体包不完备,运行时出错,一时间也找不到问题究竟出在哪,也可以试试以下代码,算是权宜之计。不过我个人还是不太建议在学习如何使用 manim 的时候尝试中文或其他语言,因为编译的时候可能出现各种各样的问题,不妨先只用英文,学会最基本的编程方法,之后有余力再去解决中文带来的各种 Bug:

class Chinese(Scene):
    def construct(self):
        line1=Text("你好",font='songti')
        line2=Text("こんにちは",font='mincho')
        line2.shift(DOWN)
        self.play(Write(line1))
        self.play(Write(line2))
        self.wait(2)

小结

看完前三篇教程,相信大家对图形及文字的定义和展现方法已经有了系统的认识,manim 对图形的处理手段和对文字的处理手段是类似的,只是文字相对图形尤其自身的一些特性,毕竟文字类 TextMobject 是矢量化类 VMobject 的一个子类。更多的图形、文字相关的内容还需要自己动手编程来实训。下一篇将重点说说数学公式。

李狗嗨:3Blue1Brown 动画制作教程(4)​zhuanlan.zhihu.com
input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第10张图片

更多内容,尽在专栏:

直观の数学​zhuanlan.zhihu.com
59b798e6f9025bdd5a7b8a923c414db8.png

input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字..._第11张图片

#原创文章,知乎首发,

未经允许,不得转载#

你可能感兴趣的:(input框文字输入文字为什么后面的数字出现在左边_3Blue1Brown 动画制作教程(3)--花里胡哨的文字...)