How to make a diagram composed of superimposed layers where the viewer can make each layer visible or invisible independently of the other layers?

This question led to a new package:
ocgx

(I have edited the question as ocgtools looks like it is the right package to use, rather than animate.)

I am trying to use LaTeX with the TikZ package to make a diagram composed of four layers. The specifications require that the viewer can make any of the layers present or absent, so each layer will need its own on/off switch.

The animate package gives one set of control buttons and is suited to an application where layers are to be added in a predetermined order. Early attempts at making my diagram tried to use one animateinline environment for each layer so that each would have it's own set of control buttons.

I tried a test case of two layers using two animateinline environments, each displays only a blank canvas or one layer, and each has its own set of control buttons. Various attempts were unsatisfactory, including

Attempt 1: Inside of a figure environment, nesting an animateinline environment inside another one. This caused a compilation warning that when ignored resulted in no output.

Attempt 2: Two separate animateinline environments inside of one figure environment - each set of radio buttons operates independently. To ensure that the second layer is superimposed on the first, using \vspace I manually shifted the second graphic to the same location on the page as the first. Unfortunately the second graphic completely covers the first with its white background, so it appears that the first set of radio buttons doesn't work just because the first layer can't be seen!

This attempt has various problems: it requires manual fiddling to superimpose the layers, needs the layers to be made transparent somehow, and even doing that would mean the control buttons are superimposed, so it's necessary to find a way of changing the location of one set of control buttons.

An answer posted now indicates that the ocgtools will give a framework that doesn't require manual fiddling, allows for transparent layers and which allows the diagram creator to place links that can make each individual layer visible or invisible. Once I have determined that the suggestion works for my needs, I will report back and make this question more concise.

Below is some code for the unsatisfactory attempt 2 made using animate. Uncommenting the vspace command shows the problem of the opaque second layer sitting on top of and obscuring the first layer.

\documentclass{article}
\usepackage{color,tikz,fancyvrb,animate}
\usetikzlibrary{matrix,fit,calc}
\begin{document}

% An experiment to get diagram layers that can be controlled individually, not just presented sequentially as I've done in "animate".
% I think this could be a passable solution if I could get the layers to be transparent rather than the top one blocking the bottom one.
\begin{figure}
\centering
% Sample_timeline determines the sequence in which frames are added
\begin{VerbatimOut}{Sample_timeline}
::0x0
::1x0
\end{VerbatimOut}

\begin{animateinline}[
step,controls,timeline=Sample_timeline,
begin={%
\begin{tikzpicture}%
\useasboundingbox (-0.5,-0.5) rectangle (6,5.5);%
},
end={\end{tikzpicture}}
]{1} %although not relavant (option step') fps is required argument

\draw[blue] (-0.5,-0.5) rectangle (4,4.5);

\newframe

\draw[blue] (0,0) circle(0.2) node (circcentre) {layer 1};
\end{animateinline}

% Having this command uncommented causes a problem as the second graphic covers the first - so it appears that the buttons for the first graphic don't work.
%   This destroys the illusion of two layers which can be turned on and off independently of each other. Maybe the problem can be
%     resolved if the "layers" can be made transparent.

%\vspace{-5.5cm}

% Sample_timeline2 determines the sequence in which frames are added
\begin{VerbatimOut}{Sample_timeline2}
::0x0
::1x0
\end{VerbatimOut}

\begin{animateinline}[
step,controls, timeline=Sample_timeline2,
begin={%
\begin{tikzpicture}%
\useasboundingbox (-0.5,-0.5) rectangle (6,5.5);%
},
end={\end{tikzpicture}}
]{1} %although not relavant (option step') fps is required argument

\draw[orange, line width=3pt] (-0.5,-0.5) rectangle (4,4.5);

\newframe

\node[draw,red] (reccentre)  at +(2,2){layer 2};
\end{animateinline}

\end{figure}
\end{document}

-
Study the microtype documentation source - it does layers. –  Martin Schröder Aug 1 '12 at 8:05

Last edit: With the invaluable assistance of Paul Isambert, I wrote the ocgx package.

Here is an example with ocgx package (available via CTAN and via TeXLive).

Three screenshots:

The code:

\documentclass{beamer}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{ocgx,calc}
\begin{document}

\tikzset{ocg button/.style={circle,minimum size=.5em,switch ocg with mark on={#1}{}}}

\begin{frame}
\frametitle{Title}

\begin{tikzpicture}[overlay,remember picture,ocg={name=Layer 1,ref=layer1}]
\begin{scope}[shift={(current page)}]
\end{scope}
\end{tikzpicture}
\begin{tikzpicture}[overlay,remember picture,ocg={name=Layer 2,ref=layer2}]
\begin{scope}[shift={(current page)}]
\end{scope}
\end{tikzpicture}
\begin{tikzpicture}[overlay,remember picture,ocg={name=Layer 3,ref=layer3}]
\begin{scope}[shift={(current page)}]
\end{scope}
\end{tikzpicture}

\begin{itemize}
\item Layer 1 \tikz\node[fill=red!50,ocg button=layer1]{};
\item Layer 2 \tikz\node[fill=blue!50,ocg button=layer2]{};
\item Layer 3 \tikz\node[fill=green!50,ocg button=layer3]{};
\end{itemize}
\end{frame}
\end{document}

-
thanks, this looks like what I want. For anyone else interested in this question, the link to CTAN provided gives a summary (edited by me) "The package ocgtools is designed to insert OGC (Optional Group Content, known as layers) into PDF presentations. ... the package allows to insert in an comfortable way any TeX material into separate layers in PDF document and also insert links which toggle these layers on and off. Parts of the PDF document like formatted text .. graphics can be turned to visible or invisible state by clicking active links or buttons." –  Jason Whyte Jul 29 '12 at 7:40
Thanks for the tip on AcroTeX. I have spent some time trying different options in ocgtools. Before I continue, do you know if you can superimpose one layer directly on top of another one? I can add layers but am having trouble making them transparent. –  Jason Whyte Jul 29 '12 at 10:50

Here is an animate based solution with links that act as switches:

\documentclass{article}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz}
\usepackage{animate}
\usepackage{hyperref}

\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% command to create toggle link to animation frame
\newcommand{\ShowHideFrame}[3]{%
% #1: anim No. (zero-based),
% #2: frame No. (zero-based),
\leavevmode%
/Border [\@pdfborder]%
/A <<
/S/JavaScript
/JS (
\if@anim@useocg%
if(a#1.fr[#2].state==true){
a#1.fr[#2].state=false;
}else{
a#1.fr[#2].state=true;
}
\else
if (a#1.fr[#2].display==display.visible){
a#1.fr[#2].display=display.hidden;
}else{
a#1.fr[#2].display=display.visible;
}
this.dirty=false; %reset document status to unchanged'
\fi
)
>>
}\strut{}#3%
}
% command to create link that goes to particular frame while hiding
% the others
\newcommand{\GoToFrame}[3]{%
% #1: anim No. (zero-based),
% #2: frame No. (zero-based),
\leavevmode%
/Border [\@pdfborder]%
/A <<
/S/JavaScript
/JS (
for (idx in a#1.fr) {
\if@anim@useocg
if(idx==#2){a#1.fr[idx].state=true;}else{a#1.fr[idx].state=false}
\else
if(idx==#2){a#1.fr[idx].display=display.visible;}else{a#1.fr[idx].display=display.hidden}
\fi
}
)
>>
}\strut{}#3%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatother

\begin{document}

\def\firstcircle{(0,0cm) circle (1.5cm)}
\def\secondcircle{(60:1.5cm) circle (1.5cm)}
\def\thirdcircle{(0:1.5cm) circle (1.5cm)}

\begin{center}
\begin{animateinline}[
step,
begin={
\begin{tikzpicture}
\useasboundingbox \firstcircle \secondcircle \thirdcircle;
},
end={\end{tikzpicture}}
]{1}
%empty 0th frame
\newframe
\fill[red,fill opacity=.5] \firstcircle;
\newframe
\fill[green,fill opacity=.5] \secondcircle;
\newframe
\fill[blue,fill opacity=.5] \thirdcircle;
\end{animateinline}

\GoToFrame{0}{0}{none} |
\ShowHideFrame{0}{1}{red} |
\ShowHideFrame{0}{2}{green} |
\ShowHideFrame{0}{3}{blue}
\end{center}

\end{document}
`
-
Very beautiful. –  Paul Gaborit Jul 30 '12 at 16:15
I think my initial question was too broad as it didn't take into account the final usage of the diagram! The beamer answer obviously suits a presentation whereas I suspect that the animate solution is better for an interactive figure in an ebook - I love the redefined buttons! I have asked the Meta forum about how best to separate the different aspects of my question. –  Jason Whyte Jul 31 '12 at 6:09
@JasonWhyte: There is no restriction on the usage of the above method. It suits both, article and presentation class documents. However, you will need the mouse for controlling layer visibility. Page-up and down buttons don't work neither here nor with the ocgtools based method, I guess. –  AlexG Jul 31 '12 at 7:05
Merci, @PolGab. –  AlexG Jul 31 '12 at 7:08
@AlexG maybe the language I used in my comment was too loose, no criticism of the animate-based solution was implied, in fact I'm very happy with it but am still evaluating options as the instructions I receive change. I'll refine my earlier comment to say that while the animate based solution is suitable for one of my purposes in an ebook (as well as in a presentation) the beamer based solution seems that it is ready-made for a presentation, rather than an amsbook documentclass or similar. –  Jason Whyte Jul 31 '12 at 14:26
show 1 more comment