Author image Noah Petherbridge
and 1 contributors


Color::Fade - Perl extension for fading text colors.


  use Color::Fade qw(color_fade format_color);

  print format_color ("html", color_fade (
    'Jackdaws love my big sphynx of quartz.',
    '#FF0000', '#00FF00', '#0000FF',


Color::Fade uses mathematical formulas to take an input string of virtually any length, and virtually any number of colors, and assign an individual color to each character to fade between each of the input colors.

In other words, it makes your sentences look really pretty. :)


Exports color_fade and format_color on demand.


color_fade ($string, @colors)

Fade $string among the colors in @colors, where $string is a string of length greater than zero, and @colors is an array of colors in six byte hexadecimal format, with or without the leading octothorpe. @colors must have at least two elements.

When called in array context, the method returns an array in which each element is of the format:

  <color #xxxxxx>y

For each character, where xxxxxx is a hexadecimal color code and y is one character from the original string.

When called in scalar context, this array is joined before being returned.

Note: It is perfectly possible to have more colors than you have characters in the original string. All that will happen is that each character of output will have a color from the original array, in the order the array was passed in, until there are no characters left.

Debug mode: To activate debug mode, set the global variable $Color::Fade::debug to a true value.

format_color ($format,@codes)

Formats the color data for display. $format is a format to use and @colors is the array you got from color_fade(). $format can either be a format or a built-in name of a predefined format. If given as a format, use the placeholders $color and $char as literals.

The pre-defined formats are:

  html   <font color="$color">$char</font>
  ubb    [color=$color]$char[/color]
  css    <span style="color: $color">$char</span>

Some examples:

  # Get an array of color codes.
  my @codes = color_fade ("Hello, world!", '#FF0000', '#0000FF');

  # Format it for HTML using the built-in format.
  my $html = format_color ('html', @codes);

  # Format it for AOL IM (meaning: no </font> tags allowed, as these mess
  # up the whole format of the IM message, at least as of AIM 5.9)
  my $aim = format_color ('<font color="$color">$char', @codes);

Having said that, the previous methods format_html, format_ubb, format_css, and format_aim are now absolute.

average_colors ($color_a, $color_b) *Internal

This function is not exportable. Given two formatted hex colors (6 bytes and no # symbol), it returns the hex code of the color directly in between them (or, the average of 2). See "BUG TRACKER".


Cuvou's Text Fader, an online implementation of this module.


  0.02  Aug  1 2008
  - Major bugfix: If the input string was so massive and not enough colors were
    sent in with it, the length of a given segment of the string might've been
    greater than 255, meaning that the delta of a RGB value against the length
    of the segment would be a number less than 1. Long story short, the fading
    would fail miserably. This has been fixed by detecting segment lengths higher
    than 128 characters, and looping through the provided colors and adding more
    to the list. So if the provide colors are red and yellow, it would make the
    list contain (red, orange, yellow), and then (red, orange-red, orange,
    yellow-orange, yellow), until the length of a segment divided by the new
    color selection is less than 128 characters. If you send something so massive
    that it fails to factor it down 100 times, it gives up and continues.
  - Minor bugfix: I was using oct() instead of hex() to convert hex into

  0.01  Jan 29 2007
  - Initial release.


Since this module was released in 2007, at least one large bug has been uncovered. This section of the POD is for describing this bug.

The bug was encountered on my web-based text fader tool. Going through the HTTP access logs I saw somebody format a very large chunk of text (or, the entire body of an "About Me" section for a MySpace profile). They initially faded it among 6 rainbow colors and then against shades of blue (white, blue, black). Both attempts looked terrible. Instead of actually fading the text from node to node, the color would remain constant until the next node was reached. On the white/blue/black one, 50% of the text was white and 50% was blue. The black node was at the end of the string and was therefore never applied entirely to any character.

The bug was a result of the length of a segment being 380 characters (or, the input length was 1142, divided by 3 colors). The colors were extremes: white (FFFFFF), blue (0000FF), and black (000000). Therefore, the deltas between each node were 255 on at least one of the red, green, or blue colors. But since 380 is greater than 255, when it calculated how many shades it should move for each character, it calculated a number less than 1, which got inted down to zero. Thus, the first 380 characters were completely white, because it was trying to subtract 0 from 255 for each color -- which doesn't do anything. When the blue node hit, again, 255 / 380 ints down to zero.

The way I fixed the bug was by adding a check to see if the length of the segments is unreasonable. 255 is an extreme number which only affects extreme colors, so I programmed the module around the number 128. If the length of segments is greater than 128, it needs to add more colors to your provided array and try again. So, for each pair of colors in your array, it inserts a new color which is an average of the two around it. So if your initial array was this:

  FFFFFF (white)
  0000FF (blue)
  000000 (black)

It would add these in:

     FFFFFF (white)
  -> 8080FF (light blue)
     0000FF (blue)
  -> 000080 (dark blue)
     000000 (black)

If the new array of colors can't divide up your string so that the length of a segment is under 128 characters, it tries again. This process repeats until the segment length is less than 128, or until it has tried more than 100 times to factor it down. In the latter case, it stops trying and continues anyway, knowing that your result won't look exactly how you expected it to.

Thus I've added average_colors for calculating the average of two colors.


Casey Kirsle, <casey at>


Copyright (C) 2008 by Casey Kirsle

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.