尝试回答我在评论中提出的问题这个答案,我最终根据 Ulrike 的代码得到了下面的代码,但该代码使\balloon
宏可以感知覆盖。但是,当在列表之前使用时,此宏会引入虚假的垂直空间。你知道它从何而来吗?
更新
代码稍有改变,并添加了动画,以使虚假的垂直空间更加明显。
更新 2
事实上,为了避免在制作\balloon
叠加层时因重复而产生麻烦,列表必须具有不同的名称。为此,\the\beamer@slideinframe
在给定的框架内使用幻灯片编号 ( ) 就足够了,但在整个文档中还不够。添加框架编号 ( \insertframenumber
) 就可以了。
\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}
答案1
这里没有什么魔法:您\tikz[overlay]
在某些框架中插入 ,而在其他框架中不插入 。 A\tikz[overlay]
可能没有大小,但它仍然是一个框,并且像 一样,\mbox{}
它可以引入空格。这意味着重要的是要么\tikz[overlay]
在这样的框不会造成伤害的地方使用 。或者在所有框架中使用类似的框,例如使用 David an\mbox
或 eg \alt
而不是\only
的定义\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}
答案2
奇怪的是,我还没有完全追踪到 beamer 和 tikzmark 在这里到底在做什么,但是添加了 invisible什么东西在垂直模式下,无论\color
是\label
总是\tikzmark
很棘手,并且很难控制副作用。在所有情况下,解决方案都是在执行任何棘手操作之前先安全进入水平模式。
如果你
\mbox{\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}}%
然后列表就会出现在所有四张幻灯片的相同位置。空的 mbox 会形成一个虚假的段落,将内容向下移动一点,但由于它是一个固定点,并且在所有幻灯片上都相同,因此您可以在框后使用空白行和负 vspace(如果需要)。