是否有一种通用方法可以禁用 Ti 中的预操作/后操作钾Z 阴影等效果依赖于什么?
如果没有,是否有一种简单的方法可以让用户向现有样式添加选项,以便他们可以中和其效果,例如通过将阴影的不透明度设置为 0,如https://tex.stackexchange.com/a/354728/?
首先是一些可以按我想要的方式运行的代码(我认为):
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shadows,positioning}
\newif\ifshowplaceholders
\showplaceholdersfalse
\tikzset{%
my node/.style={fill=gray,draw=black},
placeholders/.is choice,
placeholders/off/.code={%
\showplaceholdersfalse\let\myphantom\phantom
\pgfqkeys{/tikz}{placeholder/.style={my node,fill=none, draw=none}}%
},
placeholders/on/.code={%
\showplaceholderstrue\def\myphantom##1{##1}%
\pgfqkeys{/tikz}{placeholder/.style={my node,opacity=.25,text opacity=.5}}%
},
placeholders/.default=on,
placeholders=off,
}
\begin{document}
\begin{tikzpicture}
\node (n) [my node] {My Node};
\node (p) [above=10pt of n,placeholder] {\myphantom{Placeholder}};
\end{tikzpicture}
\end{document}
基本思想是可以创建占位符节点来帮助放置“真实”节点。在正常情况下,这些节点是不可见的,但仍可用于放置。
如果需要,它们可以被呈现为可见的,以便进行调试。
placeholders=on,
现在假设有人想给“真实节点”添加阴影
my node/.style={fill=gray,drop shadow,draw=black},
% placeholders=on,
现在占位符是不可见的,正如它应该的那样,但它的影子却不可见。
理想情况下,我想禁用占位符节点的预操作和后操作,但由于不知道该怎么做,我尝试至少让用户添加中和代码,但我无法让它工作。我怀疑这与扩展有关,但我还没有找到一种既不产生错误也不产生可见性的方法。
我不会指望下面的方法会起作用,所以我对它不起作用并不感到惊讶,但我将它包括在内,因为它代表了我认为如何处理这个问题的示意图。
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shadows,positioning}
\newif\ifshowplaceholders
\showplaceholdersfalse
\tikzset{%
my node/.style={fill=gray,draw=black},
placeholders/.is choice,
placeholders/off/.code={%
\showplaceholdersfalse\let\myphantom\phantom
\pgfqkeys{/tikz}{placeholder/.style={my node,fill=none, draw=none}}%
},
placeholders/on/.code={%
\showplaceholderstrue\def\myphantom##1{##1}%
\pgfqkeys{/tikz}{placeholder/.style={my node,opacity=.25,text opacity=.5}}%
},
placeholders/.default=on,
placeholders=off,
placeholders/when off/.code={%
% \edef\tempa{#1}%
\pgfqkeys{/tikz}{%
placeholders/off/.append code={%
\pgfqkeys{/tikz}{placeholder/.append code={\pgfqkeys{/tikz}{#1}}}%
},
}%
\ifshowplaceholders
\else
\pgfqkeys{/tikz}{placeholder/.append code={\pgfqkeys{/tikz}{#1}}}%
\fi
},
placeholders/when on/.code={%
% \edef\tempa{#1}%
\pgfqkeys{/tikz}{%
placeholders/on/.append code={%
\pgfqkeys{/tikz}{placeholder/.append code={\pgfqkeys{/tikz}{#1}}}%
}%
}%
\ifshowplaceholders
\pgfqkeys{/tikz}{placeholder/.append code={\pgfqkeys{/tikz}{#1}}}%
\fi
},
my node/.style={fill=gray,drop shadow,draw=black},
placeholders/when off={drop shadow={fill=none}},
% placeholders=on,
}
\begin{document}
\begin{tikzpicture}
\node (n) [my node] {My Node};
\node (p) [above=10pt of n,placeholder] {\myphantom{Placeholder}};
\end{tikzpicture}
\end{document}
我实际上是先尝试使用.append style
,但也没用。作为最后的手段,我可以使用 expl3,但我宁愿不这样做,因为这似乎是一个相对简单的问题。
我应该提到一些我没有考虑过的选项,从上面的 MWE 来看,这些选项可能看起来是不错的方法:
- 根本不使用
my node
占位符样式(我不知道样式是什么,我需要占位符相对于该样式进行标准化); - 消除最后一次运行的占位符(然后放置与它们相关的东西将不起作用 - 它们不像用于放置的临时网格那样被使用)。
我能做的事情:
- 当应用于这种类型的元素时,声明包与
shadows
类似的东西不兼容,除非占位符被禁用(很诱人,但有点核,人们无论如何都想这样做); - 引入(另一个)图层(或两个),用白色填充并在其后面创建占位符
off
(但该包已经创建了很多图层,而且这似乎有很多基础设施只是为了禁用阴影 - 如果用户使用在不同图层上绘制的预/后操作涉及的东西,它将不起作用)。
我的默认设置是仅记录不兼容性或采取某些措施expl3
,但我希望有更好的解决方案。
答案1
我想禁用占位节点的预操作和后操作
前置操作和后置操作仅存储在类似列表的宏中:
\tikz@preactions
和\tikz@postactions
。
将这些设置为空将删除所有先前添加的操作。
当然,用户只需在您清空它们后添加另一个操作即可。但您始终可以删除这些键本身:postaction/.code=, preaction/.code=
。(但这也适用于draw
、fill
等。)
说到draw
和fill
,我已经draw=none, fill=none
用path only
禁用替换了你的全部动作:绘制、填充、阴影、淡入淡出、图案、剪辑、用作边界框、路径图片、双重……
我还介绍了phantom node
钥匙这会禁用 PGF 针对相关节点发送 TeX 框的功能。形状的定义仍会考虑这些框的测量值,但不会将其放入页面上。
这\pgf@sh@boxes@<shape name>
是另一个包含列表的宏。在大多数情况下,这只是text
代表\pgfnodeparttextbox
。请参阅手动开启\pgfmultipartnode
关于这个话题我再说几句。
如果你比较代码 1 返回的两个页面,你会注意到占位符节点所在的页面不是显示的要小一些。(如果您不添加到line width=1ex
。my node
)这是因为绘制的路径将.5\pgflinewidth
在图片边界框的所有边上添加一个填充。
当未绘制路径时(即path only
或draw = none
),不会发生这种情况。
我只想补充overlay
一点,every placeholder node
从而禁用这些节点的任何边界框考虑。这似乎与其辅助用途一致,但当然会根据情况将这些占位符节点打印在图片的边界框之外。
我已经尝试了其他路径操作,以便更好地控制它添加undraw
和draw undraw
其中undraw
不会描边路径但会根据线宽改变边界框,并且draw undraw
会描边路径但忽略边界框的线宽。
不幸的是,这需要重新定义 PGF\pgfusepath
宏,我怀疑您是否想尝试这个。
说到盒子……
当 TikZ 遇到路径上的节点、边、图片或绘图标记时,它们或多或少会立即构造和排版,但放在一个盒子里,要么是前景或背景因此,路径实际上提供了三层,并且无论在路径上何时遇到节点,节点都可以位于路径之上。
虽然将一个节点放到一个单独的PGF层(看[1],[2] (第 5 节),[3])让一个节点消失是相当容易的。
虽然有特殊的discard
层,如果你真的不想看到那个节点……而不是路径的前景或背景框,我们可以使用任何框,然后不使用它(它也会在路径之后被遗忘;
)。
如果不设置path only
或,draw = none
边界框仍将进行调整(至少没有overlay
或类似,当然),但不会仅因线宽而变化。所有操作和排版仍将执行,并将创建节点。
代码 1(禁用绘图和操作)
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shadows, positioning}
\newif\ifshowplaceholders
\showplaceholdersfalse
\makeatletter
\tikzset{
no actions/.code=\let\tikz@preactions\pgfutil@empty
\let\tikz@postactions\pgfutil@empty,
phantom node/.code=\tikz@addoption % no recovery!
{\expandafter\let\csname pgf@sh@boxes@\tikz@shape\endcsname\pgfutil@empty}}
\makeatother
\tikzset{
show placeholders/.is if=showplaceholders,
placeholder/is on/.style={
every placeholder node, opacity=.25, text opacity=.5},
placeholder/is off/.style={
every placeholder node, path only, no actions, phantom node},
placeholder/.style={placeholder/is \ifshowplaceholders on\else off\fi},
placeholders/when off/.style={/tikz/placeholders/is off/.append style={#1}},
placeholders/when on/.style={/tikz/placeholders/is on/.append style={#1}}}
\tikzset{
my node/.style={fill=gray, draw=black},
every placeholder node/.style=my node}
\begin{document}
\begin{tikzpicture}[show placeholders, my node/.append style=drop shadow]
\node (n) [my node] {My Node};
\node (p) [above=10pt of n, placeholder] {Placeholder};
\end{tikzpicture}
\begin{tikzpicture}[show placeholders=false, my node/.append style=drop shadow]
\node (n) [my node] {My Node};
\node (p) [above=10pt of n, placeholder] {Placeholder};
\end{tikzpicture}
\end{document}
代码 2(将节点放入一次性盒子)
\documentclass[tikz, border=10pt]{standalone}
\usetikzlibrary{shadows, positioning}
\newif\ifshowplaceholders
\showplaceholdersfalse
\makeatletter
\tikzset{
discard node/.code=\setbox\pgfutil@tempboxa\box\pgfutil@voidb@x % empty out box
\def\tikz@whichbox{\pgfutil@tempboxa}}
\makeatother
\tikzset{
show placeholders/.is if=showplaceholders,
placeholder/is on/.style={every placeholder node, opacity=.25, text opacity=.5},
placeholder/is off/.style={every placeholder node, discard node},
placeholder/.style={placeholder/is \ifshowplaceholders on\else off\fi},
placeholders/.is choice,
placeholders/when off/.style={/tikz/placeholders/is off/.append style={#1}},
placeholders/when on/.style={/tikz/placeholders/is on/.append style={#1}}}
\tikzset{
my node/.style={fill=gray, draw=black},
every placeholder node/.style=my node}
\begin{document}
\begin{tikzpicture}[show placeholders, my node/.append style=drop shadow]
\node (n) [my node] {My Node};
\node (p) [above=10pt of n, placeholder] {Placeholder};
\end{tikzpicture}
\begin{tikzpicture}[show placeholders=false, my node/.append style=drop shadow]
\node (n) [my node] {My Node};
\node (p) [above=10pt of n, placeholder] {Placeholder};
\end{tikzpicture}
\end{document}