# Clipping issue with TikZ fading

Following Issue with fade-no-fill.sty, I wanted to try implementing @hpekristiansen solution. I’m giving a more complete code here because I have text nodes on the paths actually.

\documentclass[tikz]{standalone}

\begin{document}
\begin{tikzpicture}
\node [red,draw,thick,ellipse] (S) at (-3,0) {Solide};
\node [blue,draw,thick,ellipse] (L) at (3,0) {Liquide};
\node [green,draw,thick,ellipse] (G) at (0,{3*sqrt(3)}) {Gaz};
\end{tikzpicture}
\end{document}


Output (in a correct PDF viewer, see comments under https://tex.stackexchange.com/a/615816/56823) is as follow:

I have two issues with it:

1. Clipping on the horizontal line. @hpekristiansen mentionned this issue and a workaround (also in Fading arrows in TikZ), but actually clipping is not limited to the arrow : the text node also is clipped! I could of course also redraw it, but this is far from ideal. Note that using arrows.meta and substituting -latex for -Latex does not fixes the issue here (but is a fine change if required for a proper solution).
2. Fading on text nodes. I’ve tried adding path fading=none to the nodes options, but for no results. I can of course draw the text nodes separately, but again this is far from ideal.
• What happens if you put the main path fading in a preaction and don't draw the main path (either via draw=none or replace \draw by \path). For the arrowheads, there was a suggestion to use the ones from the arrows.meta library to get the right bounding box. You say that doesn't work, but you're talking about the nodes at the time, does it fix the arrowheads? Sep 19 at 9:50
• Using a preaction indeed works for the fading issue (though I apparently have to set thick again in the preaction). For the arrows head sorry, I should have been more precise: it does not solve the issue with the arrow head, but at this point I guess we’re just affected by tex.stackexchange.com/q/597927/8650. Sep 19 at 13:08
• But then note that using a preaction makes the workaround for redrawing the arrow head broken: everything else from the preaction seems discarded… Sep 19 at 13:17
• Of course I can then add a \path [preaction={decorate}, decoration={markings,mark=at position 1 with {\arrow[blue,thick]{latex}}}] (S) to (L);, but that’s a workaround again. Sep 19 at 13:24

I'm not sure how much of a "hack" this counts as, but as is often the case much of the hackery can be hidden in styles so that it doesn't feel too bad.

The two issues are addressed as follows:

1. So that the nodes are not affected by the fading, but are still defined on the relevant path, then the fading is implemented in two postactions (the choice of postaction is arbitrary - it could be two preactions, or one pre and one post). The path itself is not drawn. To make this a bit slicker, I've defined a style path bifading that takes two directions and two styles (in this, the styles are just colours but they could be more general).

2. To ensure that the arrowheads are visible, I define a key that extends the bounding box. Specifically, at the end of the path then this key simulates adding a point that is positioned at the point (-5pt,5pt) relative to the end of the path and rotated so that the x direction points along the path and the y direction is normal to the path. Note that this does not actually extend the path, it just extends the bounding box. The transformation to this coordinate system is achieved by way of my spath3 library.

\documentclass[tikz,border=10pt]{standalone}
%\url{https://tex.stackexchange.com/q/615945/86}
\usetikzlibrary{
shapes,
arrows.meta,
spath3
}

\tikzset{
postaction={
#3%
},
postaction={
#4%
}
},
#1,
spath/transform to={current}{1},
extend bounding box={(-5pt,5pt)}
}
}

\makeatletter
\tikzset{
extend bounding box/.code={%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\pgf@protocolsizes{\pgf@x}{\pgf@y}%
}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node [red,draw,thick,ellipse] (S) at (-3,0) {Solide};
\node [blue,draw,thick,ellipse] (L) at (3,0) {Liquide};
\node [green,draw,thick,ellipse] (G) at (0,{3*sqrt(3)}) {Gaz};
\path
(S) to[bend left] node [midway,above,sloped,black] {Sublimation} (G)
;
\path
(G) to[bend left] node [midway,above,sloped,black] {Liquéfaction} (L)
;
\path
(L) to[bend left] node [midway,below,sloped,black] {Solidification} (S)
;
\path
(S) to node [midway,above,sloped,black] {Fusion} (L)
;
\path
(L) to node [midway,below,sloped,black] {Vaporisation} (G)
;
\path
(G) to node [midway,below,sloped,black] {Condensation} (S)
;
\end{tikzpicture}
\end{document}


As @hpekristiansen suggests in the comments, the angle of the fading can be figured out from the path's endpoints. There's a bit of work to be done to make the path accessible in the postaction, but it's doable.

\documentclass[tikz,border=10pt]{standalone}
%\url{https://tex.stackexchange.com/q/615945/86}
\usetikzlibrary{
shapes,
decorations.markings,
arrows.meta,
spath3
}

\tikzset{
postaction={
spath/save action path,
extend bounding box,
#1%
},
postaction={
spath/save action path,
extend bounding box,
#2%
}
},
}

\makeatletter
\ExplSyntaxOn
\tikzset{
spath/save~ action~ path/.code={
\cs_set_eq:cN {\__tikzspath_path_name:n {action}} \tikz@actions@path
}
}
\ExplSyntaxOff

\tikzset{
extend bounding box/.code={%
\begingroup
\tikzset{spath/transform to={action}{1}}
\tikz@scan@one@point\pgfutil@firstofone(-5pt,5pt)\relax
\pgf@protocolsizes{\pgf@x}{\pgf@y}%
\endgroup
},
\tikz@scan@one@point\pgfutil@firstofone(spath cs:action 0)\relax
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\tikz@scan@one@point\pgfutil@firstofone(spath cs:action 1)\relax
\pgfmathsetmacro\fading@angle{atan2(\pgf@ya - \pgf@y, \pgf@xa - \pgf@x)}%
}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node [red,draw,thick,ellipse] (S) at (-3,0) {Solide};
\node [blue,draw,thick,ellipse] (L) at (3,0) {Liquide};
\node [green,draw,thick,ellipse] (G) at (0,{3*sqrt(3)}) {Gaz};
\path
[
-Latex,
]
(S) to[bend left] node [midway,above,sloped,black] {Sublimation} (G)
;
\path
[
-Latex,
]
(G) to[bend left] node [midway,above,sloped,black] {Liquéfaction} (L)
;
\path
[
-Latex,
]
(L) to[bend left] node [midway,below,sloped,black] {Solidification} (S)
;
\path
[
-Latex,
]
(S) to node [midway,above,sloped,black] {Fusion} (L)
;
\path
[
-Latex,
]
(L) to node [midway,below,sloped,black] {Vaporisation} (G)
;
\path
[
-Latex,
]
(G) to node [midway,below,sloped,black] {Condensation} (S)
;
\end{tikzpicture}
\end{document}


• +1 Instead of giving the path fading direction to bifading, you could rotate the fading automatically from the start and end point with atan2 see my bifade wheel here: tex.stackexchange.com/a/615806/8650 That would align the fading of the paths as wished in comment by @Archange: "Now I just need to figure out fading angle so that curved and straight lines fade are really aligned" Sep 19 at 22:52
• I've not much experience with fading so I was just sticking either what the OP had there, but automatically figuring out the Angles shouldn't be hard to integrate. I'll take a look later, thanks for the suggestion. Sep 20 at 5:53
• @hpekristiansen Done, see latest edit to my answer. Sep 20 at 21:42
• It looks great. -I hope there will be plenty of use cases in the future. Sep 21 at 3:47
• So the code grew quite significantly, but this is a quite clean solution in the end and with re-usability. Very nice addition for the computation of the fading angle, though it does not exactly achieve what I hoped for, that is the same colours at the same relative position along the arrow (see e.g. how “Solidification” gets to red faster than “Fusion”). Anyway, I’ve accepted this answer as I think this is the most future-proof way of solving the issue. Sep 21 at 20:59

Just for the record, here is my workaround solution:

\documentclass[tikz]{standalone}

\begin{document}
\begin{tikzpicture}
\node [red,draw,thick,ellipse] (S) at (-3,0) {Solide};
\node [blue,draw,thick,ellipse] (L) at (3,0) {Liquide};
\node [green,draw,thick,ellipse] (G) at (0,{3*sqrt(3)}) {Gaz};
\path (S) to[bend left] node [midway,above,sloped] {Sublimation} (G);
\path (G) to[bend left] node [midway,above,sloped] {Liquéfaction} (L);
\path (L) to[bend left] node [midway,below,sloped] {Solidification} (S);
\path (S) to node [midway,above,sloped] {Fusion} (L);
\path (L) to node [midway,below,sloped] {Vaporisation} (G);
\path (G) to node [midway,below,sloped] {Condensation} (S);
\end{tikzpicture}
\end{document}


And its (correct) output:

• Instead of using decorations.markings it is simpler with: \draw [thick,-latex,red,path fading=east,postaction={draw,blue,path fading=west}] ([yshift=5pt]S) -- (S) to (L); Sep 19 at 16:21
• @hpekristiansen Since I don’t like “magical values”, I’ve tried to understand what the 5pt does. And apparently, the answer is nothing and it’s not even necessary: a plain (S) -- (S) to (L) does the trick. What I don’t get is why and what this does (for me it’s just like a path in two steps, but the first one is nullified)… However, please note it shifts the gradient (whatever yshift value is, or even without), so not exactly an acceptable solution at this stage. Any additional idea to solve that? Sep 19 at 20:16
• OK, got it: it draw an invisible path because it’s under the node, the first (S) being interpreted as the node center instead of east. This explains the gradient shifting, but not how to solve it. Sep 19 at 20:26
• @hpekristiansen Then at this point we might have a different TeX installation, because it’s as I said, I’ve actually tested it. I can paste picture to show you if needed. Sep 19 at 20:29

Here is a solution that does not use decorations.markings

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\node [red,draw,thick,ellipse] (S) at (-3,0) {Solide};
\node [blue,draw,thick,ellipse] (L) at (3,0) {Liquide};
\node [green,draw,thick,ellipse] (G) at (0,{3*sqrt(3)}) {Gaz};
\path (S) to[bend left] node [midway,above,sloped] {Sublimation} (G);
\path (G) to[bend left] node [midway,above,sloped] {Liquéfaction} (L);
\path (L) to[bend left] node [midway,below,sloped] {Solidification} (S);
\path (S) to node [midway,above,sloped] {Fusion} (L);
\path (L) to node [midway,below,sloped] {Vaporisation} (G);
\path (G) to node [midway,below,sloped] {Condensation} (S);
\end{tikzpicture}
\end{document}


• So you don’t see that the gradient was shifted on the horizontal line? It does not start with the same red as the node, and is definitively not “aligned” with the curved line. Sep 19 at 20:32
• You are right - previous solution started the path at node center instead of east -corrected Sep 19 at 20:37
• Nice, and I see you’ve removed the -- part, I was surprised that worked (but is indeed necessary for the path not to be drawn), how is the serie of two nodes coordinates interpreted in this case? Sep 19 at 20:40
• It is just an extra point in the path (only there to expand the bounding box of path fading). \draw (0,0) -- (1,1) (2,2) -- (3,3); will draw two line segments. \draw (5,5); will not draw anything. See tex.stackexchange.com/questions/597927/fading-arrows-in-tikz - my workaround and @Symbol1 explanation. Sep 19 at 20:45
• Ah thanks, I had missed your edit in your workaround. So nice, together with @andrew-stacey hint I have a working and quite clean solution. :) Now I just need to figure out fading angle so that curved and straight lines fade are really aligned. ;) Sep 19 at 20:50