1

I'm trying to define rainbow-color to use with only one letter. I did some digging. It is possible to give different color each letter ofcource. But here is what i intend to do:

letter1

letter2

I'm sorry about that i don't have any trial code. I look everywhere, yet i don't know where to begin. Can you help?

5

Collecting from some other questions: Making a strechable shading and How to shade a text

We can define a strechable rainbow shading and apply it to a text:

enter image description here

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{fadings, shadings}
\newcounter{fadcnt}\setcounter{fadcnt}{0}
\newcommand\fadingtext[3][]{%
\stepcounter{fadcnt}
  \begin{tikzfadingfrompicture}[name=fading letter\thefadcnt]
    \node[text=transparent!0,inner xsep=0pt,outer xsep=0pt,#1] {#3};
  \end{tikzfadingfrompicture}%
  \begin{tikzpicture}[baseline=(textnode.base)]
    \node[inner sep=0pt,outer sep=0pt,#1](textnode){\phantom{#3}}; 
    \shade[path fading=fading letter\thefadcnt,#2,fit fading=false]
    (textnode.south west) rectangle (textnode.north east);% 
  \end{tikzpicture}% 
}
\usetikzlibrary{calc}
\newbox\shbox
\tikzset{%
  path picture shading/.style={%
  path picture={%
%
\pgfpointdiff{\pgfpointanchor{path picture bounding box}{south west}}%
  {\pgfpointanchor{path picture bounding box}{north east}}%
\pgfgetlastxy\pathwidth\pathheight%
\pgfinterruptpicture%
   \global\setbox\shbox=\hbox{\pgfuseshading{#1}}%
 \endpgfinterruptpicture%
\pgftransformshift{\pgfpointanchor{path picture bounding box}{center}}%
\pgftransformxscale{\pathwidth/(\wd\shbox)}%
\pgftransformyscale{\pathheight/(\ht\shbox)}% \dp will (should) be 0pt
\pgftext{\box\shbox}%
%
    }
  }
}
\pgfdeclarehorizontalshading{rainbow}{10bp}{color(0bp)=(violet);
            color(1.6667bp)=(blue);
            color(3.3333bp)=(cyan);
            color(5bp)=(green);
            color(6.6667bp)=(yellow);
            color(8.3333bp)=(orange);
            color(10bp)=(red)}
\begin{document} 
 \fadingtext[scale=10, font=\bfseries]{upper left=red, upper right=green, lower left=blue,lower right=yellow}{\LaTeX}

\fadingtext[scale=10, font=\bfseries]{path picture shading=rainbow}{\LaTeX}

\fadingtext[scale=10, font=\bfseries]{path picture shading=rainbow}{X}
\end{document}
  • (+1, of course) If you make the shading 100bp by 100bp, you can define it so that it behaves in the same way as the standard shadings. In the linked question, that's not what is wanted. But perhaps it would be better here? Not sure about this - you can compare my answer below. – cfr Dec 18 '16 at 14:33
  • Actually I first tried that but I didn't think the shading was being correctly scaled. Then I used the solution I linked and the shading was way better. Try to change the values to be 100bp and compile using path picture shading and just shading, you'll see that the X's are very different. (maybe I screwed up somewhere else, but if so I don't know where :/) – Guilherme Zanotelli Dec 18 '16 at 19:36
  • It works for me, as you see. But you have to remember only the middle third is going to be shown. It is very confusing at first, but it does work once you get used to it and then you can use custom shadings in the usual way, just as you use the predefined ones. – cfr Dec 18 '16 at 21:25
  • So you would want, say, violet at 0bp and 25bp and red at 75bp and 100bp, with the transition points spread between 25bp and 75bp. – cfr Dec 18 '16 at 21:27
  • "Only the middle third is going to be shown" << Where did you get this invaluable piece of info?? That's why my borders were all wrong, I thought it was because the shading was not streching... Thank you so much!! – Guilherme Zanotelli Dec 19 '16 at 7:26
4

If you make a shading 100bp square (or 100bp radius for a radial shading) and bear in mind (for a horizontal or vertical shading) that only the ninth of the area in the middle square will be visible (at most), then the shading will scale as expected. That is, it will scale in the way regular predefined shadings scale. It is, therefore, always best to specify 100bp for the width/height and arrange the colours to cover a height/width of 100bp.

I define 2 shadings of this kind, rainbow and rainbow steps. The latter uses the colours for discrete stripes. The former is a 'real' shading.

I then define 26 fadings, my <capital letter>, for each <capital letter> of the English alphabet.

These shadings and fadings may be used within tikzpictures. For example:

\begin{tikzpicture}
  \shade [shading=rainbow] (1,-1) rectangle (8,-2);
  \shade [shading=rainbow steps] (1,-1) rectangle (8,0);
  \shade [shading=rainbow, shading angle=90] (1,0) rectangle (3,2);
  \shade [shading=rainbow steps, shading angle=90] (6,0) rectangle (8,2);
  \shade [shading=rainbow, shading angle=-90] (3,1) rectangle (6,2);
  \shade [shading=rainbow, shading angle=90, path fading=my Y, fit fading=true] (4.5,.25) rectangle (5,.75);
  \shade [shading=rainbow steps, shading angle=-90, path fading=my X, fit fading=true] (4,.25) rectangle (4.5,.75);
\end{tikzpicture}

rainbow variations

Finally, I define 2 new commands

\rainbowletter(<dimension>)[<tikz keys>]{<capital letter>}
\rainbowletter*(<dimension>)[<tikz keys>]{<capital letter>}

Each takes 2 optional arguments and one mandatory one. The first optional argument, if specified, should be a dimension or a number TikZ can understand as a dimension e.g. 0.78 or 10pt. The resulting letter will be in a square box with sides of this length. The second optional argument, if specified, may specify TikZ keys for the background \path used to create the letter. These may be used to fill the background or to change the shading angle for the rainbow.

The starred form uses the discrete stripes. The non-starred form uses the regular shading.

So,

\rainbowletter(.75)[inner color=white, outer color=black, shading angle=-90]{Y}

will use a box 7.5mm by 7.5mm, with a background shading which is white in the centre and black at the edges. It will use the standard rainbow shading, but will rotate it through -90 degrees. It will produce a rainbow Y.

rainbow Y

\rainbowletter*(1){A}

This will use discrete stripes in a size equivalent to the default 1 (i.e. 10mm square) with an A and nothing else.

rainbow A

\rainbowletter[top color=black, bottom color=black, middle color=white, shading angle=90,]{X}

This will give us a shaded background with black on the left and right, white in the middle, and rainbow shading rotated through 90 degrees.

rainbow X

Note that shading angle affects the background shading, too, so we use top and bottom to get left and right.

Complete code:

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{fadings}
\usepackage{xparse}
\pgfdeclarehorizontalshading{rainbow}{100bp}{%
  rgb(0bp)=(1,0,0);
  rgb(26bp)=(1,0,0);
  rgb(33bp)=(1,.5,0);
  rgb(40bp)=(1,1,0);
  rgb(47bp)=(0,1,0);
  rgb(54bp)=(0,1,1);
  rgb(61bp)=(0,0,1);
  rgb(68bp)=(1,0,1);
  rgb(75bp)=(.5,0,.5);
  rgb(100bp)=(.5,0,.5)}
\pgfdeclarehorizontalshading{rainbow steps}{100bp}{%
  rgb(0bp)=(1,0,0);
  rgb(32.1bp)=(1,0,0);
  rgb(32.1bp)=(1,.5,0);
  rgb(39.2bp)=(1,.5,0);
  rgb(39.2bp)=(1,1,0);
  rgb(46.4bp)=(1,1,0);
  rgb(46.4bp)=(0,1,0);
  rgb(53.5bp)=(0,1,0);
  rgb(53.5bp)=(0,1,1);
  rgb(60.7bp)=(0,1,1);
  rgb(60.7bp)=(0,0,1);
  rgb(67.9bp)=(0,0,1);
  rgb(67.9bp)=(.75,0,.75);
  rgb(100bp)=(.75,0,.75)}
\foreach \i in {A,B,...,Z}
{%
  \begin{tikzfadingfrompicture}[name=my \i]
    \node [text=transparent!0, inner sep=0pt, transform shape] {\fontfamily{Roboto-TLF}\fontsize{60pt}{60pt}\bfseries\selectfont \i};
  \end{tikzfadingfrompicture}%
}
\NewDocumentCommand \rainbowletter { s D() {1} O {} m }{%
  \IfBooleanTF{#1}{\def\tempa{rainbow steps}}{\def\tempa{rainbow}}%
  \tikz{%
    \path [#3, postaction={shading=\tempa, path fading=my #4, fit fading=true}] (0,0) rectangle (#2,#2);
  }%
}
\begin{document}
\rainbowletter(.75)[inner color=white, outer color=black, shading angle=-90]{Y}
\rainbowletter*(1){A}
\rainbowletter[top color=black, bottom color=black, middle color=white, shading angle=90,]{X}
\begin{tikzpicture}
  \shade [shading=rainbow] (1,-1) rectangle (8,-2);
  \shade [shading=rainbow steps] (1,-1) rectangle (8,0);
  \shade [shading=rainbow, shading angle=90] (1,0) rectangle (3,2);
  \shade [shading=rainbow steps, shading angle=90] (6,0) rectangle (8,2);
  \shade [shading=rainbow, shading angle=-90] (3,1) rectangle (6,2);
  \shade [shading=rainbow, shading angle=90, path fading=my Y, fit fading=true] (4.5,.25) rectangle (5,.75);
  \shade [shading=rainbow steps, shading angle=-90, path fading=my X, fit fading=true] (4,.25) rectangle (4.5,.75);
\end{tikzpicture}
\end{document}
  • @R.Schumacher Thank you. I think it is a bit specific for a package ;). – cfr Dec 18 '16 at 14:21

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.