如何让Manim识别LaTeX文件中的\pause并插入2秒动画停顿?
基于LaTeX的
\pause实现Manim手写动画停顿 原始LaTeX文件(latex_slides.tex)
\documentclass{article}% \def\pause{} \pagestyle{empty} \begin{document} \pause $E=mc^2$ \pause \begin{enumerate} \item One\pause \item Two\pause \item Three\pause \end{enumerate} \end{document}
需求
用Manim制作模拟手写的文本动画,以上述LaTeX文件为输入,每遇到\pause命令时,给动画插入2秒停顿。现有脚本能实现手写效果,但无法识别\pause并自动添加停顿。
现有Python脚本
from manim import * class LaTeXAnim(Scene): def construct(self): myfile = TexTemplate.from_file("latex_slides.tex") tex = Tex(r"{}", tex_template = myfile) self.play(Write(tex, rate_func = smooth, lag_ratio = 0.25, run_time = 5)) self.wait(2)
解决方案一:拆分LaTeX内容分段动画
直接读取LaTeX文件,按\pause将内容拆分为多段,每段完成手写动画后插入2秒停顿。
修改后的Python脚本:
from manim import * class LaTeXAnim(Scene): def construct(self): # 读取LaTeX文件内容 with open("latex_slides.tex", "r") as f: content = f.read() # 提取document环境内的核心内容 start = content.find(r"\begin{document}") + len(r"\begin{document}") end = content.find(r"\end{document}") doc_content = content[start:end].strip() # 按\pause拆分内容,过滤空片段 segments = [seg.strip() for seg in doc_content.split(r"\pause") if seg.strip()] # 加载TeX模板并移除原有空\pause定义 tex_template = TexTemplate.from_file("latex_slides.tex") tex_template.body = tex_template.body.replace(r"\def\pause{}", "") # 逐段生成动画 for seg in segments: tex = Tex(seg, tex_template=tex_template) # 首次直接添加内容,后续替换原有内容 if not self.mobjects: self.add(tex) else: self.play(Transform(self.mobjects[0], tex)) # 播放手写动画 self.play(Write(tex, rate_func=smooth, lag_ratio=0.25, run_time=3)) # 插入2秒停顿 self.wait(2)
解决方案二:生成特殊标记解析SVG实现停顿
先修改LaTeX中的\pause定义,生成Manim可识别的特殊标记,再解析渲染后的SVG文件找到标记位置,对应插入停顿。
- 修改latex_slides.tex的
\pause定义:
\documentclass{article}% % 让\pause生成带特殊ID的标记,方便后续识别 \def\pause{\special{pdf: put @<pauseMarker@>}} \pagestyle{empty} \begin{document} \pause $E=mc^2$ \pause \begin{enumerate} \item One\pause \item Two\pause \item Three\pause \end{enumerate} \end{document}
- 修改Python脚本解析标记:
from manim import * import xml.etree.ElementTree as ET class LaTeXAnim(Scene): def construct(self): tex_template = TexTemplate.from_file("latex_slides.tex") tex = Tex(r"{}", tex_template=tex_template) tex.generate_target() # 解析生成的SVG文件,统计pauseMarker标记数量 svg_path = tex.get_svg_file() tree = ET.parse(svg_path) root = tree.getroot() pause_count = len(root.findall(".//*[@id='pauseMarker']")) # 计算分段动画的时间间隔 total_run_time = 5 interval = total_run_time / (pause_count + 1) # 分段播放动画,每段后插入停顿 current_time = 0 anim = Write(tex, rate_func=smooth, lag_ratio=0.25, run_time=total_run_time) for _ in range(pause_count): self.play(anim, run_time=interval) self.wait(2) current_time += interval # 播放最后一段动画 self.play(anim, run_time=total_run_time - current_time)
内容的提问来源于stack exchange,提问作者digital-Ink
相关产品推荐
相关产品推荐

