将 TikZ 的标准覆盖规范从 only 替换为 onslide

将 TikZ 的标准覆盖规范从 only 替换为 onslide

在 中beamer,标准叠加规范似乎是onslide。在下面的代码中,\item<2->为所有幻灯片上的第二个项目保留空间。tikz然而,在 环境中,标准叠加规范是only,它不保留空间并导致这些“跳跃”或“舞动”幻灯片。有没有办法将标准叠加规范更改为,onslide以便幻灯片的其余部分不会在幻灯片 2 和 3 之间移动?

我知道我可以使用overlayarea高度足够大的,或者在幻灯片 1-2 上绘制一个不可见的矩形,但这需要手动操作,在创建讲座幻灯片的过程中,这些操作可能会累积起来,成本相当高昂。 选项overlay只有tikzpicture在幻灯片上没有其他内容时才会产生预期的效果。我可以使用\onslide<3->{\draw (0, 0) rectangle (-1, -1);},它具有预期的效果,但相当丑陋。 有没有办法更改\draw和其他 beamer 命令的默认行为,以便\draw<> ...产生\onslide<>{\draw ...}

\documentclass{beamer}
\usepackage{tikz}

\begin{document}

\begin{frame}
\begin{center}
\begin{tikzpicture}
\draw (0, 0) rectangle (1, 1);
\draw<3-> (0, 0) rectangle (-1, -1);
\end{tikzpicture}
\end{center}

\begin{itemize}
\item Some text
\item<2-> More text
\end{itemize}
\end{frame}

\end{document}

答案1

一个简单的解决方案是使用它\path来替换缺失的\draw功能。您也可以将其用于[opacity=0]节点甚至整个范围。

\documentclass{beamer}
\usepackage{tikz}

\begin{document}

\begin{frame}
\begin{center}
\begin{tikzpicture}
\draw (0, 0) rectangle (1, 1);
\draw<3-> (0, 0) rectangle (-1, -1);
\path (0, 0) rectangle (-1, -1);%***** added line *****
\end{tikzpicture}
\end{center}

\begin{itemize}
\item Some text
\item<2-> More text
\end{itemize}
\end{frame}

\end{document}

答案2

我找到了答案。发布此内容作为答案,希望其他人会发现它很有用。TikZ将每个开头的\draw和类似命令重置为,以防止用户意外覆盖它。这允许我们简单地重新定义中的和其他命令,检查是否存在覆盖规范,如果有,则使用 对其进行解析。我认为这个解决方案应该非常强大且非常快速。\path[draw]tikzpicture\drawevery picture/.code\futurelet\def

\documentclass{beamer}
\usepackage{tikz}

\makeatletter
\newcommand{\fixtikzpath}[1]{
    \expandafter\def\csname #1@standard@btkz\endcsname{\path[#1]}
    \expandafter\def\csname #1@gobble@btkz\endcsname<##1>##2;{
        \def\overlay@btkz{<##1>}
        \expandafter\onslide\overlay@btkz{\path[#1] ##2;}
    }
    \expandafter\def\csname #1@check@btkz\endcsname{
        \ifx\next@btkz<
            \expandafter\expandafter\csname #1@gobble@btkz\endcsname
        \else
            \expandafter\expandafter\csname #1@standard@btkz\endcsname
        \fi
    }
    \expandafter\def\csname #1\endcsname{\expandafter\futurelet\expandafter\next@btkz\csname #1@check@btkz\endcsname}
}
\newcommand{\fixtikznode}{
    \def\node@standard@btkz{\tikz@path@overlay{node}}
    \def\node@gobble@btkz<##1>##2;{
        \def\overlay@btkz{<##1>}
        \expandafter\onslide\overlay@btkz{\tikz@path@overlay{node} ##2;}
    }
    \def\node@check@btkz{
        \ifx\next@btkz<
            \expandafter\node@gobble@btkz
        \else
            \expandafter\node@standard@btkz
        \fi
    }
    \def\node{\futurelet\next@btkz\node@check@btkz}
}
\tikzset{every picture/.code={
    \fixtikzpath{draw}
    \fixtikzpath{fill}
    \fixtikzpath{clip}
    \fixtikznode
}}
\makeatother

\begin{document}
\begin{frame}
\begin{center}
\begin{tikzpicture}
\draw (0, 0) rectangle (1, 1);
\draw<2-> (0, 0) rectangle (1.2, -1.2);
\fill<3-> (0, 0) rectangle (-1.4, -1.4);
\node<4-> at (-1.4, 1.4) {It works};
\end{tikzpicture}
\end{center}
\end{frame}
\end{document}

在此处输入图片描述在此处输入图片描述 在此处输入图片描述在此处输入图片描述

相关内容