用 LaTeX 制作动画

我们在制作文档、幻灯片时,一些概念性的内容可能通过动画的方式能够更清晰地表达。这些概念性的图通常来说比较简单,使用 LaTeX\LaTeX 的 tikz 宏包或其他类似的绘图语言可以很方便地进行绘制,结合 TeX\TeX 的发行版提供的 animate 宏包则可以方便地生成动画。本文将对这部分内容进行叙述。

使用 animate 宏包创建 pdf 动画

以 tikzpicture 手动绘制关键帧并结合 animate 进行动态 pdf 文件的制作示例代码如下,其中关于 animate 的用法可参考其使用手册。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
\documentclass{standalone}
\usepackage{tikz,animate}

% creation of the ove.txt timeline file
\newwrite\Fichier
\immediate\openout\Fichier=ove.txt
\foreach \n in {0,1,...,6}{
\immediate\write\Fichier{::\n x0}
}
\immediate\closeout\Fichier% always close the file

\newcommand{\Debut}{% Systematic start of drawing
\begin{tikzpicture}
\useasboundingbox (-2.5,-2.5) rectangle (4,2.5);}
\newcommand{\Fin}{\end{tikzpicture} }% Systematic end of drawing
\begin{document}
\begin{animateinline}[autoplay,begin={\Debut},end={\Fin},timeline=ove.txt]{1.5}
\draw[thick] (-2.5,0)--(4,0);
\draw[thick] (0,-2.5)--(0,2.5);
\newframe% circle - transparent 1
\draw[thick] (0,0) circle (2cm);
\newframe% half-line 1 - transparent 2
\draw[thick] (0,-2)--(3,1);
\newframe% half-line 2 - transparent 3
\draw[thick] (0,2)--(3,-1);
\newframe% arc 1 - transparent 4
\draw[thick](0,2)arc[start angle=90,end angle=45,radius=4cm];
\newframe% arc 2 - transparent 5
\draw[thick](0,-2)arc[start angle=-90,end angle=-45,radius=4cm];
\newframe% arc 3 - transparent 6
\draw[thick]([xshift=2cm]45:1.171573cm)arc[start angle=45,end angle=-45,radius=1.171573cm];
\end{animateinline}
\end{document}

上述代码的第 5~10 行用于输出时间线文件 ove.txt 从而可以简化代码的内容,使各关键帧中重复的内容无需重复绘制,当ove.txt 生成后,后续可以注释掉这 5 行代码。代码使用任意 LaTeX\LaTeX 编译引擎编译,可以得到动态的 testgif.pdf 文件(假定代码文件名为 testgif.tex)效果如下:

testgif.pdf

创建 gif 格式的动画

使用上述方法生成的动画是一个 pdf 文件,可能在 Microsoft Word 文件中或网页文件中并不方便使用,有这种需要时可以提取动画中的关键帧,并使用 Imagemagick 转换为 gif 文件。

使用 animate 宏包创建各关键帧单独成页的 pdf 文件

使用 LaTeX\LaTeX 创建动画时,若需要获取关键帧的图像,则应在 animate 宏包载入时使用 export 选项,或将 export 作为文档类的全局选项加载。将前述 LaTeX\LaTeX 代码的第一行改为:

1
\documentclass[export]{standalone}

即可,以此编译出的 testgif.pdf 文件中,关键帧则单独成页。
testgif-1.png
testgif-1.png
testgif-1.png
testgif-1.png
testgif-1.png
testgif-1.png
testgif-1.png

使用 pdftocairo 输出各关键帧的 png 图像文件

利用 cairo 库可以将 pdf 文件中的各页单独输出为一个 png 图像,命令行执行:

1
pdftocairo -png testgif.pdf

在同一目录下则生成 testgif-01.png、testgif-02.png …… 等一系列 png 文件。

使用 Imagemagick 程序命令 magick 输出 gif 文件

安装 Imagemagick 程序后,可以在命令行使用 magick 或 convert 命令将一系列 png 文件转换为 gif 文件。命令名称取决于安装时的设定,在 Linux 下为 convert,Windows 下通常为避免与系统的 convert (Windows 下这个命令用于转换磁盘文件系统格式)重名而使用 magick,当然安装时也可以设定使用 convert 命令,但这时自己必须清楚两个可执行文件的路径在系统变量 PATH 中的排列顺序,从而能准确调用正确的程序。以 Windows 下使用 magick 为例,命令行应执行:

1
magick -delay 50 -loop 0 *.png output.gif

其中用 -delay 控制每帧切换的时间,单位为 ms,-loop 控制播放次数,-loop 0 则表示无限循环播放。magick(或 convert)命令的其他参数可以参考其使用手册。

使用 animate 宏包和 dvisvgm 创建动态的 svg 文件

另外一种生成动画文件的方式是生成动态的 svg 文件,这类文件可以在 Chromium 内核的浏览器中查看显示。生成方法是对 animate 宏包使用 dvisvgm 选项。以使用文档类全局选项为例,将代码第一行改为:

1
\documentclass[dvisvgm]{standalone}

编译时则应该使用 latex 或 xelatex 进行编译,后者还应该使用 --no-pdf 参数来输出 xdv 文件;随后使用 dvisvgm 命令转换 dvi 文件和 xdv 文件。命令行应执行:

1
2
3
4
5
6
7
# latex 编译
latex testgif.tex
dvisvgm testgif.dvi

# xelatex 编译
xelatex --no-pdf testgif.tex
dvisvgm testgif.xdv

此时得到的 svg 文件即为动画文件,可以将 <svg> 标签内的内容直接写入 html 文件形成动画。

感谢拨冗阅读本文,若有些许收获,不妨捐赠以资鼓励。