这个问题源于我想直接在幻灯片上突出显示聚光灯的想法。我能够编写类似的代码。(这里还有另一种选择:beamer:使用聚光灯突出显示图像的一部分)但问题是这两种方法都对突出显示的位置进行了硬编码。
因此,我想知道是否有一种方法可以确定幻灯片上文本的位置(和大小),从而自动执行此突出显示过程。(即\spotlight{Highlights!}
在我的示例中编写一些类似于突出显示文本的内容。)
我的梦想是实现如下所示的盒子式亮点:
\documentclass[xcolor=dvipsnames]{beamer}
\usetheme{metropolis}
\metroset{block=fill}
\usepackage{tikz}
\begin{document}
% invclip from: https://tex.stackexchange.com/questions/12010/how-can-i-invert-a-clip-selection-within-tikz
\tikzset{invclip/.style={clip,insert path={{[reset cm]
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
}}}}
\begin{frame}{Example Slide}
%highlighting overlay
\begin{tikzpicture}[remember picture,overlay]
\begin{scope}
\begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
\path[invclip]
% TODO: automatically position, resize this ugly hardcoded box
(3,-4.95) -- (5.1,-4.95) -- (5.1,-4) -- (3,-4) -- (3,-4.95);
\end{pgfinterruptboundingbox}
\fill[black, opacity=0.5] (current page.south west) rectangle (current page.north east);
\end{scope}
\end{tikzpicture}
% Some (arbitrary) content of the slide.
Some text here.
\vspace{3em}
\hspace{17em} Other text here.
\vspace{3.2em}
\hspace{8em} Highlights!
\end{frame}
\end{document}
我不知道这有多现实,所以另一种选择是手动设置高光的半径,但仍自动确定它的位置。(即使代码是这样的Highli\spotlight{2}ghts!
。)
pgfinterruptboundingbox
将上面代码中的环境替换为:
\begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
\draw[draw=none, invclip]
% TODO: automatically reposition this hardcoded circle.
(4,-4.55) circle (1.6);
\end{pgfinterruptboundingbox}
答案1
我们可以简单地通过 tikzmark 检索文本的位置并通过 saveboxes 计算宽度/高度,如下所示:
\documentclass[xcolor=dvipsnames]{beamer}
\usetheme{metropolis}
\metroset{block=fill}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
% invclip from: https://tex.stackexchange.com/questions/12010/how-can-i-invert-a-clip-selection-within-tikz
\tikzset{invclip/.style={clip,insert path={{[reset cm]
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
}}}}
% placeholder for the name of saveboxes defined in the spotlight macro
\newcommand{\hilboxname}{somesecrethilboxname}
% placeholder for the name of marks defined in the spotlight macro
\newcommand{\hilboxmark}{somearbitraryhilboxmarkname}
% spotlight padding in pt
\newcommand{\hilboxpadding}{10}
% counter to dinamically adjust the saveboxname
\newcounter{hilboxcounter}
% macro to create a spotlight for the passed content
\newcommand{\spotlight}[1]{%
% create a savebox for the content
\expandafter\newsavebox\csname \hilboxname\roman{hilboxcounter}\endcsname%
\expandafter\savebox\csname \hilboxname\roman{hilboxcounter}\endcsname{#1}%
% mark position and use savebox
\tikzmark{\hilboxmark\roman{hilboxcounter}}\expandafter\usebox\csname \hilboxname\roman{hilboxcounter}\endcsname%
% create the spotlight
\begin{tikzpicture}[remember picture,overlay]
% shortcuts for the calculations below (width, height, depth of the box, padding for the spotlight)
\newcommand{\w}{\wd\csname \hilboxname\roman{hilboxcounter}\endcsname};
\newcommand{\h}{\ht\csname \hilboxname\roman{hilboxcounter}\endcsname};
\newcommand{\D}{\dp\csname \hilboxname\roman{hilboxcounter}\endcsname};
\newcommand{\p}{\hilboxpadding};
\begin{scope}
\begin{pgfinterruptboundingbox} % needed by the range definition of invclip
% draw a path around the text for the highlight
\path[invclip]
(pic cs:\hilboxmark\roman{hilboxcounter}) + (0,-\D-\p)
-- ++(\w+\p, -\D-\p)
-- ++(0, \h+\D+2*\p)
-- ++(-\w-2*\p, 0)
-- ++(0,-\h-\D-2*\p);
\end{pgfinterruptboundingbox}
% fill the rest of the slide greyish
\fill[black, opacity=0.5] (current page.south west) rectangle (current page.north east);
\end{scope}
\end{tikzpicture}%
\stepcounter{hilboxcounter}%
}
\begin{document}
\begin{frame}{Example Slide}
Some text here.
\vspace{3em}
\hspace{17em} Other text here.
\vspace{3.2em}
\hspace{8em} \spotlight{Highlights!}
\end{frame}
\end{document}
如果您更喜欢圆圈,则可以使用:
% define the radius of the circle to create
\pgfmathsetmacro{\r}{\p+max(\w,\h+\D))/2}
% draw a circle around the text
\draw[draw=none, invclip]
(pic cs:\hilboxmark\roman{hilboxcounter}) + (0.5*\w, 0.5*\h - 0.5*\D) circle (\r pt);
但是,以这种方式创建多个高光会使背景更加暗淡。因此我创建了一个包含更多选项的版本。
cspotlight
创建圆形聚光灯。
rspotlight
创建矩形聚光灯。
附加一个p
可让您增加填充大小。
附加一个d
可让您指定突出显示应出现在哪些幻灯片上。
这些命令仅在 中有效hframe
。其想法很简单,即 hframe 插入“变暗的 tikz 图片”。而聚光灯命令插入聚光灯。(而不是像以前一样创建多个这样的 tikzpictures。)
\documentclass[xcolor=dvipsnames]{beamer}
\usetheme{metropolis}
\metroset{block=fill}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usepackage{ifthen}
% invclip from: https://tex.stackexchange.com/questions/12010/how-can-i-invert-a-clip-selection-within-tikz
\tikzset{invclip/.style={clip,insert path={{[reset cm]
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
}}}}
% placeholder for the name of saveboxes defined in the spotlight macro
\newcommand{\hilboxname}{somesecrethilboxname}
% placeholder for the name of marks defined in the spotlight macro
\newcommand{\hilboxmark}{somearbitraryhilboxmarkname}
% standard spotlight padding in pt
\newcommand{\hilboxpadding}{10}
% counter to dinamically adjust the saveboxname
\newcounter{hilboxcounter}
% shortcut for hilboxcounter as number
\newcommand{\hc}{\arabic{hilboxcounter}}
% generalized spotlight macro
% #1 - mode
% #2 - content
% #3 - padding
% #4 - higlight range
\newcommand{\gspotlight}[4]{%
% create a savebox for the content
\expandafter\newsavebox\csname \hilboxname\hc\endcsname%
\expandafter\savebox\csname \hilboxname\hc\endcsname{#2}%
% mark position and use savebox
\tikzmark{\hilboxmark\hc}\expandafter\usebox\csname \hilboxname\hc\endcsname%
% save the spotlight info
\only<#4>{%
\ifthenelse{\equal{\highlightlist}{}}{%
\edef\highlightlist{#1/\hc/#3}%
}{%
\edef\highlightlist{\highlightlist,#1/\hc/#3}%
}%
}%
\stepcounter{hilboxcounter}%
}
\newcommand{\rspotlight}[1]{\rspotlightp{#1}{\hilboxpadding}}
\newcommand{\rspotlightp}[2]{\rspotlightpd{#1}{#2}{1-}}
\newcommand{\rspotlightd}[2]{\rspotlightpd{#1}{\hilboxpadding}{#2}}
\newcommand{\rspotlightpd}[3]{\gspotlight{creater}{#1}{#2}{#3}}
% add rectangular spotlight
% #1 - savebox number
% #2 - padding
\newcommand{\creater}[2]{
% shortcuts for the calculations below (width, height, depth of the box, padding for the spotlight)
\def\w{\wd\csname \hilboxname#1\endcsname}
\def\h{\ht\csname \hilboxname#1\endcsname}
\def\D{\dp\csname \hilboxname#1\endcsname}
\def\p{#2}
\path[invclip]
(pic cs:\hilboxmark#1) + (0,-\D-\p)
-- ++(\w+\p, -\D-\p)
-- ++(0, \h+\D+2*\p)
-- ++(-\w-2*\p, 0)
-- ++(0,-\h-\D-2*\p);
}
\newcommand{\cspotlight}[1]{\cspotlightp{#1}{\hilboxpadding}}
\newcommand{\cspotlightp}[2]{\cspotlightpd{#1}{#2}{1-}}
\newcommand{\cspotlightd}[2]{\cspotlightpd{#1}{\hilboxpadding}{#2}}
\newcommand{\cspotlightpd}[3]{\gspotlight{createc}{#1}{#2}{#3}}
% add circular spotlight
% #1 - savebox number
% #2 - padding
\newcommand{\createc}[2]{
% shortcuts for the calculations below (width, height, depth of the box, padding for the spotlight)
\def\w{\wd\csname \hilboxname#1\endcsname}
\def\h{\ht\csname \hilboxname#1\endcsname}
\def\D{\dp\csname \hilboxname#1\endcsname}
\def\p{#2}
% define the radius of the circle to create
\pgfmathsetmacro{\r}{\p+max(\w,\h+\D))/2}
% draw a circle around the text
\draw[draw=none, invclip]
(pic cs:\hilboxmark#1) + (0.5*\w, 0.5*\h - 0.5*\D) circle (\r pt);
}
% A new environment that assumes the slide should have some highlighted words
\newenvironment{hframe}[1]{%
% there may be a nicer way to generally append something to a frame, this idea is from:
% https://tex.stackexchange.com/questions/11708/run-macro-on-each-frame-in-beamer?rq=1
\begin{frame}[environment=hframe]\frametitle{#1}%
\def\highlightlist{}
}{%
\ifthenelse{\equal{\highlightlist}{}}{}{%
% create highlight overlay
\begin{tikzpicture}[remember picture,overlay]
\begin{scope}
\begin{pgfinterruptboundingbox}
\foreach \mode \number \padding in \highlightlist {
\csname \mode\endcsname{\number}{\padding}
}
\end{pgfinterruptboundingbox}
% fill the rest of the slide greyish
\fill[black, opacity=0.5] (current page.south west) rectangle (current page.north east);
\end{scope}
\end{tikzpicture}%
}%
\end{frame}%
}
\begin{document}
\begin{hframe}{Example Slide}
Some text here.
\vspace{3em}
\hspace{17em} \rspotlightd{FIRST HIGHLIGHT}{2-}
\vspace{3.2em}
\hspace{8em} \rspotlightd{Highlights!}{3}
\end{hframe}
\begin{hframe}{Example Slide}
Some text here.
\vspace{3em}
\hspace{17em} \cspotlightd{FIRST HIGHLIGHT}{2-}
\vspace{3.2em}
\hspace{8em} \cspotlightpd{Highlights!}{20}{3} % increase the radius for this one
\end{hframe}
\end{document}