如何在 PGF/TikZ 中儲存目前顏色?

如何在 PGF/TikZ 中儲存目前顏色?

在 TikZ/PGF 中,我們可以使用 來取得目前線寬\pgflinewidth。不幸的是,沒有(據我所知)\pgfstrokecolor、、\pgffillcolor和。\pgfstrokeopacity\pgffillopacity

我的主要問題是:有沒有辦法恢復目前的繪製和填滿顏色?

我知道最後設定的顏色\color 可以恢復\colorlet{saved}{.},因為點代表最後一種顏色。當我們直接將顏色設定為樣式時,可以使用此功能,例如\draw[red] ...(請參閱程式碼)。

我嘗試破解\pgfsetstrokecolor,\pgfsetfillcolor\pgfsetcolor以某種方式保存最後一次通話......但沒有成功。

在下面的程式碼中,我正在尋找一些技巧來保存顏色,以便能夠在另一層中重複使用它們。

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}

\pgfdeclarelayer{foreground}
\pgfsetlayers{main,foreground}

\begin{document}
  \begin{tikzpicture}[green, draw=red, ultra thick, fill=yellow, text=purple]
    \filldraw (-.5,-.5) rectangle +(1,1) node[midway]{A};
    \pgfmathsetlengthmacro{\savedpgflinewidth}{\pgflinewidth}
    \colorlet{saved}{.}
    \def\pgfstrokecolor{red} % <- to be replaced by \strokecolorlet
    \def\pgffillcolor{yellow} % <- to be replaced by \fillcolorlet

    \begin{pgfonlayer}{foreground}
      \draw (0,0) rectangle +(1,1) node[midway]{B};
      \color{saved} % <- restore the color set by \color{green}
      \pgfsetlinewidth{\savedpgflinewidth} % <- restore the line width
      \draw (.5,.5) rectangle +(1,1) node[midway]{C};
      \pgfsetstrokecolor{\pgfstrokecolor} % <- restore the draw color
      \pgfsetfillcolor{\pgffillcolor} % <- restore the fill color
      \filldraw (1,1) rectangle +(1,1) node[midway]{D};
    \end{pgfonlayer}

    \filldraw (1.5,1.5) rectangle +(1,1) node[midway]{E}; % <- line width reset after pgfonlayer !
  \end{tikzpicture}
\end{document}

在此輸入影像描述

註1:在下面的程式碼中我們可以看到,使用 後線寬被重設pgfonlayer。這是一個錯誤還是一個(已記錄的)功能?

筆記2:以一種奇怪的方式,文字顏色會在圖層更改後保留下來,但其他顏色和線寬都不會。

註3:我的印像是\pgfsetcolorTikZ 沒有使用它,而是\color使用了它。如果是這樣,為什麼?


編輯:上面的程式碼只是一個工作範例。我不想在不恢復顏色的情況下解決這個特殊情況。

答案1

這是一種概念性的方法。我認為有很多事情需要改進(更少的宏,因為你只需要顏色描述中的最後兩項,適當的擴展控制,自訂巨集名稱的可能性)但我沒有時間。我想你可以從這裡拿走它。

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\makeatletter
\tikzset{get stroke color/.code={%
    \expandafter\global% Jump over, now we have \global
    \expandafter\let% Jump over now we have \global\let
    \expandafter\pgfsavedstrokecolor% Jump we have \global\let\pgf...
    \csname\string\color@pgfstrokecolor\endcsname% Finally expand this and put it at the end 
    },                                           % \global\let\pgf...{} in expanded form 
    restore stroke color/.code={\pgf@setstrokecolor#1},
}


\begin{document}
  \begin{tikzpicture}[green, draw=yellow!20!blue, ultra thick, fill=yellow, text=purple]
    \tikzset{get stroke color}% <-- Gets the drive-dependent low-level desc of y!20!b
    \show\pgfsavedstrokecolor% <-- Look at the log
    \filldraw (0,0) rectangle +(1,1) node[midway]{A};
    \pgfsetstrokecolor{orange} % <-- Change the drawing color to orange
    \draw (0.5,0.5) rectangle +(1,1) node[midway]{B}; % <-- Draw something to verify
    \tikzset{restore stroke color/.expand once=\pgfsavedstrokecolor} % <-- Restore it back
    \draw (1,1) rectangle +(1,1) node[midway]{C}; % <-- Verify
  \end{tikzpicture}
\end{document}

在此輸入影像描述

答案2

簡單的方法是聲明性方法:使用pgfkeys及其.style處理程序來儲存您的首選項(顏色、線寬等)並多次應用它們。

在此輸入影像描述

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}

\pgfdeclarelayer{foreground}
\pgfsetlayers{main,foreground}

\begin{document}
\tikzset{my preferecences/.style={green, draw=red, ultra thick,fill=yellow, text=purple}}
\begin{tikzpicture}[my preferecences]
    \filldraw (-.5,-.5) rectangle +(1,1) node[midway]{A};
    \begin{pgfonlayer}{foreground}
      \begin{scope}[my preferecences]
      \draw (0,0) rectangle +(1,1) node[midway]{B};
      \draw (.5,.5) rectangle +(1,1) node[midway]{C};
      \filldraw (1,1) rectangle +(1,1) node[midway]{D};
      \end{scope}
    \end{pgfonlayer}

    \filldraw (1.5,1.5) rectangle +(1,1) node[midway]{E}; % <- line width reset after pgfonlayer !
  \end{tikzpicture}
\end{document}

相關內容