5

Consider the following MWE:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
\shade[top color=yellow,bottom color=green] (-2,0) to[out=-90,in=180] (0,-2) to[out=0,in=-90] (2,0) to[out=-90-35,in=0] (0,-.7) to[out=180,in=-55] (-2,0);
\end{tikzpicture}
\end{document}

whose output is

enter image description here

As you can see, the top color=yellow only affects the upper tips/vertices of the shape. I was expecting something of the form

enter image description here

where I apologise for the crappy paint job. In any case, I wanted the shading to follow the shape of the object: that the upper edge is yellow, the bottom one is green, and that the gradient affects the whole figure, and not only the upper vertices.

How can this be done (in TikZ)? It would be nice to understand the general case but, if it's not possible, the shape above suffices for my purposes.

6

The shades available are only radial or linear, but you can solve this using a clipped area and draw the shape many times shifted by some value in the y coordinate while the color is changed. Also you can use many clipped shapes to draw another elements outside if you put it in a scope.

RESULT:

enter image description here

MWE:

\documentclass[tikz,border=20pt]{standalone}
\begin{document}
    \begin{tikzpicture}

    \begin{scope}
    \clip
    (-2,0)
        to[out=-90,in=180] (0,-2)
        to[out=0,in=-90] (2,0)
        to[out=-90-35,in=0](0,-.7)
        to[out=180,in=-55] (-2,0);

    \foreach \x [evaluate=\x as \xn using {\x*4}] in {1,...,25} {
    \fill[green!\xn!yellow,yshift=2-\x]
    (-2,0)
        to[out=-90,in=180] (0,-2)
        to[out=0,in=-90] (2,0)
        to[out=-90-35,in=0](0,-.7)
        to[out=180,in=-55] (-2,0);
    }
    \end{scope}
    \shade[top color=yellow,bottom color=red](1,0) circle (0.2);
    \end{tikzpicture}
\end{document}
6

Welcome to TeX.SE! The answer is, AFAIK, that there is no predefined way of doing this. However, you can cheat and use some of the options that come with the shadings library together with clip to do something along the lines you are suggesting.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shadings}
\begin{document}
\begin{tikzpicture}
\clip (-2,0) to[out=-90,in=180] (0,-2) to[out=0,in=-90] (2,0) to[out=-90-35,in=0] (0,-.7) to[out=180,in=-55] (-2,0);
\shade[inner color=yellow,outer color=green] (-3,0.8) arc(180:360:3);
\end{tikzpicture}
\end{document}

enter image description here

I could not resist adding something more fancy based on cfr's fancy radial shading. This also is meant to illustrate how one can customize shading.

\documentclass[border=3.14mm,x11names,dvipsnames,svgnames]{standalone}
\usepackage{tikz}
\usetikzlibrary{shadings}
\pgfdeclareradialshading[fradialcolour1,fradialcolour2,fradialcolour3]{fncyradial}{\pgfpoint{0}{0}}{% manual 1082-1083; later - shading is assumed to be 100bp diameter ??
  color(0)=(fradialcolour1);
  color(20bp)=(fradialcolour2);
  color(40bp)=(fradialcolour3);
  color(50bp)=(fradialcolour3)
}
\tikzset{%
  fradial/.code={%
        \tikzset{%
          fancy radial/.cd,
          shading=fncyradial,
          #1
        }
  },
  fancy radial/.search also={/tikz},
  fancy radial/.cd,
  fancy radial inner colour/.code={
        \colorlet{fradialcolour1}{#1}
  },
  fancy radial mid colour/.code={
        \colorlet{fradialcolour2}{#1}
  },
  fancy radial outer colour/.code={
        \colorlet{fradialcolour3}{#1}
  },
  fancy radial inner colour=black,
  fancy radial outer colour=black,
  fancy radial mid colour=white,
  inner color/.style={
        fancy radial inner colour=#1,
  },
  outer color/.style={
        fancy radial outer colour=#1,
  },
  mid color/.style={
        fancy radial mid colour=#1,
  },
}
\begin{document}
\begin{tikzpicture}
\clip (-2,0) to[out=-90,in=180] (0,-2) to[out=0,in=-90] (2,0) to[out=-90-35,in=0] (0,-.7) to[out=180,in=-55] (-2,0);
\shade[fradial={inner color=yellow, outer color=green, mid color=yellow!70!green}] (-3,1) arc(180:360:3);
\end{tikzpicture}
\end{document}

enter image description here

And, of course, there are all the advanced options described in section 109 of the pgfmanual. In principle you could try to use \pgfsetadditionalshadetransform but this is major effort and also won't lead to a universal solution. I'd also like to mention that it seems nontrivial to implement nonlinear transformations here (see here). If this problem was not there, one may be able to construct a general solution in a similar way as the bending library works, i.e. define a nonlinear transformation from a path.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.