有没有办法获取投影仪幻灯片上的文本位置?(我可以插入自动定位的聚光灯高亮吗?)

有没有办法获取投影仪幻灯片上的文本位置?(我可以插入自动定位的聚光灯高亮吗?)

这个问题源于我想直接在幻灯片上突出显示聚光灯的想法。我能够编写类似的代码。(这里还有另一种选择: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}

在此处输入图片描述 在此处输入图片描述 在此处输入图片描述 在此处输入图片描述 在此处输入图片描述 在此处输入图片描述

相关内容