3

This is a follow-up question of this one.

In the previous question, I asked how to create an interactive slide with two parts: one left-hand-side part and one right-hand-side part; typically concentrating on the left-hand-side part.

Now, I need help for the right-hand-side part. Consider, as an example:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows}
\tikzstyle{int}=[draw, fill=blue!20, minimum size=2em]
\tikzstyle{init} = [pin edge={to-,thin,black}]

    \begin{document}
    \begin{frame}
    \begin{minipage}{0.2\textwidth}
    \begin{enumerate}
    \item this is 1
    \item this is 2
    \end{enumerate}
    \end{minipage}
    \hfill
    \begin{minipage}{0.75\textwidth}
    \only<1> {

    \begin{tikzpicture}[node distance=2.5cm,auto,>=latex']
        \node [int, pin={[init]above:$v_0$}] (a) {$\frac{1}{s}$};
        \node (b) [left of=a,node distance=2cm, coordinate] {a};
        \node [int, pin={[init]above:$p_0$}] (c) [right of=a] {$\frac{1}{s}$};
        \node [coordinate] (end) [right of=c, node distance=2cm]{};
        \path[->] (b) edge node {$a$} (a);
        \path[->] (a) edge node {$v$} (c);
    \end{tikzpicture}}
    \only<2> {
    \begin{tikzpicture}[node distance=2.5cm,auto,>=latex']
        \node [int, pin={[init]above:$v_0$}] (a) {$\frac{1}{s}$};
        \node (b) [left of=a,node distance=2cm, coordinate] {a};
        \node [int, pin={[init]above:$p_0$}] (c) [right of=a] {$\frac{1}{s}$};
        \node [coordinate] (end) [right of=c, node distance=2cm]{};
        \path[->] (b) edge node {$a$} (a);
        \path[->] (a) edge node {$v$} (c);
        \draw[->] (c) edge node {$p$} (end) ;
    \end{tikzpicture}}
    \end{minipage}
    \end{frame}

    \end{document}

Disclaimer: image sources are shamelessly copied from here.

As you will obviously notice, excepting a small change in the second tikzpicture, the same code is copied. How can I avoid this? In the previous question, I solved this using two separate files and including the images. But aren't there some cute ways?

4

An option to avoid code duplication is to use the very useful visible on style defined in this answer to Mindmap tikzpicture in beamer (reveal step by step); also, take into account that paths in TikZ are overlay-aware so this might also help you avoid repeating code unnecessarily or using "external" overlay specifications:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning}

\tikzset{
  int/.style={
    draw, 
    fill=blue!20, 
    minimum size=2em
  },  
  init/.style={pin edge={to-,thin,black}}
}

\tikzset{
  % use option [visible on=<+->] to uncover parts of a tikzpicture
  invisible/.style={opacity=0},
  visible on/.style={alt=#1{}{invisible}},
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
  },
}

    \begin{document}
    \begin{frame}
    \begin{minipage}{0.2\textwidth}
    \begin{enumerate}
    \item this is 1
    \item this is 2
    \end{enumerate}
    \end{minipage}
    \hfill
    \begin{minipage}{0.75\textwidth}
    \begin{tikzpicture}[node distance=1.5cm,auto,>=latex']
        \node [int, pin={[init]above:$v_0$}] (a) {$\frac{1}{s}$};
        \node (b) [left = of a,coordinate] {a};
        \node [int, pin={[init]above:$p_0$}] (c) [right =of a] {$\frac{1}{s}$};
        \node [coordinate] (end) [right = of c]{};
        \path[->] (b) edge node {$a$} (a);
        \path[->] (a) edge node {$v$} (c);
        \draw[->,visible on=<2>] (c) edge node {$p$} (end) ;
    \end{tikzpicture}
    \end{minipage}
    \end{frame}

    \end{document}

enter image description here

The styles are also part of the aobs-tikz package.

I changed the original code to use \tikzset and the =of syntax (with the positioning library) instead of the problematic of= syntax.

Here's the code, combining the solutions to both questions:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,tikzmark}

\newcounter{tmp}
\newcommand<>\Highlight[1]{%
  \stepcounter{tmp}%
  \only#2{%
    \begin{tikzpicture}[remember picture,overlay]
      \fill[green!60!black,opacity=0.5] 
      ([xshift=-.2em,yshift=2ex]pic cs:start-\thetmp)
        rectangle  
      ([xshift=.2em,yshift=-1ex]pic cs:end-\thetmp);
    \end{tikzpicture}}%
  \tikzmark{start-\thetmp}#1\tikzmark{end-\thetmp}%
}

\tikzset{
  int/.style={
    draw, 
    fill=blue!20, 
    minimum size=2em
  },  
  init/.style={pin edge={to-,thin,black}}
}

\tikzset{
  % use option [visible on=<+->] to uncover parts of a tikzpicture
  invisible/.style={opacity=0},
  visible on/.style={alt=#1{}{invisible}},
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
  },
}

\begin{document}
\begin{frame}
\begin{minipage}{0.2\textwidth}
\begin{enumerate}
\item \Highlight<+>{this is 1}
\item \Highlight<+>{this is 2}
\end{enumerate}
\end{minipage}
\hfill
\begin{minipage}{0.75\textwidth}
\begin{tikzpicture}[node distance=1.5cm,auto,>=latex']
    \node [int, pin={[init]above:$v_0$}] (a) {$\frac{1}{s}$};
    \node (b) [left = of a,coordinate] {a};
    \node [int, pin={[init]above:$p_0$}] (c) [right =of a] {$\frac{1}{s}$};
    \node [coordinate] (end) [right = of c]{};
    \path[->] (b) edge node {$a$} (a);
    \path[->] (a) edge node {$v$} (c);
    \draw[->,visible on=<2>] (c) edge node {$p$} (end) ;
\end{tikzpicture}
\end{minipage}
\end{frame}

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.