自定义填充 TIKZ 节点而不覆盖文本

自定义填充 TIKZ 节点而不覆盖文本

我想为文本创建自定义框架,并决定使用 TIKZ 包。

我想要一个带有自定义填充标题的文本框,即不是全部填充,也不是全部为空,以及另一个带有内容的文本框。

这个例子基于我在另一个帖子上看到的一张图片。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\mybox}[2]{
\begin{tikzpicture}
\node[minimum width = \linewidth, text = white] (title) {\bfseries\Large #1};
\node[minimum width = \linewidth, anchor = north] at (title.south) (main frame) {\parbox{.95\linewidth}{#2}};

\draw[line width= 0.25mm] (title.north west) -- (main frame.south west) -- (main frame.south east) -- (title.north east);

\filldraw[fill = blue, line width= 0.25mm]
let \p1 = (title.south west),
\p2 = (title.north west),
\p3 = (title.south east),
\p4 = (title.north east) in
(\x2, \y2) arc (90:0:0.5*\y2-0.5*\y1) arc (180:270:0.5*\y2-0.5*\y1) -- (\x3 - \y2 + \y1, \y1) arc (270:360:0.5*\y2-0.5*\y1) arc (180:90:0.5*\y2-0.5*\y1) -- cycle;
\draw[text = white] node at (title){\bfseries\Large #1};
\end{tikzpicture}
}

\begin{document}
\mybox{TITLE}{
Many paragraphs 

can 

go 

in content.
}
\end{document}

例子

这样可以得到令人满意的结果,但请注意一件事。我需要(title)先绘制节点以确定大小(如果标题很长,则可能需要两行),然后绘制背景,然后重新绘制节点以显示文本。

有没有更有效的绘图方式,而不必绘制两次相同的节点(即在绘制背景时不覆盖文本)?

答案1

tcolorbox包可能是一个很好的方法,但是对于您的特定代码,您可以加载该backgrounds库,然后使用\begin{scope}[on background layer] \filldraw ... \end{scope}它来绘制标题节点后面的背景。

代码输出

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,backgrounds}
\newcommand{\mybox}[2]{
\begin{tikzpicture}
\node[minimum width = \linewidth, text = white] (title) {\bfseries\Large #1};
\node[minimum width = \linewidth, anchor = north] at (title.south) (main frame) {\parbox{.95\linewidth}{#2}};

\draw[line width= 0.25mm] (title.north west) -- (main frame.south west) -- (main frame.south east) -- (title.north east);

\begin{scope}[on background layer]
\filldraw[fill = blue, line width= 0.25mm]
let \p1 = (title.south west),
\p2 = (title.north west),
\p3 = (title.south east),
\p4 = (title.north east) in
(\x2, \y2) arc (90:0:0.5*\y2-0.5*\y1) arc (180:270:0.5*\y2-0.5*\y1) -- (\x3 - \y2 + \y1, \y1) arc (270:360:0.5*\y2-0.5*\y1) arc (180:90:0.5*\y2-0.5*\y1) -- cycle;
\end{scope}
\end{tikzpicture}
}

\begin{document}
\mybox{TITLE}{
Many paragraphs 

can 

go 

in content.
}
\end{document}

答案2

类似带有的框tcolorbox。代码改编自tcolorbox文档第 161 页中的示例。

\documentclass{article}
\usepackage[most]{tcolorbox}
\usepackage{varwidth}
\usepackage{lipsum}

\newtcolorbox{mybox}[2][]{%
skin=enhancedlast jigsaw, 
interior hidden,
boxsep=0pt, 
boxrule=1pt,
top=2mm, 
sharp corners,
colframe=black, 
coltitle=white,
fonttitle=\bfseries,
attach boxed title to top center={yshift*=-\tcboxedtitleheight},
boxed title style={empty,boxrule=1pt, size=small},
varwidth boxed title=0.75\linewidth,
underlay boxed title={
\path[draw, fill=blue!70!black, line width=1pt]
(frame.north west)
cos +(5mm,-\tcboxedtitleheight/2)
sin +(5mm,-\tcboxedtitleheight/2)
-- ([shift={(-10mm,-\tcboxedtitleheight)}]frame.north east) cos +(5mm,\tcboxedtitleheight/2)
sin +(5mm,\tcboxedtitleheight/2);
\draw[line width=1pt] (frame.north west)--(frame.north east); },
title={#2},#1}

\begin{document}

\begin{mybox}{This is a ver very long title which uses more than one line}
\lipsum[2]
\end{mybox}

\end{document}

在此处输入图片描述

相关内容