![分割投影机动画](https://linux22.com/image/246499/%E5%88%86%E5%89%B2%E6%8A%95%E5%BD%B1%E6%9C%BA%E5%8A%A8%E7%94%BB.png)
我有一个复杂的动画,它在一系列幻灯片中演变(\foreach \frm in {1,...,12}\only<\frm>{
循环,其中在各个幻灯片上使用 选择某些部分\visible
)。
到目前为止,我已将所有叠加层放在一个框架内,但我想将其分配到多个框架中,以便我可以将其他框架(包含文本和其他内容)放在它们之间,因此我将tikzpicture
创建所有叠加层的整个位置移动到了一个\newcommand{\makeAnimation}[1]
我可以说的位置,例如
\begin{frame}{First part of the animation}
\makeAnimation{1,...,4}
\end{frame}
\begin{frame}{Some explanations}
Lorem ipsum
\end{frame}
\begin{frame}{Next part}
\makeAnimation{4,...,7}
\end{frame}
(一次性创建整个内容更容易,因为否则我必须复制大量代码)
但是,在由 (正确) 生成的动画部分之后,\makeAnimation{1,...,4}
我得到了一个额外的空白幻灯片,我无法将其移开。更糟糕的是,如果我将语句\only
之后的语句更改\foreach
为\visible
(这可以防止居中的 tikzpicture 跳来跳去),它会生成从 1 ... 12 的所有幻灯片,但将 5 ... 12 留空。
我该如何修复这个问题并去掉多余的幻灯片?目前,只要我不必拆分/重做动画,我就会接受任何黑客攻击。
小例子:
\documentclass[
presentation,
english,
]{beamer}
%\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{tikz}
\newcommand{\makeAnimation}[1]{
\begin{center}
\scalebox{0.7} {
\begin{tikzpicture}
\foreach \frm in {#1} {
\only<\frm>{
\node {FRAME \frm};
\visible<3>{\node at (4,0) {three hippos};}
\visible<4-5>{\node (a) at (2,0) {a couple giraffes};}
\visible<5-6>{\node (b) at (4,2) {hello};}
\visible<5>{\path[-] (a) edge (b);}
\visible<6>{\node at (4,0) {six elephants};}
}
}
\end{tikzpicture}
}
\end{center}
}
\begin{document}
\begin{frame}{foo}
\makeAnimation{1,...,4}
\end{frame}
\begin{frame}{bar}
next slide
\end{frame}
\end{document}
生产
foo FRAME 1
foo FRAME 2
foo FRAME 3 three hippos
foo FRAME 4 a couple giraffes
foo % evil blank slide
bar next slide
答案1
如果我可以这么大胆的话,我想说你做错了。 beamer
有一种内置的“切割”帧的方式:命令\againframe
,结合要切割的帧上的叠加规范。它在手册的第 11.2 节(“在稍后重复帧”)中有描述,其工作原理如下:
\documentclass[
presentation,
english,
]{beamer}
%\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{tikz}
\begin{document}
\begin{frame}<1-4>[label = foo]{foo}
\begin{tikzpicture}
\onslide<1>
\node {Frame 1};
\onslide<2>
\node {Frame 2};
\onslide<3>
\node at (4,0) {three hippos};
\onslide<4-5>
\node (a) at (2,0) {a couple giraffes};
\onslide<5-6>
\node (b) at (4,2) {hello};
\onslide<5>
\path[-] (a) edge (b);
\onslide<6>
\node at (4,0) {six elephants};
\end{tikzpicture}
\end{frame}
\begin{frame}{bar}
next slide
\end{frame}
\againframe<4-6>{foo}
\end{document}
基本上,第一帧是动画的“模板”,并替换您的\makeAnimation
。叠加规范仅表示运行四张幻灯片,然后切换到说明。然后\againframe
进入并生成幻灯片 4 到 7 以完成动画。
我有点恼火,因为必须单独编写Frame 1
和Frame 2
,因为确实存在一个计数器framenumber
,它应该在单个\theframenumber
命令中打印正确的值。然而,当我尝试
\onslide<1-2>
\node {Frame \theframenumber};
它只是打印了两次“Frame 1”。使用 也\only<1-2>
做了同样的事情,事实上,使用Frame \theframenumber
两个\onslide
命令后也打印了“Frame 1” \onslide<2>
!也许这是一个错误;当然,手册中没有提到这个计数器,所以也许它不受支持。
答案2
避免不必要的\visible<...>
行,让它取决于你的参数范围。在我删除了你示例中的\visible<5>
和\visible<6>
行之后,空框就消失了。
代码(在问题更新之前)甚至可以减少,执行相同操作但没有空幻灯片:
\begin{tikzpicture}
\foreach \frm in {#1} {
\only<\frm>{
\node {FRAME \frm};
\visible<\frm>{\node at (4,0) {its \frm};}
}
}
\end{tikzpicture}
即使经过更新,您也可以使用\if
类似或\foreach
循环\visible
以及节点内容的变量。
如果只是为了防止跳跃,我会使用\overlayarea
。
答案3
我发现最好用 tex 来玩弄花招。这个方法很管用,因为它会包裹住整个东西。
% parameter documentation
% #1: current frame
% #2: displayed range minimum
% #3: displayed range maximum
% #4: object range minimum
% #5: object range maximum
% #6: object
\newcommand{\showPart}[6]{\ifnum#1<#4\relax\else\ifnum#5<#1\relax\else\visible<\ifnum#2<#4 #4\else#2\fi-\ifnum#3<#5 #3\else#5\fi>{#6}\fi\fi}
这使得动画命令看起来像这样:
\begin{tikzpicture}
\foreach \frm in {#1,...,#2} {
%\only<\frm>{ %%%%% IMPORTANT: remove this!
\node at (-4,\frm) {FRAME \frm}; %% all four shown all the time!
\showPart{\frm}{#1}{#2}{2}{4}{\node at (4,0) {it's 2-4};}
\showPart{\frm}{#1}{#2}{4}{5}{\node at (4,2) {it's 4-5};}
\showPart{\frm}{#1}{#2}{5}{5}{\node at (4,4) {it's 5};}
%}
}
\end{tikzpicture}