Komplexe Tikz-Animation mit Beamer

Komplexe Tikz-Animation mit Beamer

Ich verwende Tikz, um mit Beamer eine Art Caesar-Chiffre-Animation zu erstellen.

Ich bekomme, was ich will, aber da ich mich mit Tikz nicht gut auskenne, ist das Ergebnis etwas seltsam, weil die Kompilierung sehr langsam ist. Das ist ein ziemlicher Nachteil, weil es in einem großen Dokument mit vielen Kompilierungen enorm langsamer wird.

Mein Code ist wie folgt (also ein kleines funktionierendes Beispiel)

\documentclass{beamer}
\usetheme{Berkeley}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{tikz}
\tikzset{
  invisible/.style={opacity=0},
  visible on/.style={alt={#1{}{invisible}}},
  alt/.code args={<#1>#2#3}{\alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} 
  },
}
\begin{document}
\begin{frame}
\centering
\begin{tikzpicture}[scale=0.3, every node/.style={scale=0.3}]
 \pgfmathsetmacro{\alphsize}{26}
 \pgfmathsetmacro{\ang}{360/\alphsize}
 \pgfmathsetmacro{\d}{3}
 \pgfmathsetmacro{\op}{98 + \ang/2 - 1.2}
 \pgfmathsetmacro{\e}{\ang + \ang*\d}
 \pgfmathsetmacro{\ep}{\op + \ang*\d}
 \foreach \x in {0,\ang,...,360} {\draw[gray] (\x:8em) -- (\x:12em);}
 \foreach \x [count=\xi] in {A,...,Z} {
  \node[rotate=\ang - \ang*\xi,visible on=<1>]  at (\op - \ang*\xi:11em)     {{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<2>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{T}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<3>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<4>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{L}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<5>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<6>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{P}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<7>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{H}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<8>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{O}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<9>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{N}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<10>] at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\e - \ang*\xi,visible on=<1>]  at (\ep - \ang*\xi:9em) {{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<2>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{W}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<3>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<4>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{O}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<5>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<6>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{S}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<7>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{K}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<8>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{R}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<9>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{Q}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<10>] at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
}
 \draw[thick] (0cm,0cm) circle(12em);
 \draw[gray] (0cm,0cm) circle(10em);
 \draw[thick] (0cm,0cm) circle(8em);
\end{tikzpicture} 

\bigskip

\centering
\begin{tikzpicture}[every node/.style={scale=0.6}]
  \draw[step=1em,gray,thin] (0em,0em) grid (9em,2em);
  \node at (0.5em,1.5em) {\textcolor<2> {green}T};
  \node at (1.5em,1.5em) {\textcolor<3> {green}E};
  \node at (2.5em,1.5em) {\textcolor<4> {green}L};
  \node at (3.5em,1.5em) {\textcolor<5> {green}E};
  \node at (4.5em,1.5em) {\textcolor<6> {green}P};
  \node at (5.5em,1.5em) {\textcolor<7> {green}H};
  \node at (6.5em,1.5em) {\textcolor<8> {green}O};
  \node at (7.5em,1.5em) {\textcolor<9> {green}N};
  \node at (8.5em,1.5em) {\textcolor<10>{green}E};
  \node[visible on=<2->]  at (0.5em,0.5em) {\textcolor<2> {red}W};
  \node[visible on=<3->]  at (1.5em,0.5em) {\textcolor<3> {red}H};
  \node[visible on=<4->]  at (2.5em,0.5em) {\textcolor<4> {red}O};
  \node[visible on=<5->]  at (3.5em,0.5em) {\textcolor<5> {red}H};
  \node[visible on=<6->]  at (4.5em,0.5em) {\textcolor<6> {red}S};
  \node[visible on=<7->]  at (5.5em,0.5em) {\textcolor<7> {red}K};
  \node[visible on=<8->]  at (6.5em,0.5em) {\textcolor<8> {red}R};
  \node[visible on=<9->]  at (7.5em,0.5em) {\textcolor<9> {red}Q};
  \node[visible on=<10->] at (8.5em,0.5em) {\textcolor<10>{red}H};
\end{tikzpicture}

\end{frame}
\end{document}

Die Frage ist: Gibt es einen intelligenteren Weg, um dasselbe Ergebnis wie oben zu erzielen, der schneller kompiliert wird?

Antwort1

Ich sehe keine größeren Probleme, die deinen Code deutlich verlangsamen könnten. Da das Neukompilieren einer großen Anzahl komplexer TikZ-Bilder sehr lästig sein kann, gibt es eine Bibliothek, externaldie TikZ zwingt, die Bilder zu speichern und, wenn möglich, wiederzuverwenden. Dies geschieht wie folgt.

\usetikzlibrary{external}
\tikzexternalize

Bearbeiten: Wie @brad in den Kommentaren vorschlägt, kann es von Vorteil sein, zu verwenden \tikzexternalize[prefix=tikz/], um einen Ordner für die temporären TikZ-Bilder festzulegen.

Da du die Beamer-Konstruktion verwendest \only, funktioniert das nicht wie erwartet, es wird nur das erste Bild gerendert. Es gibt allerdings einen "Hack":

Umhüllen Sie die gesamte tikzpictureUmgebung mit \only<m-M>demmminimalund Mist diemaximalFramenummer, auf die von \onlyBefehlen verwiesen wirdinnerhalbdas Tikzbild.

Da die [visible on=<m-M>]Option „äquivalent“ zum \onlyBefehl ist, können Sie diese auch so verwenden.

\only<1-10>{%
\begin{tikzpicture}
    \node[visible on=<1>] {};
    % ...
    \node[visible on=<10>] {};
\end{tikzpicture}
}

Ich habe dies für Ihren Code versucht und die zweite (und spätere) Kompilierungszeiten sindvieluntere.

SehenVerwenden Sie die externe Tikz-Funktion nur mit BeamerFür mehr Information.

Der vollständige Code:

\documentclass{beamer}
\usetheme{Berkeley}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{tikz}
\tikzset{
  invisible/.style={opacity=0},
  visible on/.style={alt={#1{}{invisible}}},
  alt/.code args={<#1>#2#3}{\alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} 
  },
}

\usetikzlibrary{external}
\tikzexternalize

\begin{document}
\begin{frame}
\centering
\only<1-10>{%
\begin{tikzpicture}[scale=0.3, every node/.style={scale=0.3}]
 \pgfmathsetmacro{\alphsize}{26}
 \pgfmathsetmacro{\ang}{360/\alphsize}
 \pgfmathsetmacro{\d}{3}
 \pgfmathsetmacro{\op}{98 + \ang/2 - 1.2}
 \pgfmathsetmacro{\e}{\ang + \ang*\d}
 \pgfmathsetmacro{\ep}{\op + \ang*\d}
 \foreach \x in {0,\ang,...,360} {\draw[gray] (\x:8em) -- (\x:12em);}
 \foreach \x [count=\xi] in {A,...,Z} {
  \node[rotate=\ang - \ang*\xi,visible on=<1>]  at (\op - \ang*\xi:11em)     {{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<2>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{T}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<3>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<4>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{L}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<5>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<6>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{P}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<7>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{H}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<8>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{O}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<9>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{N}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<10>] at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\e - \ang*\xi,visible on=<1>]  at (\ep - \ang*\xi:9em) {{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<2>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{W}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<3>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<4>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{O}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<5>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<6>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{S}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<7>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{K}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<8>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{R}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<9>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{Q}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<10>] at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
}
 \draw[thick] (0cm,0cm) circle(12em);
 \draw[gray] (0cm,0cm) circle(10em);
 \draw[thick] (0cm,0cm) circle(8em);
\end{tikzpicture} 
}
\bigskip

\centering
\only<1-10>{%
\begin{tikzpicture}[every node/.style={scale=0.6}]
  \draw[step=1em,gray,thin] (0em,0em) grid (9em,2em);
  \node at (0.5em,1.5em) {\textcolor<2> {green}T};
  \node at (1.5em,1.5em) {\textcolor<3> {green}E};
  \node at (2.5em,1.5em) {\textcolor<4> {green}L};
  \node at (3.5em,1.5em) {\textcolor<5> {green}E};
  \node at (4.5em,1.5em) {\textcolor<6> {green}P};
  \node at (5.5em,1.5em) {\textcolor<7> {green}H};
  \node at (6.5em,1.5em) {\textcolor<8> {green}O};
  \node at (7.5em,1.5em) {\textcolor<9> {green}N};
  \node at (8.5em,1.5em) {\textcolor<10>{green}E};
  \node[visible on=<2->]  at (0.5em,0.5em) {\textcolor<2> {red}W};
  \node[visible on=<3->]  at (1.5em,0.5em) {\textcolor<3> {red}H};
  \node[visible on=<4->]  at (2.5em,0.5em) {\textcolor<4> {red}O};
  \node[visible on=<5->]  at (3.5em,0.5em) {\textcolor<5> {red}H};
  \node[visible on=<6->]  at (4.5em,0.5em) {\textcolor<6> {red}S};
  \node[visible on=<7->]  at (5.5em,0.5em) {\textcolor<7> {red}K};
  \node[visible on=<8->]  at (6.5em,0.5em) {\textcolor<8> {red}R};
  \node[visible on=<9->]  at (7.5em,0.5em) {\textcolor<9> {red}Q};
  \node[visible on=<10->] at (8.5em,0.5em) {\textcolor<10>{red}H};
\end{tikzpicture}
}
\end{frame}
\end{document}

verwandte Informationen