Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>An aside: RGB is not a perceptually linear color space. I recommend converting from RGB to HSL, interpolating, then converting back to RGB. I wrote the following PHP code to generate arbitrary perceptually-correct gradients; I suggest turning it into a service which can then be called from PHP or AJAX at need.</p> <p>You can get your final hex output as</p> <pre><code>$hexcol = col2string( RGBinterpolate("#ececec", "#ffffff", 0.5) ); // "#f4f4f4" </code></pre> <p>The code:</p> <pre><code>// Input: // $start as RGB color string, // $end as RGB color string, // $dist as float in [0.0 .. 1.0] being % distance between start and end colors // Output: // array(int, int, int) being the resulting color in RGB) function RGBinterpolate( $start, $end, $dist ) { $hsl_start = rgb2hsl( getCol($start) ); $hsl_end = rgb2hsl( getCol($end) ); // choose the shorter arc of the hue wheel! if ($hsl_start[0] &gt; $hsl_end[0]) { if ($hsl_start[0] &gt; $hsl_end[0] + 0.5) $hsl_start[0] -= 1.0; } else { if ($hsl_end[0] &gt; $hsl_start[0] + 0.5) $hsl_end[0] -= 1.0; } // do linear interpolation in hsl color space $hs = interp( $hsl_start[0], $hsl_end[0], $dist ); $ss = interp( $hsl_start[1], $hsl_end[1], $dist ); $ls = interp( $hsl_start[2], $hsl_end[2], $dist ); return hsl2rgb( array( $hs, $ss, $ls ) ); } // Input: start-value, end-value, % distance as float in [0.0 .. 1.0] // Output: result of interpolation as float function interp($start, $end, $dist) { return $start + ($end - $start)*$dist; } // Input: string in one of the following formats: // #XXXXXX (standard hex code as used in CSS) // 0xXXXXXX (same thing written as C longint) // #XXX (equivalent to each-digit-doubled, ie #abc is #aabbcc) // 000, 000, 000 (decimal triad, each value in 0..255) // colorname (Netscape defined color names) // Output: array(int, int, int) for legal values, else default value function getCol($str, $default=array(0,0,0)) { global $namedcolors; // convert named color to #xxxxxx code if( isset($namedcolors[$str]) ) $str = $namedcolors[$str]; // turn named color into a hex value $str = trim($str); // remove leading and trailing whitespace $hex = "[0-9a-z]"; // attempt to match #XXXXXX $pat = "/(#)($hex{2})($hex{2})($hex{2})/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = hexdec($arr[2]); $g = hexdec($arr[3]); $b = hexdec($arr[4]); return array($r, $g, $b); } // attempt to match 0xXXXXXX $pat = "/(0x)($hex{2})($hex{2})($hex{2})/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = hexdec($arr[2]); $g = hexdec($arr[3]); $b = hexdec($arr[4]); return array($r, $g, $b); } // attempt to match #XXX $pat = "/(#)($hex)($hex)($hex)/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = hexdec($arr[2]) * 17; $g = hexdec($arr[3]) * 17; $b = hexdec($arr[4]) * 17; return array($r, $g, $b); } // attempt to match int, int, int $pat = "/(\d{1,3})\\s*,\\s*(\d{1,3})\\s*,\\s*(\d{1,3})/i"; if ((preg_match($pat, $str, $arr)) == 1) { $r = 0 + $arr[2]; // implicit cast to int - make explicit? $g = 0 + $arr[3]; $b = 0 + $arr[4]; return array($r, $g, $b); } // if none of the above worked, return default value return $default; } // Input: array(int,int,int) being RGB color in { [0..255], [0..255], [0..255] } // Output array(float,float,float) being HSL color in { [0.0 .. 1.0), [0.0 .. 1.0), [0.0 .. 1.0) } function rgb2hsl($rgbtrio) { $r = $rgbtrio[0] / 256.0; // Normalize {r,g,b} to [0.0 .. 1.0) $g = $rgbtrio[1] / 256.0; $b = $rgbtrio[2] / 256.0; $h = 0.0; $s = 0.0; $L = 0.0; $min = min($r, $g, $b); $max = max($r, $g, $b); $delta = $max - $min; $L = 0.5 * ( $max + $min ); if ( $delta &lt; 0.001 ) // This is a gray, no chroma... { $h = 0.0; // ergo, hue and saturation are meaningless $s = 0.0; } else // Chromatic data... { if ( $L &lt; 0.5 ) $s = ($max - $min) / ( $max + $min ); else $s = ($max - $min) / ( 2 - $max - $min ); $dr = ( (($max - $r) / 6.0) + ($max / 2.0) ) / $max; $dg = ( (($max - $g) / 6.0) + ($max / 2.0) ) / $max; $db = ( (($max - $b) / 6.0) + ($max / 2.0) ) / $max; if ($r == $max) $h = $db - $dg; elseif ($g == $max) $h = (0.3333) + $dr - $db; elseif ($b == $max) $h = (0.6666) + $dg - $dr; if ( $h &lt; 0.0 ) $h += 1.0; if ( $h &gt; 1.0 ) $h -= 1.0; } return array($h, $s, $L); } function Hue_2_RGB( $v1, $v2, $vH ) { $v1 = 0.0+$v1; $v2 = 0.0+$v2; $vH = 0.0+$vH; if ( $vH &lt; 0.0 ) $vH += 1.0; elseif ( $vH &gt;= 1.0 ) $vH -= 1.0; // 0.0 &lt;= vH &lt; 1.0 if ( $vH &lt; 0.1667 ) return ( $v1 + 6.0*$vH*($v2 - $v1) ); elseif ( $vH &lt; 0.5 ) return ( $v2 ); elseif ( $vH &lt; 0.6667 ) return ( $v1 + (4.0-(6.0*$vH ))*($v2 - $v1) ); else return ( $v1 ); } // Input: array(float,float,float) being HSL color in { [0.0 .. 1.0), [0.0 .. 1.0), [0.0 .. 1.0) } // Output: array(int,int,int) being RGB color in { [0..255], [0..255], [0..255] } function hsl2rgb($hsltrio) { $h = $hsltrio[0]; $s = $hsltrio[1]; $L = $hsltrio[2]; if ( $s &lt; 0.001 ) //HSL from 0 to 1 { $r = $L; $g = $L; $b = $L; } else { if ( $L &lt; 0.5 ) $j = $L * ( 1.0 + $s ); else $j = ($L + $s) - ($s * $L); $i = (2.0 * $L) - $j; $r = Hue_2_RGB( $i, $j, $h + 0.3333 ); $g = Hue_2_RGB( $i, $j, $h ); $b = Hue_2_RGB( $i, $j, $h - 0.3333 ); } return array( floor(256.0 * $r), floor(256.0 * $g), floor(256.0 * $b) ); } function col2string($rgbtrio) { global $colornames; $r = floor( $rgbtrio[0] ); $g = floor( $rgbtrio[1] ); $b = floor( $rgbtrio[2] ); $str = sprintf("#%02x%02x%02x", $r, $g, $b); if( isset($colornames[$str]) ) return $colornames[$str]; else return $str; } // All Netscape named colors $namedcolors = array( "aliceblue" =&gt; "#f0f8ff", "antiquewhite" =&gt; "#faebd7", "aqua" =&gt; "#00ffff", "aquamarine" =&gt; "#7fffd4", "azure" =&gt; "#f0ffff", "beige" =&gt; "#f5f5dc", "bisque" =&gt; "#ffe4c4", "black" =&gt; "#000000", "blanchedalmond" =&gt; "#ffebcd", "blue" =&gt; "#0000ff", "blueviolet" =&gt; "#8a2be2", "brown" =&gt; "#a52a2a", "burlywood" =&gt; "#deb887", "cadetblue" =&gt; "#5f9ea0", "chartreuse" =&gt; "#7fff00", "chocolate" =&gt; "#d2691e", "coral" =&gt; "#ff7f50", "cornflowerblue" =&gt; "#6495ed", "cornsilk" =&gt; "#fff8dc", "crimson" =&gt; "#dc143c", "cyan" =&gt; "#00ffff", "darkblue" =&gt; "#00008b", "darkcyan" =&gt; "#008b8b", "darkgoldenrod" =&gt; "#b8860b", "darkgray" =&gt; "#a9a9a9", "darkgreen" =&gt; "#006400", "darkgrey" =&gt; "#a9a9a9", "darkkhaki" =&gt; "#bdb76b", "darkmagenta" =&gt; "#8b008b", "darkolivegreen" =&gt; "#556b2f", "darkorange" =&gt; "#ff8c00", "darkorchid" =&gt; "#9932cc", "darkred" =&gt; "#8b0000", "darksalmon" =&gt; "#e9967a", "darkseagreen" =&gt; "#8fbc8f", "darkslateblue" =&gt; "#483d8b", "darkslategray" =&gt; "#2f4f4f", "darkslategrey" =&gt; "#2f4f4f", "darkturquoise" =&gt; "#00ced1", "darkviolet" =&gt; "#9400d3", "deeppink" =&gt; "#ff1493", "deepskyblue" =&gt; "#00bfff", "dimgray" =&gt; "#696969", "dimgrey" =&gt; "#696969", "dodgerblue" =&gt; "#1e90ff", "firebrick" =&gt; "#b22222", "floralwhite" =&gt; "#fffaf0", "forestgreen" =&gt; "#228b22", "fuchsia" =&gt; "#ff00ff", "gainsboro" =&gt; "#dcdcdc", "ghostwhite" =&gt; "#f8f8ff", "gold" =&gt; "#ffd700", "goldenrod" =&gt; "#daa520", "gray" =&gt; "#808080", "green" =&gt; "#008000", "greenyellow" =&gt; "#adff2f", "grey" =&gt; "#808080", "honeydew" =&gt; "#f0fff0", "hotpink" =&gt; "#ff69b4", "indianred" =&gt; "#cd5c5c", "indigo" =&gt; "#4b0082", "ivory" =&gt; "#fffff0", "khaki" =&gt; "#f0e68c", "lavender" =&gt; "#e6e6fa", "lavenderblush" =&gt; "#fff0f5", "lawngreen" =&gt; "#7cfc00", "lemonchiffon" =&gt; "#fffacd", "lightblue" =&gt; "#add8e6", "lightcoral" =&gt; "#f08080", "lightcyan" =&gt; "#e0ffff", "lightgoldenrodyellow" =&gt; "#fafad2", "lightgray" =&gt; "#d3d3d3", "lightgreen" =&gt; "#90ee90", "lightgrey" =&gt; "#d3d3d3", "lightpink" =&gt; "#ffb6c1", "lightsalmon" =&gt; "#ffa07a", "lightseagreen" =&gt; "#20b2aa", "lightskyblue" =&gt; "#87cefa", "lightslategray" =&gt; "#778899", "lightslategrey" =&gt; "#778899", "lightsteelblue" =&gt; "#b0c4de", "lightyellow" =&gt; "#ffffe0", "lime" =&gt; "#00ff00", "limegreen" =&gt; "#32cd32", "linen" =&gt; "#faf0e6", "magenta" =&gt; "#ff00ff", "maroon" =&gt; "#800000", "mediumaquamarine" =&gt; "#66cdaa", "mediumblue" =&gt; "#0000cd", "mediumorchid" =&gt; "#ba55d3", "mediumpurple" =&gt; "#9370db", "mediumseagreen" =&gt; "#3cb371", "mediumslateblue" =&gt; "#7b68ee", "mediumspringgreen" =&gt; "#00fa9a", "mediumturquoise" =&gt; "#48d1cc", "mediumvioletred" =&gt; "#c71585", "midnightblue" =&gt; "#191970", "mintcream" =&gt; "#f5fffa", "mistyrose" =&gt; "#ffe4e1", "moccasin" =&gt; "#ffe4b5", "navajowhite" =&gt; "#ffdead", "navy" =&gt; "#000080", "oldlace" =&gt; "#fdf5e6", "olive" =&gt; "#808000", "olivedrab" =&gt; "#6b8e23", "orange" =&gt; "#ffa500", "orangered" =&gt; "#ff4500", "orchid" =&gt; "#da70d6", "palegoldenrod" =&gt; "#eee8aa", "palegreen" =&gt; "#98fb98", "paleturquoise" =&gt; "#afeeee", "palevioletred" =&gt; "#db7093", "papayawhip" =&gt; "#ffefd5", "peachpuff" =&gt; "#ffdab9", "peru" =&gt; "#cd853f", "pink" =&gt; "#ffc0cb", "plum" =&gt; "#dda0dd", "powderblue" =&gt; "#b0e0e6", "purple" =&gt; "#800080", "red" =&gt; "#ff0000", "rosybrown" =&gt; "#bc8f8f", "royalblue" =&gt; "#4169e1", "saddlebrown" =&gt; "#8b4513", "salmon" =&gt; "#fa8072", "sandybrown" =&gt; "#f4a460", "seagreen" =&gt; "#2e8b57", "seashell" =&gt; "#fff5ee", "sienna" =&gt; "#a0522d", "silver" =&gt; "#c0c0c0", "skyblue" =&gt; "#87ceeb", "slateblue" =&gt; "#6a5acd", "slategray" =&gt; "#708090", "slategrey" =&gt; "#708090", "snow" =&gt; "#fffafa", "springgreen" =&gt; "#00ff7f", "steelblue" =&gt; "#4682b4", "tan" =&gt; "#d2b48c", "teal" =&gt; "#008080", "thistle" =&gt; "#d8bfd8", "tomato" =&gt; "#ff6347", "turquoise" =&gt; "#40e0d0", "violet" =&gt; "#ee82ee", "wheat" =&gt; "#f5deb3", "white" =&gt; "#ffffff", "whitesmoke" =&gt; "#f5f5f5", "yellow" =&gt; "#ffff00", "yellowgreen" =&gt; "#9acd32" ); $colornames = array_flip($namedcolors); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload