![Tikz 從上到下繪製在圖層堆疊上(相反的順序)](https://rvso.com/image/420763/Tikz%20%E5%BE%9E%E4%B8%8A%E5%88%B0%E4%B8%8B%E7%B9%AA%E8%A3%BD%E5%9C%A8%E5%9C%96%E5%B1%A4%E5%A0%86%E7%96%8A%E4%B8%8A%EF%BC%88%E7%9B%B8%E5%8F%8D%E7%9A%84%E9%A0%86%E5%BA%8F%EF%BC%89.png)
在 Tikz 中,我想要一個指令
\StartDrawOnBottomOfLayerStack
繪製所有以下元素底層的底部圖片的。這意味著以下節點和路徑出現在圖片的所有內容後面。我需要一個命令來返回標準行為
\StartDrawOnTopOfLayerStack
目前,我必須定義與要繪製的背景節點一樣多的層。我想知道是否可以更容易實現?
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}
\pgfdeclarelayer{background3}
\pgfdeclarelayer{background2}
\pgfdeclarelayer{background1}
\pgfsetlayers{background3,background2,background1,main}
\begin{tikzpicture}
%% block diagram
\node[rectangle,draw,fill=yellow] (A) at (-4,0) {A};
\node[rectangle,draw,fill=yellow] (B) at (-3,0) {B};
\node[rectangle,draw,fill=yellow] (C) at (-2,0) {C};
\node[rectangle,draw,fill=yellow] (D) at (-1,0) {D};
% \StartDrawOnBottomOfLayerStack
%% group 1
\begin{pgfonlayer}{background1}
\node[rectangle,fill=green,fit={(B) (C)}](G1) {};
\end{pgfonlayer}
%% group 2
\begin{pgfonlayer}{background2}
\node[fill=blue,fit={(B) (C) (D)(G1)}](G2) {};
\end{pgfonlayer}
%% group 3
\begin{pgfonlayer}{background3}
\node[fill=red,fit={(A)(B) (C) (D) (G1) (G2)}](G3) {};
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
答案1
簡短介紹,從下往上:
- 類似環境
pgfonlayer
,新環境pgfonlayerreversed
,定義了。其內容將在指定圖層上排版,但順序相反,即排版最新內容以下累積的內容。 on background layer
與庫中的選項類似backgrounds
,on background layer reversed
定義了使用新環境pgfonlayerreversed
(在圖層上background
)的新選項。- 最後,
\StartDrawOnBottomOfLayerStack
和\EndDrawOnBottomOfLayerStack
構成了一個特殊的scope
環境,其中 的每次使用\node
都相當於\scoped[on lowest layer] \node
。
全面實施:
% from https://tex.stackexchange.com/q/562577
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{backgrounds, fit}
\usepackage{xpatch}
\makeatletter
% similar to env "pgfonlayer", but the latest contents are typeset on
% lowest bottom (on reversed order)
\let\pgfonlayerreversed\pgfonlayer
\let\endpgfonlayerreversed\endpgfonlayer
\xpatchcmd\pgfonlayerreversed
{\expandafter\box\csname pgf@layerbox@#1\endcsname\begingroup}
{\begingroup}
{}{\fail}
\xpatchcmd\endpgfonlayerreversed
{\endgroup}
{\endgroup\expandafter\box\csname pgf@layerbox@\pgfonlayer@name\endcsname}
{}{\fail}
\tikzset{
on background layer reversed/.style={%
execute at begin scope={%
\pgfonlayerreversed{background}%
\let\tikz@options=\pgfutil@empty
\tikzset{every on background layer/.try,#1}%
\tikz@options
},
execute at end scope={\endpgfonlayerreversed}
}
}
\def\StartDrawOnBottomOfLayerStack{%
\scope\relax
% patch \path variants to auto insert "\scoped[on lowest layer]"
% currently \node, \pic, \coordinate, and \matrix are patched
\let\tikz@path@overlay\tikz@path@overlay@autoscoped
\let\tikz@path@overlayed\tikz@path@overlayed@autoscoped
}
\def\EndDrawOnTopOfLayerStack{%
\endscope
}
\def\tikz@path@overlay@autoscoped#1{%
\let\tikz@signal@path=\tikz@signal@path% for detection at begin of matrix cell
\pgfutil@ifnextchar<%
{\tikz@path@overlayed{#1}}
{\scoped[on background layer reversed] \path #1}}%
\def\tikz@path@overlayed@autoscoped#1<#2>{%
\scoped[on background layer reversed] \path<#2> #1}%
\makeatother
\begin{document}
\begin{tikzpicture}
% text nodes
\node[rectangle,draw,fill=yellow] (A) at (-4,0) {A};
\node[rectangle,draw,fill=yellow] (B) at (-3,0) {B};
\node[rectangle,draw,fill=yellow] (C) at (-2,0) {C};
\node[rectangle,draw,fill=yellow] (D) at (-1,0) {D};
% background rectangles
\StartDrawOnBottomOfLayerStack
\node[rectangle,fill=green,fit={(B) (C)}](G1) {};
\node[fill=blue,fit={(B) (C) (D)(G1)}](G2) {};
\node[fill=red,fit={(A)(B) (C) (D) (G1) (G2)}](G3) {};
\EndDrawOnTopOfLayerStack
\end{tikzpicture}
\end{document}