
Tentando responder a mim mesmo uma pergunta feita em meu comentário paraesta resposta, acabei com o código abaixo baseado no de Ulrike, mas que torna a \balloon
sobreposição de macro consciente. Mas, quando usada antes das listagens, esta macro introduz um espaço vertical espúrio. Você vê de onde isso pode vir?
Atualizar
O código foi ligeiramente alterado e uma animação foi adicionada para tornar o espaço vertical espúrio mais perceptível.
Atualização 2
Na verdade, para evitar problemas por duplicatas na \balloon
conscientização das sobreposições, é necessário que as listagens tenham nomes distintos. Usar para isso os números dos slides ( \the\beamer@slideinframe
) é suficiente dentro de um determinado quadro, mas não é suficiente para todo o documento. Adicionar os números dos quadros ( \insertframenumber
) resolve.
\documentclass{beamer}
%
\setbeamertemplate{footline}[page number]
%
\usepackage{listings}
\usepackage[foreground]{pagegrid}
\usepackage{tikz}
\usetikzlibrary{tikzmark,fit,calc}
\usetikzmarklibrary{listings}
\lstset{basicstyle=\ttfamily}
\tikzset{%
balloon/.style={%
draw,%
fill=blue!20,%
opacity=0.4,%
inner sep=4pt,%
rounded corners=2pt%
},%
}
%
\makeatletter
\renewcommand\iftikzmark[3]{%
\@ifundefined{save@pt@#1-\the\beamer@slideinframe}{%
#3%
}{%
#2%
}%
}%
\newcommand{\@balloon}[4]{%
\pgfmathtruncatemacro\@firstline{%
#3-1%
}%
\iftikzmark{line-#2-\@firstline-start}{%
\iftikzmark{line-#2-#3-first}{%
\xdef\@blines{%
($ ({pic cs:line-#2-\@firstline-start} -| {pic
cs:line-#2-#3-first})!.5!({pic cs:line-#2-#3-first}) $)%
}%
}{%
\iftikzmark{line-#2-#3-start}{%
\xdef\@blines{%
({pic cs:line-#2-\@firstline-start} -| {pic cs:line-#2-#3-start})%
}%
}{%
\xdef\@blines{(pic cs:line-#2-\@firstline-start)}%
}%
}%
}{%
\xdef\@blines{}%
}%
\foreach \k in {#3,...,#4} {%
\iftikzmark{line-#2-\k-first}{%
\xdef\@blines{%
\@blines (pic cs:line-#2-\k-first)%
}%
}{}%
\iftikzmark{line-#2-\k-end}{%
\xdef\@blines{%
\@blines (pic cs:line-#2-\k-end)%
}%
}{}%
}%
\ifx\@blines\empty%
\else%
\edef\temp{\noexpand\tikz[remember picture,overlay]%
\noexpand\node[fit={\@blines},balloon] (#1) {};}%
\temp%
\fi%
}
%
\newcommand<>{\balloon}[4][code\insertframenumber\the\beamer@slideinframe]{%
\only#5{\@balloon{#2}{#1}{#3}{#4}}%
}
%
\lstnewenvironment{hllisting}[1][]{%
\lstset{name=code\insertframenumber\the\beamer@slideinframe,#1}%
}{%
\lstset{name=}%
}
\makeatother
%
\begin{document}
\begin{frame}[fragile]
\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}%
\begin{hllisting}
1st line of code
2nd line of code
3rd line of code
4th line of code
5th line of code
6th line of code
\end{hllisting}
\end{frame}
\end{document}
Responder1
Não há mágica aqui: você está inserindo um \tikz[overlay]
em alguns quadros e não em outros. A \tikz[overlay]
pode não ter tamanho, mas é, no entanto, uma caixa e, tal como uma, \mbox{}
pode introduzir espaços. Isso significa que é importante usar a caixa \tikz[overlay]
em locais onde essa caixa não faça mal. Ou usar uma caixa semelhante em todos os quadros, por exemplo, usando como sugerido por David an \mbox
ou, por exemplo, \alt
em vez de \only
na definição de \balloon
:
\documentclass{beamer}
%
\setbeamertemplate{footline}[page number]
%
\usepackage{listings}
\usepackage[foreground]{pagegrid}
\usepackage{tikz}
\usetikzlibrary{tikzmark,fit,calc}
\usetikzmarklibrary{listings}
\lstset{basicstyle=\ttfamily}
\tikzset{%
balloon/.style={%
draw,%
fill=blue!20,%
opacity=0.4,%
inner sep=4pt,%
rounded corners=2pt%
},%
}
%
\makeatletter
\renewcommand\iftikzmark[3]{%
\@ifundefined{save@pt@#1-\the\beamer@slideinframe}{%
#3%
}{%
#2%
}%
}%
\newcommand{\@balloon}[4]{%
\pgfmathtruncatemacro\@firstline{%
#3-1%
}%
\iftikzmark{line-#2-\@firstline-start}{%
\iftikzmark{line-#2-#3-first}{%
\xdef\@blines{%
($ ({pic cs:line-#2-\@firstline-start} -| {pic
cs:line-#2-#3-first})!.5!({pic cs:line-#2-#3-first}) $)%
}%
}{%
\iftikzmark{line-#2-#3-start}{%
\xdef\@blines{%
({pic cs:line-#2-\@firstline-start} -| {pic cs:line-#2-#3-start})%
}%
}{%
\xdef\@blines{(pic cs:line-#2-\@firstline-start)}%
}%
}%
}{%
\xdef\@blines{}%
}%
\foreach \k in {#3,...,#4} {%
\iftikzmark{line-#2-\k-first}{%
\xdef\@blines{%
\@blines (pic cs:line-#2-\k-first)%
}%
}{}%
\iftikzmark{line-#2-\k-end}{%
\xdef\@blines{%
\@blines (pic cs:line-#2-\k-end)%
}%
}{}%
}%
\ifx\@blines\empty%
\else%
\edef\temp{\noexpand\tikz[remember picture,overlay]%
\noexpand\node[fit={\@blines},balloon] (#1) {};}%
\temp%
\fi%
}
%
\newcommand<>{\balloon}[4][code\the\beamer@slideinframe]{%
\alt#5{\@balloon{#2}{#1}{#3}{#4}}{\tikz[overlay,remember picture]\path (0,0);}%
}
%
\lstnewenvironment{hllisting}[1][]{%
\lstset{name=code\the\beamer@slideinframe,#1}%
}{%
\lstset{name=}%
}
\makeatother
%
\begin{document}
\begin{frame}
\tikz[overlay]\node{a};
blblb
\end{frame}
\begin{frame}
blblb
\end{frame}
\begin{frame}[fragile]
\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}%
\begin{hllisting}
1st line of code
2nd line of code
3rd line of code
4th line of code
5th line of code
6th line of code
\end{hllisting}
\end{frame}
\end{document}
Responder2
Estranhamente, não rastreei exatamente o que o beamer e o tikzmark estão fazendo aqui, mas adicionando invisívelo que éno modo vertical, seja \color
ou \label
seja \tikzmark
sempre complicado e com efeitos colaterais difíceis de controlar. A solução em todos os casos é entrar com segurança no modo horizontal antes de fazer qualquer coisa complicada.
Se você fizer
\mbox{\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}}%
então a listagem aparece na mesma posição em todos os quatro slides. A mbox vazia forma um parágrafo espúrio que move um pouco as coisas para baixo, mas como é um ponto fixo e igual em todos os slides, você pode usar uma linha em branco e um vspace negativo após a caixa, se necessário.