如何在beamer的一帧中,水平居中放置n个相似的内容?

发布于 2025-05-11 17:43:36

需求效果:

A

需求表述:

当当前帧需要展示一些相似的内容(暂以node为例),在水平方向上:

  1. 如果只有1个内容,那么它需要被放置在版心宽度二等分的位置上;
  2. 如果有2个相似内容,那么它们需要被放置在版心宽度三等分的位置上;
  3. 如果有3个相似内容,那么它们需要被放置在版心宽度四等分的位置上;
  4. 如果有4个相似内容,那么它们需要被放置在版心宽度五等分的位置上...

请问,如何简化代码,使得可以方便地指定被放置的内容的数量、位置和内容?

% pdflatex 编译两次
\documentclass[draft]{beamer} 
\usepackage{tikz}    
%\usepackage{showframe}
\begin{document} 
\begin{frame}
\centering%
\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
    \node at (.5\linewidth,0) {A};
}

\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
    \node at (.33\linewidth,0) {A};
    \node at (.66\linewidth,0) {B};
}

\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
    \node at (.25\linewidth,0) {A};
    \node at ( .5\linewidth,0) {B};
    \node at (.75\linewidth,0) {C};
}

\tikz[every node/.style={draw,dotted,inner sep=1cm}]{
    \node at (.2\linewidth,0) {A};
    \node at (.4\linewidth,0) {B};
    \node at (.6\linewidth,0) {C};
    \node at (.8\linewidth,0) {D};%...
}
\end{frame}
\end{document} 

查看更多

关注者
0
被浏览
203
2 个回答
Eureka
Eureka 2天前
这家伙很懒,什么也没写!

无非就是堆盒子嘛,不需要用 tikz 这种大杀器的, 也不需要用 l3coffin 之类的东西,虽然用这两个更加的简单. 代码如下:

\documentclass{article}
\usepackage[showframe, textwidth=18cm]{geometry}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{lipsum}
\ExplSyntaxOn\makeatletter
\cs_set_protected:Npn \__item_align:nnn #1#2#3
  {% #1:cmd, #2:width, #3:object
    \hb@xt@#2{
      \tl_map_inline:nn {#3} 
        {
          \seq_put_right:No \l_tmpa_seq {\exp_not:N #1{##1}}
        } 
      \edef\seq@count{\seq_count:N \l_tmpa_seq}
      \seq_map_inline:Nn \l_tmpa_seq
        {
          \edef\item@width{\dim_eval:n {#2/(\seq@count+1)}}
          \hskip\item@width\clap{##1}
        }\hskip\item@width\hss
    }
  }
\NewDocumentCommand\itemAlign{O{}mm}
    {
        \__item_align:nnn {#1}{#2}{#3}
    }
\makeatother\ExplSyntaxOff
\parindent0pt

\begin{document}
\itemAlign{\linewidth}{A}\par
\itemAlign{\linewidth}{AA}\par
\itemAlign{\linewidth}{{(A)}{(A)}{(A)}}\par

\vskip6em
\dotfill\par
\def\imageA{\includegraphics[width=5em]{example-image-a}}
\def\imageB{\includegraphics[width=5em]{example-image-b}}
\itemAlign{\linewidth}{\imageA}\par
\itemAlign{\linewidth}{\imageA\imageA}\par
\itemAlign{\linewidth}{\imageB\imageB\imageB}\par
\itemAlign{\linewidth}{\imageB\imageB\imageB\imageB}

\vskip6em
\dotfill\par
\def\parA{\parbox[c]{12em}{\lipsum[1][1-2]}}
\def\parB{\parbox[c]{12em}{\lipsum[1][3-5]}}
\itemAlign[\sffamily]{\linewidth}{\parA}\par
\itemAlign[\color{red}]{\linewidth}{\parA\parA}\par
\itemAlign[\fbox]{\linewidth}{\parB\parB\parB}
\end{document}

编译结果如下:
image.png

注意事项:

  • 如果你想要更改 \itemAlign 第二个参数中对象的分割方式,可以把 \tl_map_inline:nn 换为 \clist_map_inline:nn 之类的函数.
  • 注意空格,任何显示的空格都会被 吞掉, 可以使用 \␣~ 替代.
Sagittarius Rover
我要成为Typst糕手/(ㄒoㄒ)/~~

似乎有很明显的循环结构呀🧐

\documentclass{beamer} 
\usepackage{tikz}
\makeatletter
\newcommand{\Letter}[1]{\@Alph{#1}}
\makeatother
\newcommand{\myplot}[1]{
    \foreach \i[evaluate=\i as \j using (\i/(1+#1))] in {1,...,#1} {
        \node[minimum size=2cm,font=\tiny,align=center] at (\j\linewidth,0) {\Letter{\i}\\(\j,0)};
    }
}
\begin{document} 
\tikzset{every node/.style={draw,dotted,inner sep=.5cm}}
\begin{frame}
\centering%
\tikz{\myplot{1}}\medskip

\tikz{\myplot{2}}\medskip

\tikz{\myplot{3}}\medskip

\tikz{\myplot{4}}\medskip

\end{frame}
\begin{frame}
    \centering%
    \foreach \x in {4,...,1}{%
        \tikz{\myplot{\x}}\par\medskip
    }
\end{frame}
\end{document} 

image.png

Edit:

node里的内容通常是写一大段不相同的文字,怎么循环?

也许用clist会挺方便(?)可以自己设计一下syntax(例如\mydraw{C,A,V,X})

我自己写的时候没注意到\centering的重要作用😡,怀疑人生了好一会儿...

\documentclass{beamer} 
\usepackage{tikz}
\begin{document} 
\tikzset{every node/.style={draw,dotted,inner sep=.5pt}}
\ExplSyntaxOn
\NewDocumentCommand{\mydraw}{m}{%
    \clist_set:Nn \l_tmpa_clist {#1}
    % \clist_use:Nn \l_tmpa_clist {;} \par
    \int_set:Nn \l_tmpa_int { \clist_count:N \l_tmpa_clist }
    \begin{tikzpicture}
        \foreach \i in {1,...,\l_tmpa_int} {%
            \def\j{\fpeval{round(\i/(1+\l_tmpa_int),4)}}% texdoc xfp
            \node[minimum~size=1.5cm,font=\tiny,align=center] at (\j\textwidth,0) {(\j)\\ \clist_item:Nn \l_tmpa_clist {\i}};
        }
    \end{tikzpicture}
}
\ExplSyntaxOff
\begin{frame}
    \centering%
    \mydraw{ahahaha,123456,1aaa2,{some~text,hia\\hiahia},kkk}\medskip

    \mydraw{I~am~A,You~are~B,He~is~C}\medskip

    \mydraw{C,A,B,F,E,H,G}\medskip
\end{frame}
\end{document} 

image.png

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览