5

I would like to do something like here in order to clip text outside of an area. But I'd like to specify the area using precisely a given node (that, in my case, is constructed using fit). The thing is that I can't find how to convert a node border into a path. Any idea?

MWE:

\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{fit,shapes.misc}

\begin{document}
\begin{tikzpicture}
  [
    mybox/.style={fill=#1!30,draw=#1,rounded corners}
    ]
  \node[mybox=green] at (0,0) (a) {A};
  \node[mybox=blue] at (0,3) (b) {B};
  \node[mybox=orange] at (3,0) (c) {C};
  \node[mybox=pink] at (5,3) (d) {D};
  \draw[-latex] (a) -- (b);
  \draw[-latex] (b) -- (c);
  \draw[-latex] (c) -- (a);
  \draw[-latex] (c) -- (d);
  \node[fit=(a)(c), rounded rectangle, draw, inner sep=10pt] (fitnode) {};
  % How to remove 
  \fill[white,fill opacity=.75] [even odd rule]
  (current bounding box.south west) rectangle (current bounding box.north east)
  (fitnode.south west) rectangle (fitnode.north east);
\end{tikzpicture}
\end{document}

NB: I want a precise border fit, not just an approximation of my node by a rectangle.

tobiasBora
  • 8,684

2 Answers2

7

You can use spath3 library to save the node path with save spath=..., and then to reuse it with restore spath=....

\documentclass[tikz,border=7pt]{standalone}
\usepackage{spath3}
\usetikzlibrary{fit,shapes.misc}

\begin{document} \begin{tikzpicture}[ mybox/.style={fill=#1!30,draw=#1,rounded corners} ] \node[mybox=green] at (0,0) (a) {A}; \node[mybox=blue] at (0,3) (b) {B}; \node[mybox=orange] at (3,0) (c) {C}; \node[mybox=pink] at (5,3) (d) {D}; \draw[-latex] (a) -- (b); \draw[-latex] (b) -- (c); \draw[-latex] (c) -- (a); \draw[-latex] (c) -- (d); \node[fit=(a)(c), rounded rectangle, draw, inner sep=10pt,save spath=fit] {}; \fill[white,fill opacity=.75,restore spath=fit] (current bounding box.north west) rectangle (current bounding box.south east); \end{tikzpicture} \end{document}

enter image description here

Note : The inconvenient is that half of the fit node line is dimmed.

Kpym
  • 23,002
  • 2
    To fix the line dimming, you could draw the node border afterwards. That is, remove the draw from the \node command and put a \draw[restore spath=fit]; after the last \fill command. – Andrew Stacey Apr 24 '18 at 20:48
4

Just for completeness, another solution which use show path construction decoration, in place of spath3, to save a high level presentation of the path in a global macro \savedtikzpath.

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{fit,shapes.misc}
\usetikzlibrary{decorations.pathreplacing}
\tikzset{
  append tikz path/.style = {
    decoration={show path construction,
      moveto code={
        \xdef\savedtikzpath{\savedtikzpath (\tikzinputsegmentfirst)}
      },
      lineto code={
        \xdef\savedtikzpath{\savedtikzpath -- (\tikzinputsegmentlast)}
      },
      curveto code={
        \xdef\savedtikzpath{\savedtikzpath .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) ..(\tikzinputsegmentlast)}
      },
      closepath code={
        \xdef\savedtikzpath{\savedtikzpath -- cycle}
      }
    },
    decorate
  },
  save tikz path/.style = {append tikz path},
  save tikz path/.prefix code={\xdef\savedtikzpath{}}
}

\begin{document}
  \begin{tikzpicture}[
      mybox/.style={fill=#1!30,draw=#1,rounded corners}
    ]
    \path (0,0) node[mybox=green](a) {A}
          (0,3) node[mybox=blue] (b) {B}
          (3,0) node[mybox=orange] (c) {C}
          (5,3) node[mybox=pink] (d) {D};
    \foreach \from/\to in {a/b,b/c,c/a,c/d}{
      \draw[-latex] (\from) -- (\to);
    }
    \node[fit=(a)(c), rounded rectangle, inner sep=10pt, save tikz path] {};
    \fill[white, fill opacity=.75] \savedtikzpath
      (current bounding box.north west) rectangle (current bounding box.south east);
    \draw \savedtikzpath;
  \end{tikzpicture}
\end{document}

enter image description here

Kpym
  • 23,002