TikZ 相对于命令中的其他节点定位节点

TikZ 相对于命令中的其他节点定位节点

所以我是 TeX 的新用户。我在 HTML 和 CSS 方面经验丰富,但这完全是另一回事。

我有以下命令:

\newcommand{\header}[4]{
  \begin{tikzpicture}[remember picture, overlay]
    \node [below right, fill=#1, minimum height=\hdrheight, minimum width=\paperwidth, outer sep=0] (name) at (current page.north west) {};
    \node[text=white, anchor=east, xshift=-10mm] (nametext) at (name.east) {
      \fontsize{40pt}{32pt}\color{white}
      {\titlefont #2}
    };
  \end{tikzpicture}
}

它运行得很好。但是,假设我想重复使用它。如果我\header再次调用,它将直接写在前一个节点的顶​​部。我如何正确定位它以便它将绘制在前一个节点下?每个节点都像传单或其他东西上某个部分的标题。它下面将是该部分的正确文本。因此,元素将被定位在最后一个结束的位置。

谢谢

答案1

要在 tikz 中将节点相对放置,请使用\usetikzlibrary{positioning}

\node (a) {node a};
\node (b) [above=of a] {node b};

其中前面of可以给出距离。

以下代码放置标题以下彼此,因为这比彼此之上更容易:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\newlength{\hdrheight}
\setlength{\hdrheight}{1cm}
\newcounter{headercounter}
\setcounter{headercounter}{0}

\newcommand{\header}[4]{%
    \begin{tikzpicture}[remember picture, overlay]
        \ifnum \theheadercounter=0
            \def\positionKey{at}
            \def\positionVal{(current page.north)}
        \else
            \def\positionKey{below}
            \def\positionVal{0em of header-\number\numexpr\theheadercounter-1\relax}
        \fi
        \node[anchor=north, fill=#1, minimum height=\hdrheight, minimum width=\paperwidth, outer sep=0, \positionKey=\positionVal] (header-\theheadercounter) {};
        \node[text=white, anchor=east, xshift=-10mm, text=white, font=\fontsize{40pt}{32pt}] at (header-\theheadercounter.east) {#2};
    \end{tikzpicture}%
    \stepcounter{headercounter}%
}


\begin{document}
\header{yellow}{hello world}{arg3}{arg4}%
\header{green}{hello again}{arg3}{arg4}%
\header{orange}{and a third one}{arg3}{arg4}%
content...
\end{document}

屏幕截图 1:标题相互重叠

请注意,我如何使用%字符注释掉换行符以避免出现不必要的空格。(a 内的空格tikzpicture将被忽略 - 这就是我没有在那里这样做的原因。)

另外,请注意,这仅适用于一页。如果您想再次在另一页上使用它,则需要使用 重置计数器\setcounter{headercounter}{0}

在 LaTeX 中设置标题的常用方法是使用fancyhdr包。有关简单示例,请参阅其第 5 页文档


以下代码放置标题多于彼此。为了做到这一点,该\header命令现在仅将标题保存在不同的命令中,并且当所有标题都已指定时,该\setheaders命令将循环遍历所有标题并将它们以相反的顺序放在彼此之下。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\newlength{\hdrheight}
\setlength{\hdrheight}{1cm}
\newcounter{headercounter}
\setcounter{headercounter}{0}
\newif\ifFirstHeader

\newcommand{\header}[4]{% #1: background color, #2: text, #3: ?, #4: ?
    \def\saveheader##1{%
        \expandafter\def\csname header\theheadercounter\endcsname{%
            \begin{tikzpicture}[remember picture, overlay]
                \ifFirstHeader
                    \def\positionKey{at}
                    \def\positionVal{(current page.north)}
                    \global\FirstHeaderfalse
                \else
                    \def\positionKey{below}
                    \def\positionVal{0em of header-\number\numexpr##1+1\relax}
                \fi
                \node[anchor=north, fill=#1, minimum height=\hdrheight, minimum width=\paperwidth, outer sep=0, \positionKey=\positionVal] (header-##1) {};
                \node[text=white, anchor=east, xshift=-10mm, text=white, font=\fontsize{40pt}{32pt}] at (header-##1.east) {#2};
            \end{tikzpicture}%
        }%
    }%
    \expandafter\saveheader\expandafter{\theheadercounter}%
    \stepcounter{headercounter}%
}
\newcommand{\setheaders}{%
    \FirstHeadertrue
    \loop
        \addtocounter{headercounter}{-1}%
        \csname header\theheadercounter\endcsname
    \ifnum\theheadercounter>0
    \repeat
}


\begin{document}
\header{yellow}{hello world}{arg3}{arg4}%
\header{green}{hello again}{arg3}{arg4}%
\header{orange}{and a third one}{arg3}{arg4}%
\setheaders
content...

\newpage
\header{blue!30}{new page}{arg3}{arg4}%
\header{green!70!blue!30}{new header}{arg3}{arg4}%
\setheaders
content...
\end{document}

屏幕截图 2:标题相互重叠


编辑:如果你想定制\section命令和朋友标题安全是要走的路:

\documentclass{article}
\usepackage{titlesec}
\usepackage{tikz}
\usetikzlibrary{positioning}

\newlength{\hdrheight}
\setlength{\hdrheight}{1cm}
\newcounter{headercounter}
\setcounter{headercounter}{0}

\newcommand{\lastPageWithHeader}{-1}
\newcommand{\header}[4]{%
    \ifnum\thepage=\lastPageWithHeader
    \else
        \setcounter{headercounter}{0}%
    \fi
    \xdef\lastPageWithHeader{\thepage}%
    \begin{tikzpicture}[remember picture, overlay]
        \ifnum \theheadercounter=0
            \def\positionKey{at}
            \def\positionVal{(current page.north)}
        \else
            \def\positionKey{below}
            \def\positionVal{0em of header-\number\numexpr\theheadercounter-1\relax}
        \fi
        \node[anchor=north, fill=#1, minimum height=\hdrheight, minimum width=\paperwidth, outer sep=0, \positionKey=\positionVal] (header-\theheadercounter) {};
        \node[text=white, anchor=east, xshift=-10mm, text=white, font=\fontsize{40pt}{32pt}] at (header-\theheadercounter.east) {#2};
    \end{tikzpicture}%
    \stepcounter{headercounter}%
}

\newcommand{\setTitleBackgroundColor}[1]{%
    \def\theTitleBackgroundColor{#1}%
    \ignorespaces
}
\setTitleBackgroundColor{black}

\newcommand{\sectionformat}[1]{%
    \header{\theTitleBackgroundColor}{#1}{arg3}{arg4}%
    #1%
}

% default values copied from titlesec documentation page 23
% parameters of \titleformat command are explained on page 4
\titleformat%
    {\section}% <command> is the sectioning command to be redefined, i. e., \part, \chapter, \section, \subsection, \subsubsection, \paragraph or \subparagraph.
    {\normalfont\Large\bfseries}% <format>
    {}% <label> the number
    {0em}% <sep> length. horizontal separation between label and title body
    {\sectionformat}% code preceding the title body  (title body is taken as argument)

\usepackage{blindtext}
\begin{document}
\tableofcontents
\newpage

\setTitleBackgroundColor{yellow}
\section{Section~1}
\blindtext
\setTitleBackgroundColor{green}
\section{Section~2}
\Blindtext
\setTitleBackgroundColor{orange}
\section{Section~3}
\Blindtext
\setTitleBackgroundColor{brown}
\section{Section~4}
\blindtext
\setTitleBackgroundColor{blue!30}
\section{Section~5}
\blindtext
\setTitleBackgroundColor{green!70!blue!30}
\section{Section~6}
\blindtext
\setTitleBackgroundColor{rgb,255:red,255; green,194; blue,0}
\section{Section~7}
\blindtext
\end{document}

屏幕截图:自定义部分标题

如果您想自定义间距,\section可以使用\titlespacing{\section}{<left-margin>}{<space-above-the-heading>}{<space-below-the-heading>}

如果您想了解有关如何指定颜色的更多信息,请参阅xcolor 包文档这个答案

相关内容