TikZ-PGF – Overprint Environment Inside TikZ Node: Unexpected Alignment

beameroverlaystikz-pgf

I want to use an overprint environment inside a tikz-node.
I expect the content text of the overprint-sections to be aligned centrally, but it aligns right and even protrudes a little beyond the overprint/nodes border.

Minimal example output:
unexpected output

What am I missing and how can the issue be fixed?

Also I do not want the overprint to wobble, which it does a little bit, but I expect that will automatically be gone with a fix.

Minimal example code:

\documentclass[transparent]{beamer}
\usepackage[english]{babel}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
    \begin{frame}%
        \begin{center}
        \begin{tikzpicture}[every node/.style={draw}]
            \onslide<+->{\node(a){test1};}
            \onslide<+->{\node(b)[below=of a,align=center]{
                \begin{overprint}[4cm]
                    \onslide<+>
                        $a=b$
                    \onslide<+>
                        $b=c$
                    \onslide<+>
                        $c=d$
                \end{overprint}
            };}
            \node(c)[below=of b]{test2};
        \end{tikzpicture}
        \end{center}
    \end{frame}%
\end{document}

Best Answer

This is due to an unfortunate interaction between how overprint works and the center environment. Because the center environment is in force when overprint is figuring out which text to use, the text gains some extra horizontal space (to centre it). But when overprint sets the text, it modifies it in such a way that TeX adds yet more space to centre it again. Net result being that the text gets shoved too far over to the right. Thanks to David Carlisle and Herbert, I can offer two ways to "cancel" the effect. Both get rid of the centre effect when the overprint environment is doing its stuff.

Note that due to the way overprint works, to get the contents centred, you have to add in \centering to each piece. There's no other way to do that. I've assumed, in the below, that that is what you want to happen.

\documentclass[transparent]{beamer}
\usepackage[english]{babel}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{positioning}

\makeatletter
\def\normaljustify{%
  \let\\\@centercr
  \rightskip\z@skip
  \leftskip\z@skip%
  \parfillskip=0pt plus 1.0fil\relax
}
\makeatother


\begin{document}
    \begin{frame}%
        \begin{center}
        \begin{tikzpicture}[every node/.style={draw}]
            \onslide<+->{\node(a){Herbert's code};}
            \onslide<+->{\node(b)[below=of a,align=center]{%
\normaljustify
                \begin{overprint}[4cm]
                    \onslide<+>
    \centering
                        $a=b$
                    \onslide<+>
    \centering
                        $b=c$
                    \onslide<+>
    \centering
                        $c=d$
                \end{overprint}
            };}
            \node(c)[below=of b]{test2};
        \end{tikzpicture}

        \begin{tikzpicture}[every node/.style={draw}]
            \onslide<+->{\node(a){David Carlisle's code};}
            \onslide<+->{\node(b)[below=of a,align=center]{%
            \begin{minipage}{\textwidth}%
                \begin{overprint}[4cm]
                    \onslide<+>
    \centering
                        $a=b$
                    \onslide<+>
    \centering
                        $b=c$
                    \onslide<+>
    \centering
                        $c=d$
                \end{overprint}%
            \end{minipage}
            };}
            \node(c)[below=of b]{test2};
        \end{tikzpicture}

        \end{center}
    \end{frame}%
\end{document}

I'm not sure which of the two to prefer. One thing to note about David's method (with the additional minipage) is that if you put anything "normal" (such as bare text) inside that minipage then it will have width \textwidth which is not desirable.

overprint and centre sorted out