Introduction
A long time ago I started learning how to use TikZ and I created some not very well made diagrams. One of those diagrams is a state space representation of linear dynamical systems. When I discovered I could perform animations with TikZ I tried my best to animate that diagram as an explanation of one should think step by step to draw and to understand the diagram.
Recently I redesigned some old diagrams with new methods I learned and decided to create some animations, but I noticed I should also revise how to animate them, since they were different from the originals draws I made.
Question
And now comes the decision-making point. What would be the best method to animate these diagrams, creating step by step, in diagrams where I create the nodes and then the connections between them (MWE 2 below)? How to create such step by step animation after a already read TikZ diagram?
I know asking for "The Best " is a little bit subjective and opinion based, but in this case, it just lacks me information to decide how to proceed and it would take a long time to learn by trial and error which method is more suitable.
Criteria for "The Best".
- Less changes in the original TikZ drawn
- Allowing step by step of the diagram in (almost) any order
- Compiling fast (or not so long)
Background
I've seen some possibilities with uncover, multido, creating multiple pages pdf and using \animategraphics, but I don't know which one would fit the best my needs.
- uncover: Animate Line / Path using Tikz and 'animate' package
- multido: how to hold previous lines in \multiframe in \tikz?
- multiple pages pdf animation How to draw a cobweb graph like this one?
\animategraphics[<options>]{<frame rate>}{<file basename>}{<first>}{<last>}The animate Package
As fas as I've read, I guess uncover seems to better fill my criteria.
Original diagram and animation - MWE 1
This is the first method I created the animation. It is clumsy, I used \ifthenelse to define what is presented in ecah step, the code is long, I didn't know how to keep what have already been draw. It is a mess. (I don't even remember where I find the example I based this code).
MWE 1 follows:
\documentclass[border=5pt]{standalone}
\usepackage{amsmath,xifthen,tikz,animate}
\usetikzlibrary{calc}
\begin{document}
\begin{animateinline}[poster=last, controls]{1}
\multiframe{8}{ii=0+1}{% ii=0,1,...99 ; rj=9.9,9.8,...,0.0
\begin{tikzpicture}[very thick, every node/.style={font=\LARGE}];
\definecolor{dkg}{rgb}{0,0.5,0};
% ==========
\useasboundingbox (-6,-3) rectangle ++(20,8);
\node[blue, right] at (9.5,-0.5) {\Huge Step:\ii};
\draw (2.5,0) rectangle ++(2,2) coordinate(G) node[pos=0.5] {\Huge{$\int$}};
\node at (-1,-1.5) {
\begin{tabular}{l}
$\dot{x} = A x + B u$ \\
$y = C x + D u$
\end{tabular}
};
\ifthenelse{\ii < 1}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
}{
\ifthenelse{\ii < 2}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
}{
\ifthenelse{\ii < 3}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
\draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
\draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);
}{
\ifthenelse{\ii < 4}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
\draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
\draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);
\draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};
}{
\ifthenelse{\ii < 5}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
\draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
\draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);
\draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};
\draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
\draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
\draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);
}{
\ifthenelse{\ii < 6}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
\draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
\draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);
\draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};
\draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
\draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
\draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);
\draw (6.5,0) coordinate(C) rectangle ++(2*1,2*1) node[pos=0.5]{$C$};
\draw (10.5,1) coordinate(y) circle (1/2);
\draw [-latex, violet] (y)++(0.5,0) -- ++(1,0) node[above]{$y$};
\draw [-latex, olive] ($(C)+(2*1,1)$) -- ($(y)+(-0.5,0)$) node[above left]{$+$};
}{
\ifthenelse{\ii < 7}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
\draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
\draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);
\draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};
\draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
\draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
\draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);
\draw (6.5,0) coordinate(C) rectangle ++(2*1,2*1) node[pos=0.5]{$C$};
\draw (10.5,1) coordinate(y) circle (1/2);
\draw [-latex, violet] (y)++(0.5,0) -- ++(1,0) node[above]{$y$};
\draw [-latex, olive] ($(C)+(2*1,1)$) -- ($(y)+(-0.5,0)$) node[above left]{$+$};
\draw (2.5,2.5) coordinate(D) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$D$};
\draw [-latex, dkg] ($(u)+(0.5*1,0)$) |- ($(D)+(0,1)$);
\draw [-latex, cyan] ($(D)+(2*1,1)$) -| ($(y)+(0,0.5)$) node[above right]{$+$};
}{
\draw [-latex, teal] (G)++(0,-1) -- ++(1,0) coordinate(X) node[above]{$x$} -- ++(1,0);
\draw (1,1) coordinate(S) circle (1/2);
\draw [-latex, orange] (S)++(1/2,0) -- ++(1,0) coordinate(E) node[midway, above]{$\dot{x}$};
\draw (2.5,-2.5) coordinate(A) rectangle ++(2*1,2*1) node[pos=0.5]{$A$};
\draw [-latex, teal] (X) -- ++(0,-2.5) -- ++(-1,0);
\draw [-latex, cyan] ($(A)+(0,1)$) -| ($(S)+(0,-0.5)$) node[below right]{$+$};
\draw (-2.5,0) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$B$};
\draw [-latex, red] (B)++(0,-1) -- ++(1,0) node[above left]{$+$};
\draw [-latex, dkg] (-4,1) coordinate(u) node[above]{$u$} |- ++(1.5,0);
\draw (6.5,0) coordinate(C) rectangle ++(2*1,2*1) node[pos=0.5]{$C$};
\draw (10.5,1) coordinate(y) circle (1/2);
\draw [-latex, violet] (y)++(0.5,0) -- ++(1,0) node[above]{$y$};
\draw [-latex, olive] ($(C)+(2*1,1)$) -- ($(y)+(-0.5,0)$) node[above left]{$+$};
\draw (2.5,2.5) coordinate(D) rectangle ++(2*1,2*1) coordinate(B) node[pos=0.5]{$D$};
\draw [-latex, dkg] ($(u)+(0.5*1,0)$) |- ($(D)+(0,1)$);
\draw [-latex, cyan] ($(D)+(2*1,1)$) -| ($(y)+(0,0.5)$) node[above right]{$+$};
\draw [very thick, red] (-3,-3) coordinate(eq) rectangle ++(12,8);
}}}}}}}
\end{tikzpicture}
}
\end{animateinline}
\end{document}
The result is as follows.
New diagram to animated - MWE 2
This new diagram uses some personal local defined /.styles and is much better organized. Nodes are defined first and then connections are made. The code is clean, easy to change, much better than the older one. But I don't how the best way to animate it.
MWE 2 follows:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{addCross/.style n args={6}{
minimum size={#5 mm}, %minimum height=10mm,
path picture={
\draw[#6]
(path picture bounding box.south east) -- (path picture bounding box.north west)
(path picture bounding box.south west) -- (path picture bounding box.north east);
\node at ($(path picture bounding box.south)!0.4!(path picture bounding box.center)$) {#1};
\node at ($(path picture bounding box.west)!0.4!(path picture bounding box.center)$) {#2};
\node at ($(path picture bounding box.north)!0.4!(path picture bounding box.center)$) {#3};
\node at ($(path picture bounding box.east)!0.4!(path picture bounding box.center)$) {#4};
}
},
addCross/.default={}{}{}{}{10}{}
}
\tikzset{mySimpleArrow/.style n args={2}{
>={latex[#1]},
every path/.style={draw=#2}
},
mySimpleArrow/.default={black}{black}
}
\tikzset{myBlockOpacity/.style n args={4}{
every node/.style={rectangle,draw, text=black,
minimum width=#1, minimum height=#2,
fill opacity=#3, text opacity=#4}
},
myBlockOpacity/.default={1cm}{1cm}{0.4}{1}
}
\begin{document}
\begin{tikzpicture}[very thick]
\begin{scope}
\node[circle,draw,addCross={$+$}{$+$}{}{}{10}{black}] (N1) at (1,-0.5) {};
\end{scope}
\begin{scope}[shift={(3.0,-0.5)},myBlockOpacity]
\node[fill=red] (A) at (0,-1.5) {$A$};
\node[fill=green!50!black] (B) at (-4,0) {$B$};
\node[fill=yellow!75!black] (C) at (3,0) {$C$};
\node (I) at (0,0) {$\displaystyle \int$};
\end{scope}
\begin{scope}[mySimpleArrow={blue}{cyan}]
\path[->] (-2.5,-0.5) node[above]{$u$} -- (B);
\path[->] (B) -- (N1);
\path[->] (N1) -- (I) node[midway, above] {$\dot{x}$};
\path[->] (I) -- (4.5,-0.5) coordinate(x) node[above]{$x$} -- (C);
\path[->] (x) |- (A) -| (N1);
\path[->] (C) -- ++(1.5,0) node[above]{$y$};
\end{scope}
\end{tikzpicture}
\end{document}
which produces







on slide, etc. – Black Mild Apr 29 '22 at 06:20