如何在特定幻灯片上将样式应用于现有tikz节点

时间:2010-06-05 04:47:51

标签: latex beamer tikz

这就是我要做的事情

    \begin{tikzpicture}
    [node distance = 1cm, auto,font=\footnotesize,
    % STYLES
    every node/.style={node distance=1.3cm},
    comment/.style={rectangle, inner sep= 5pt, text width=4cm, node distance=0.25cm, font=},
    module/.style={rectangle, drop shadow, draw, fill=black!10, inner sep=5pt, text width=3cm, text badly centered, minimum height=0.8cm, font=\bfseries\footnotesize\sffamily,rounded corners},
    selected/.style={fill=red!40}]

    \node [module] (nodeA) {node A};
    \node [module, below of=nodeA] (nodeA) {node B};

    \only<1>{
      \node [comment, text width=6cm, right=0.25 of nodeA] {short description of Node A};
      \node [comment, text width=6cm, right=0.25 of nodeB] {short description of Node B};
     }

    \only<2>{
      \node [selected] (nodeA) {};
      \node [comment, text width=6cm, right=0.25 of nodeA] {long description of node A};
    }
    \only<3>{
      \node [selected] (nodeB) {};
      \node [comment, text width=6cm, right=0.25 of nodeA] {long description of node B};
    }
    \end{tikzpicture}

问题是

      \node [selected] (nodeB) {};

创建一个新节点,但我希望它为现有节点应用样式。有没有办法这样做?

当然,我可以拥有处于选定状态和未选择状态的每个节点的副本,但我真的希望有一个正常的解决方案。

4 个答案:

答案 0 :(得分:4)

我认为你不能按照你想要的方式做到这一点(假设我正确理解了这个问题),因为一旦绘制了一个节点,就无法改变它的外观。我建议使用Beamer的\alt宏:

\alt<2>{\node[module,selected] at (nodeA) {node A};}{\node[module] at (nodeA) {node A};}
\alt<3>{\node[module,selected] at (nodeB) {node B};}{\node[module] at (nodeB) {node B};}
\node[comment,text width=6cm,right=0.25 of nodeA]{\alt<2>{short description}{long description}};
\node[comment,text width=6cm,right=0.25 of nodeB]{\alt<3>{short description}{long description}};

或类似的东西(你可能不得不修补分号以使其工作,我现在无法测试它。)

另一种选择是实际上只绘制一个新节点。如果你包括

\node[module,selected] at (nodeA) {node A};

\only<2>内部,它将在节点A的相同位置绘制一个看起来像节点A的节点,但红色背景除外。新节点将覆盖原始节点A.

答案 1 :(得分:1)

有时,为了避免重复,做这样的事情可能会很好:

% #1    Overlay specs.
% #2    Style name.
% #4    Style properties.
\def\onlystyle<#1>#2#3{%
    \alt<#1>{%
        \tikzset{#2/.style = {#3}}
    }{%
        \tikzset{#2/.style = {}}
    }%
}

然后,如果你把它放在一个框架内:

\onlystyle<2>{selected}{fill = red}

样式selected将在动画的第二张幻灯片上定义为fill = red,并且在每张其他幻灯片上都没有任何效果。然后,您可以编写一个可读的数字,例如:

\begin{tikzpicture}
    \node           at (0, 0) {A};
    \node[selected] at (1, 0) {B};
    \node           at (2, 0) {C};
\end{tikzpicture}

和“B”节点将在第二张幻灯片上突出显示。这样,您就不必复制粘贴大量的节点定义。 当然,它不能应用于每一个动画需要,但我喜欢保持这种技术。

答案 2 :(得分:1)

我找到了又一个解决方案,与所有以前的解决方案(包括我之前发布的解决方案)相比,它具有优势(更多功能!)。

首先,我提到改进的解决方案,然后解释为什么它实际上比所有其他解决方案都显示更多的功能。

以下从How can I make Beamer overlays with TikZ node attributes?改编的解决方案,使用了一个附加的tikz库,并为与幻灯片编号相关的属性(当然是幻灯片编号)使用了一个参数。请注意,现在必须在框架外进行tikz设置。

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles}
\begin{document}

\begin{frame}{With code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  [every node/.style={draw,circle},
   redStyle/.style={fill=red},
   blueStyle/.style={fill=blue}]
   
  \node<1> [] (A) {A};          % no style
  \node<2> [redStyle]  (A) {A}; % red style
  \node<3> [blueStyle] (A) {A}; % blue style

  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}


\tikzset{
  every node/.style={draw,circle},
  redStyle/.style={fill=red},     redStyle on/.style={alt=#1{redStyle}{}},
  blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  \node [redStyle on=<2>,blueStyle on=<3>] (A) {A};   
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}


\tikzset{
  every node/.style={draw,circle},
  redStyle/.style={fill=red},     redStyle on/.style={alt=#1{redStyle}{}},
  blueStyle/.style={fill=blue}, blueStyle on/.style={alt=#1{blueStyle}{}}}
\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
  \begin{tikzpicture}
  \node [redStyle on=<+(1)>,blueStyle on=<+(1)>] (A) {A};   
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\end{document}

现在解释一下为什么该解决方案是迄今为止最佳提及的内容,即它具有哪些附加功能以及它们为何相关(或何时使用)。好吧,仅仅因为相应的属性不必针对同一帧内的不同用途在相同的幻灯片号上显示。简单的例子:

假设您有一棵简单的树,即带有定向边的节点将它们连接起来。假设您要在特定幻灯片中将某些边缘加粗。当然,您有多个边缘,因此很明显它们不会同时变大胆!一些边缘在帧编号m到n处变为粗体,其他边缘在x和y处变为粗体。现在,可以使用节点(或边,在这种情况下)属性timedBold on=<m-n>timedBold on=<x,y>来轻松实现这一点。

答案 3 :(得分:0)

请注意,还有另一种可能性,在我看来,这比前两个建议要好一些,因为它具有较少的代码重复(与David Z的解决方案相比),并且(与Alice M.的解决方案相比)您不需要定义必须在框架外部定义的新命令(尽管定义此附加命令可能对任何人都不是问题)。原则上,以下建议似乎与Alice M的建议密切相关。

无论如何,解决方案是直接使用How to modify a node in TikZ when using beamer's overlays

基本上只是根据帧号重新定义样式。请参见以下最小示例,第二或第三帧。 (我重新整理了最小示例,因为我认为给定的极端非常复杂;它当然不是 minimum 的示例,也不能单独运行。)

\documentclass{beamer}
\usepackage{tikz}
\begin{document}

\begin{frame}{With code/node duplication (explicit frame numbers)}
  \begin{tikzpicture}
  [every node/.style={draw,circle},
   redStyle/.style={fill=red},
   blueStyle/.style={fill=blue}]
   
  \node<1> [] (A) {A};          % no style
  \node<2> [redStyle]  (A) {A}; % red style
  \node<3> [blueStyle] (A) {A}; % blue style

  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\begin{frame}{\textbf{Without} code/node duplication (explicit frame numbers)}
  \only<1>{\tikzset{colorStyle/.style={}}}          % no style
  \only<2>{\tikzset{colorStyle/.style={fill=red}}}  % red style
  \only<3>{\tikzset{colorStyle/.style={fill=blue}}} % blue style

  \begin{tikzpicture}
  [every node/.style={draw,circle}]
    
  \node [colorStyle] (A) {A}; % frame-dependent style
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\begin{frame}{\textbf{Without} code/node duplication (relative frame numbers)}
  \only<+>{\tikzset{colorStyle/.style={}}}          % no style
  \only<+>{\tikzset{colorStyle/.style={fill=red}}}  % red style
  \only<+>{\tikzset{colorStyle/.style={fill=blue}}} % blue style

  \begin{tikzpicture}
  [every node/.style={draw,circle}]
    
  \node [colorStyle] (A) {A}; % frame-dependent style
  \node [right of=A] (B) {B};
  \draw [-latex] (A) -- (B) ;
  \end{tikzpicture}
\end{frame}

\end{document}