如何在 tikz 中拥有一个不可见的图层?

如何在 tikz 中拥有一个不可见的图层?

早在 2014 年,我就发布了一些代码不可见地绘制样式节点(幻影/屏幕外)?,下面重新发布。然后它显然编译成功了;使用我当前的 texlive 2014(可能一个月前更新过),现在它失败了:

! Package pgf Error: Sorry, the requested layer 'invisible' is not part of the 
layer list. Please verify that you provided \pgfsetlayers and that 'invisible' 
is part of this list.

See the pgf package documentation for explanation.

所以我的猜测是:

只需声明一个 pgf 层,但不要设置它 - 它将使您在其上绘制的所有内容都不可见;

...不再有效 - 因为现在它显然会引发错误。

那么,是否有可能使用当前 API 在 tikz 中创建一个不可见的层?

代码:

\documentclass[varwidth]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\pagecolor{yellow!15}
% just declare the layer, and don't do
% \pgfsetlayers ; then it will be invisible:
\pgfdeclarelayer{invisible}
\begin{document}
\begin{tikzpicture}
\makeatletter
\pgfdeclareshape{testshape}{ %
  \inheritsavedanchors[from={rectangle}] %
  \inheritbackgroundpath[from={rectangle}] %
  \inheritanchorborder[from={rectangle}] %
  \foreach \x in {center,north,north east,north west,south,south east,south west,east,west}{ %
    \inheritanchor[from={rectangle}]{\x} %
  } %
  %\backgroundpath{} %
  \foregroundpath{ %
    \draw[] (\tikz@[email protected] west) -- (\tikz@[email protected] east)
      (\tikz@[email protected] west) -- (\tikz@[email protected] east);
  }
}
\makeatother

\tikzstyle{mynode} = [testshape,draw=gray,line width=2pt,inner sep=2pt, outer sep=5pt, minimum width=2cm,minimum height=0pt,align=center]

\node[mynode] (Starter) {Testing the node\\(a bit)};
\node[mynode] (Ender) [right=2cm of Starter] {Also test\\(even more)};

\begin{pgfonlayer}{invisible}
\node[mynode] (tester) [at=(current bounding box.center)] {Trying to measure this one};
\end{pgfonlayer}

\path let \p1=(tester.north east), \p2=(tester.south west)
  in coordinate (testerSize) at (\x1-\x2,\y1-\y2);

% \pgfpointanchor{testerSize}{center} % "returns"/sets a (last) pgfpoint
\path(testerSize.center); % a bit easier than \pgfpointanchor: https://tex.stackexchange.com/a/33706/2595

\pgfgetlastxy{\testerWidth}{\testerHeight} % ... and globalize:
\global\let\testerWidth\testerWidth
\global\let\testerHeight\testerHeight

\typeout{tester size is: \testerWidth\space X \testerHeight}

\end{tikzpicture}

tester size is: \testerWidth\ X \testerHeight

\end{document}

答案1

每个图层都存储在自己的框中,每个框都按顺序插入到图片末尾。以下是代码的破解,它只插入未声明为不可见的图层/框。这应该没问题,尽管我不能保证它是 100% 可靠的。

必须将图层声明为不可见一张图片开始,但每张图片的不同层可以是不可见的。此外,整个图片的边界框包括不可见层的内容。

\documentclass[border=5]{standalone}
\usepackage{tikz}

\makeatletter

\def\pgfsetinvisiblelayers#1{\def\pgf@layers@invisible{#1}}
\def\pgfshowalllayers{\let\pgf@layers@invisible=\pgfutil@empty}
\pgfshowalllayers

\def\pgf@dolayer#1,#2,\relax{%
  % Is layer declared as invisible...?
  \edef\pgf@marshal{\noexpand\pgfutil@in@{,#1,}{,\pgf@layers@invisible,}}%
  \pgf@marshal%
  \ifpgfutil@in@% Yep. So do nothing.
  \else% Nope. So, insert box.
    \def\pgf@test{#1}%
    \ifx\pgf@test\pgf@maintext%
      \box\pgf@layerbox@main%
    \else%
      \pgfsys@beginscope%
        \expandafter\box\csname pgf@layerbox@#1\endcsname%
      \pgfsys@endscope%
    \fi%
  \fi
  \def\pgf@test{#2}%
  \ifx\pgf@test\pgfutil@empty%
  \else%
    \pgf@dolayer#2,\relax%
  \fi%
}

\pgfdeclarelayer{layer 1}
\pgfdeclarelayer{layer 2}
\pgfdeclarelayer{layer 3}
\pgfdeclarelayer{label}
\pgfsetlayers{main,layer 1,layer 2,layer 3,label}

\begin{document}

\foreach \l in {main,layer 1,layer 2,layer 3,{main,layer 2}}{
\pgfsetinvisiblelayers{\l}
\begin{tikzpicture}
\begin{pgfonlayer}{label}
  \node at (0,-2) [above] {Invisible: \ttfamily\l};
\end{pgfonlayer}
\fill [gray] (-2,-2) rectangle (2,2);
\begin{pgfonlayer}{layer 1}
  \fill [red, opacity=0.75] circle [radius=1.5];
\end{pgfonlayer}
\begin{pgfonlayer}{layer 2}
  \fill [green, opacity=0.75]
    (90:2) -- (210:2) -- (330:2) -- cycle;
\end{pgfonlayer}
\begin{pgfonlayer}{layer 3}
  \fill [blue, opacity=0.75]
    (225:1) rectangle (45:1);
\end{pgfonlayer}

\end{tikzpicture}
}
\end{document}

在此处输入图片描述

答案2

K,这里有一个小技巧,可以让上面的示例现在编译;这个例子看起来不错,但不确定总体方法。但在得到更博学的答案之前:我们可以用 来“绕过” tikzpicture 内部的错误引发\let\pgfonlayer@assert@fail\relax;而在 tikzpicture 之外,原始\pgfonlayer@assert@fail宏将被恢复。

或者,作为一个整体的 MWE:

\documentclass[varwidth]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\pagecolor{yellow!15}
% just declare the layer, and don't do
% \pgfsetlayers ; then it will be invisible:
\pgfdeclarelayer{invisible}
\begin{document}
\begin{tikzpicture}
\makeatletter
\pgfdeclareshape{testshape}{ %
  \inheritsavedanchors[from={rectangle}] %
  \inheritbackgroundpath[from={rectangle}] %
  \inheritanchorborder[from={rectangle}] %
  \foreach \x in {center,north,north east,north west,south,south east,south west,east,west}{ %
    \inheritanchor[from={rectangle}]{\x} %
  } %
  %\backgroundpath{} %
  \foregroundpath{ %
    \draw[] (\tikz@[email protected] west) -- (\tikz@[email protected] east)
      (\tikz@[email protected] west) -- (\tikz@[email protected] east);
  }
}
\makeatother

\tikzstyle{mynode} = [testshape,draw=gray,line width=2pt,inner sep=2pt, outer sep=5pt, minimum width=2cm,minimum height=0pt,align=center]

\node[mynode] (Starter) {Testing the node\\(a bit)};
\node[mynode] (Ender) [right=2cm of Starter] {Also test\\(even more)};

\makeatletter
\let\pgfonlayer@assert@fail\relax
\makeatother
\begin{pgfonlayer}{invisible}
\node[mynode] (tester) [at=(current bounding box.center)] {Trying to measure this one};
\end{pgfonlayer}

\path let \p1=(tester.north east), \p2=(tester.south west)
  in coordinate (testerSize) at (\x1-\x2,\y1-\y2);

% \pgfpointanchor{testerSize}{center} % "returns"/sets a (last) pgfpoint
\path(testerSize.center); % a bit easier than \pgfpointanchor: http://tex.stackexchange.com/a/33706/2595

\pgfgetlastxy{\testerWidth}{\testerHeight} % ... and globalize:
\global\let\testerWidth\testerWidth
\global\let\testerHeight\testerHeight

\typeout{tester size is: \testerWidth\space X \testerHeight}

\end{tikzpicture}

\makeatletter % original pgfonlayer@assert@fail is restored here:
\typeout{MACRO pgfonlayer@assert@fail is: \meaning\pgfonlayer@assert@fail}
\makeatother
tester size is: \testerWidth\ X \testerHeight

\end{document}

相关内容