5

The following code uncovers a Forest tree level-by-level in a Beamer frame. However, the shadows appear all at once rather than with their nodes. How can I adjust the code so that the shadows stay with the nodes casting them?

\documentclass{beamer}
\usepackage{forest}
\tikzset{% set up for transitions using tikz with beamer overlays - developed by Daniel (http://tex.stackexchange.com/a/55849/) and, in earlier form, by Matthew Leingang (http://tex.stackexchange.com/a/6155/) and modified for this use, I think by Qrrbrbirlbel (http://tex.stackexchange.com/a/112471/)
    invisible/.style={opacity=0,text opacity=0},
    visible on/.style={alt=#1{}{invisible}},
    alt/.code args={<#1>#2#3}{%
      \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
    },
}
\forestset{%
  visible with edge from/.style={% based on visible on, developed by Qrrbrbirlbel (http://tex.stackexchange.com/a/112471/)
    /tikz/visible on=<#1->,
    /tikz/every label/.append style={visible on=<#1->},
    edge={/tikz/visible on=<#1->},
  },
}
\usetikzlibrary{shadows}
\begin{document}

\begin{frame}
  \begin{forest}
    for tree={
      draw,
      fill=white,
      drop shadow,
    },
    before typesetting nodes={
      for tree={
        tempcounta/.option=level,
        tempcounta'+=1,
        visible with edge from/.register=tempcounta,
      }
    }
    [first slide
      [second slide[third slide][third slide]]
      [second slide]
    ]
  \end{forest}
\end{frame}

\end{document}

Here's the problem:

shadows without nodes

I thought I'd seen code for this, but I can't seem to find a duplicate. In particular, I hope that at least I've not asked this before!

  • 1
    cfr is asking a question?! ;) I took the liberty of adding a visualization -- hope that's ok. – Dr. Manuel Kuehner Mar 7 '17 at 19:54
  • 2
    Does this help? I managed to get the opposite invisible/.style={opacity=0,text opacity=0,drop shadow={opacity=0.8,fill=blue}},and comment the drop shadow in the frame (dropbox.com/s/42p9e420ljd9svx/dsds.gif?dl=0). – Dr. Manuel Kuehner Mar 7 '17 at 20:31
  • 1
    @Dr.ManuelKuehner Thanks. I meant to add an image but had to run for the bus. However, I've now edited. I thought it might be more useful having a picture of the problem rather than one of the only slide which looks fine :-). – cfr Mar 7 '17 at 22:49
  • Going to bed now. I don't understand what you mean with "picture of the problem" since I posted an animated gif. :) – Dr. Manuel Kuehner Mar 7 '17 at 22:51
  • 1
    @Dr.ManuelKuehner It is surely my fault for not understanding. – cfr Mar 9 '17 at 0:23
4

How about this: instead of dealing with \beamer@slideinframe, we trace the opacity of an object and apply that opacity to its shadow. Like the following

\def\tikzshadowopacityregister{1}
\tikzset{
  invisible/.append code={\def\tikzshadowopacityregister{0}},
  every shadow/.style={opacity=\tikzshadowopacityregister}
}

(Put this after \usetikzlibrary{shadows} otherwise every shadow will be erased.)

This strategy is more flexible in the following way: even if someday someone comes up with some \setbeamercovered which sets the opacity in some complicated way, we just need to smuggle the result by a global macro and apply it to the shadow.

PS

My approach above is pretty similar to @Dr. Manuel Kuehner. To save me from plagiarism scandal, here is an even more flexible version

\makeatletter
\def\tikzopacityregister{1}
\tikzset{
  opacity/.append code={
    \pgfmathsetmacro\tikzopacityregister{#1*\tikzopacityregister}
  },
  opacity aux/.code={ % this is the original definition of opacity
    \tikz@addoption{\pgfsetstrokeopacity{#1}\pgfsetfillopacity{#1}}
  },
  every shadow/.style={opacity aux=\tikzopacityregister}
}
3

This was suggested to me by the comments, in some round about way that I don't quite understand. That is, it doesn't actually seem related to the suggestion in the comments, which I don't understand and couldn't make work. But I thought of this right after trying to make that work, which suggests a non-trivial connection.

I don't like this solution because it requires an additional style be created for each drop-shadow-like-item and then applied separately from the application of the main overlay specification. This makes it error-prone and I'm good at errors.

However, it does, strictly speaking answer the specific question I asked, so perhaps it will inspire somebody to provide a more satisfactory approach.

\documentclass{beamer}
\usepackage{forest}
\tikzset{% set up for transitions using tikz with beamer overlays - developed by Daniel (http://tex.stackexchange.com/a/55849/) and, in earlier form, by Matthew Leingang (http://tex.stackexchange.com/a/6155/) and modified for this use, I think by Qrrbrbirlbel (http://tex.stackexchange.com/a/112471/)
    invisible/.style={opacity=0,text opacity=0},
    visible on/.style={alt=#1{}{invisible}},
    alt/.code args={<#1>#2#3}{%
      \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} % \pgfkeysalso doesn't change the path
    },
}
\forestset{%
  visible with edge from/.style={% based on visible on, developed by Qrrbrbirlbel (http://tex.stackexchange.com/a/112471/)
    /tikz/visible on=<#1->,
    /tikz/every label/.append style={visible on=<#1->},
    edge={/tikz/visible on=<#1->},
  },
  drop shadow visible from/.style={/tikz/alt=<#1->{drop shadow}{}},
}
\usetikzlibrary{shadows}
\begin{document}

\begin{frame}
  \begin{forest}
    for tree={
      draw,
      fill=white,
    },
    before typesetting nodes={
      for tree={
        tempcounta/.option=level,
        tempcounta'+=1,
        visible with edge from/.register=tempcounta,
        drop shadow visible from/.register=tempcounta,
      }
    }
    [first slide
      [second slide[third slide][third slide]]
      [second slide]
    ]
  \end{forest}
\end{frame}

\end{document}

shadows with nodes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.