1

I'd like to make a node whose text content changes between overlays. Of course, the different contents have different sizes, so the node itself changes size between overlays. I'd like to avoid that by allocating the maximum needed size.

Here's some code to demonstrate what I'd like. Because the Bar text caption's size changes, the whole picture jumps around. First, I try using \only for the overlays, but that means only the current one takes up space. Then, I try using \visible, but then all of them always take up space.

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}{Try 1}

\begin{center} \begin{tikzpicture} \draw (0,0) node[draw]{Foo}; \draw (1,0) node[right]{Bar{\only<2>{short}}{\only<3>{much much longer}}}; \end{tikzpicture} \end{center} \end{frame}

\begin{frame}{Try 2}

\begin{center} \begin{tikzpicture} \draw (0,0) node[draw]{Foo}; \draw (1,0) node[right]{Bar{\visible<2-3>{\visible<2>{short}}{\visible<3>{much much longer}}}}; \end{tikzpicture} \end{center} \end{frame} \end{document}

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

Cactus
  • 1,107
  • 2
    Do you know the text of the longest version beforehand? Then you could just add text width=width("<longest text>") to that node. (Or just use a length that's wide enough.) Similar things can be done with minimum width. Or Q107227. – Qrrbrbirlbel Oct 08 '22 at 09:56
  • @Qrrbrbirlbel: can you post a complete example of using that approach? I tried \draw (1,0) node[right,text width=width("Barmuch much longer")]{Bar{\only<2>{short}}{\only<3>{much much longer}}}; but it still jumps around (although only very slightly) – Cactus Oct 08 '22 at 10:42
  • @Qrrbrbirlbel no wait, that can be worked around by adding a \strut to the always-displayed portion (i.e. Bar\strut). – Cactus Oct 08 '22 at 10:43

2 Answers2

2

If you know the longest text beforehand (and are willing to specify it in the document) you can just add the option

text width=width("Barmuch much longer")

to the node.

As you've noticed, this will still “jump around” (vertically at least) since the last one has that g that has a descender (a depth in TeX language).

Since you implicitly specify with right that the node should use its west anchor it will be vertically aligned at the center of the text box.

You will either anchor your nodes via the base or the mid anchors west mid, mid, east mid, base west, base, base east or text or also specify the text depth and the text height for your nodes, too.

Adding a \strut (which also can be added automatically to your nodes via font=\strut) extends the text box vertically enough so that normal text does not protrude.

But you can also use text depth and text height again:

\tikzset{
  max text/.style={
    text width ={width("#1")},
    text height={height("#1")},
    text depth ={depth("#1")}},
}

with

node[max text=Barshourtmuch much longer]

At the end, it comes down to what your diagram needs, how you place the nodes, if you draw their border and whether you connect lines to them.


Adding a \strut is similar to doing

text depth=.3\baselineskip,
text height=.7\baselineskip,

although \strut will allow the text box to grow vertically while text depth and text height will result in fixed sizes.

Qrrbrbirlbel
  • 119,821
0

You could split your node into two nodes and have the long node occupy space on all slides by making it invisible:

\documentclass{beamer}
\usepackage{tikz}

\usetikzlibrary{overlay-beamer-styles}

\begin{document} \begin{frame}{Try 1}

\begin{center} \begin{tikzpicture} \node[draw] (0,0) {Foo}; \node[right,visible on=<3>] at (1,0) {\strut Barmuch much longer}; \node[right,visible on=<-2>] at (1,0) {\strut Bar\only<2>{short}};
\end{tikzpicture} \end{center} \end{frame}

\end{document}

enter image description here