[Tex/LaTex] How to loop through a list of tikzpicture within animateinline

animateforeachmacrostikz-pgf

I have the following code which uses animateinline and several tikzpicture for it's animation effects:

\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{ifthen}
\usepackage{animate}
\usetheme{Warsaw}
\usecolortheme{whale}

\def\layera{
  \path[cm={{0.8028232,-0.59621716,0.59621716,0.8028232,(0.0,0.0)}},draw=black,opacity=0.990,miter
    limit=4.00,line width=0.943pt,rounded corners=0.0000cm] (-99.8372,584.6912)
    rectangle (-30.7483,653.7801);
}

\def\layerb{
    \fill[blue!40] (0,0) circle (1);
}

\def\layerc{
    \fill[red!40] (0,0) circle (1);
}

\begin{document}
\begin{center}
\begin{frame}
\begin{animateinline}[loop,controls]{1}

\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
    \layera{}
\end{tikzpicture}

\newframe
\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
    \layerb{}
\end{tikzpicture}

\newframe
\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
    \layerc{}
\end{tikzpicture}

\newcommand{\makelayer}{
    \newframe
    \begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
        \layerc{}
    \end{tikzpicture}
}

%\makelayer{}

%\def\MyLayers{\layerb, \layerc}
%\foreach \mylayer in \MyLayers {
%    \newframe
%    \begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
%        \mylayer{}
%    \end{tikzpicture}
%}

\end{animateinline}
\end{frame}
\end{center}
\end{document}

As you can see, it has 3 layers (1 layer/frame): layera, layerb and layerc. The following file could be converted to pdf and the animation effects are correct: a square, then a blue circle, and a red circle.

However, when I try to use \newcommand makelayer, the output is not correct: just uncomment \makelayer{} and compile to pdf. The strange thing is layerb is not shown correctly, instead of layerc, which is inside \makelayer{}?

It must be something obvious for a trained eye; could someone kindly point out what is the correct way of using \newcommand in this case?

The second question is looping through all the tikzpictures, and I think it might be related to the above question. I have also have the code that's not working commented out, starting at: %\def\MyLayers{\layerb, \layerc}

Any help is much appreciated.

Edit1

@Harish's answer solved the first question.

To clarify my second question, which is how to loop through the contents of each tikzpicture using foreach or any other looping mechanism? I made some changes to the code to illustrate the question (the actual tex file may contain many more layers/tikzpicture ):

\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{ifthen}
\usepackage{animate}
\usetheme{Warsaw}
\usecolortheme{whale}

\newcommand\layera{%
\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
  \path[cm={{0.8028232,-0.59621716,0.59621716,0.8028232,(0.0,0.0)}},draw=black,opacity=0.990,miter
    limit=4.00,line width=0.943pt,rounded corners=0.0000cm] (-99.8372,584.6912)
    rectangle (-30.7483,653.7801);
  \end{tikzpicture}
}

\newcommand\layerb{%
    \fill[blue!40] (0,0) circle (1);
}

\newcommand\layerc{%
    \fill[red!40] (0,0) circle (1);
}

\begin{document}
\begin{center}
\begin{frame}
\begin{animateinline}[loop,controls]{1}
    \layera

\newcommand{\makemylayer}{%
    \newframe
    \begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
        \layerb
    \end{tikzpicture}

    \newframe
    \begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]   
        \layerc
    \end{tikzpicture}
}

\makemylayer

%\newcommand\MyLayers{\layerb, \layerc}
%\foreach \mylayer in \MyLayers {
%    \newframe
%    \begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
%        \mylayer{}
%    \end{tikzpicture}
%}


\end{animateinline}
\end{frame}
\end{center}
\end{document}

There are 3 layers (tikzpicture): layera, layerb, and layerc, and except for layera, I'd like to loop through the contents of each tikzpicture (layerb and layerc).

So when I comment out \makemylayer, uncomment the foreach block, when I try to compile, there's the following error message:

! Package animate Error: Contents of first frame must not have zero width.

Thanks for your help.

Edit2

I've tried other looping methods such as loop, forloop etc., but most of them deals with a counter or something like that; could someone kindly provide any advice on how to iterate through the above list of commands and make it work?

Thank you very much.

Best Answer

Your first problem will be solved by putting a % after \newcommand{\makelayer}{.

And I think I didn't get your second question properly. It can be done as shown in this modified code of yours.

\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{ifthen}
\usepackage{animate}
\usetheme{Warsaw}
\usecolortheme{whale}

\newcommand\layera{%
\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
  \path[cm={{0.8028232,-0.59621716,0.59621716,0.8028232,(0.0,0.0)}},draw=black,opacity=0.990,miter
    limit=4.00,line width=0.943pt,rounded corners=0.0000cm] (-99.8372,584.6912)
    rectangle (-30.7483,653.7801);
  \end{tikzpicture}
}

\newcommand\layerb{%
\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
    \fill[blue!40] (0,0) circle (1);
\end{tikzpicture}
}

\newcommand\layerc{%
\begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
    \fill[red!40] (0,0) circle (1);
\end{tikzpicture}
}

\begin{document}
\begin{center}
\begin{frame}
\begin{animateinline}[loop,controls]{1}
    \layera
\newframe
    \layerb
\newframe
    \layerc

\newcommand{\makelayer}{%
    \newframe
        \layerb
}

\makelayer

%\def\MyLayers{\layerb, \layerc}
%\foreach \mylayer in \MyLayers {
%    \newframe
%    \begin{tikzpicture}[y=0.20pt,x=0.20pt,yscale=-1, inner sep=0pt, outer sep=0pt]
%        \mylayer{}
%    \end{tikzpicture}
%}

%% Instead of above try this:

\newcommand{\makemylayer}{%
    \newframe
        \layera
    \newframe
        \layerc
    \newframe
         \layerb
}

\makemylayer

\end{animateinline}
\end{frame}
\end{center}
\end{document}

I have changed the order of appearance to make things clear.