Skip to content
This repository has been archived by the owner on Apr 20, 2023. It is now read-only.

Commit

Permalink
Enhancements to PIE.Color: handle converting hsl and hsla color value…
Browse files Browse the repository at this point in the history
…s to equivalents recognizable by IE, and add a hexValue method which forces colors to 6-digit hex format (this is needed by the Glow filter as it only accepts full hex)
  • Loading branch information
Jason Johnston committed Jun 10, 2011
1 parent 5bfe984 commit 95737dd
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 15 deletions.
105 changes: 92 additions & 13 deletions sources/Color.js
Expand Up @@ -5,6 +5,44 @@
* @param {string} val The raw CSS string value for the color * @param {string} val The raw CSS string value for the color
*/ */
PIE.Color = (function() { PIE.Color = (function() {

/*
* hsl2rgb from http://codingforums.com/showthread.php?t=11156
* code by Jason Karl Davis (http://www.jasonkarldavis.com)
* swiped from cssSandpaper by Zoltan Hawryluk (http://www.useragentman.com/blog/csssandpaper-a-css3-javascript-library/)
* modified for formatting and size optimizations
*/
function hsl2rgb( h, s, l ) {
var m1, m2, r, g, b,
round = Math.round;
s /= 100;
l /= 100;
if ( !s ) { r = g = b = l * 255; }
else {
if ( l <= 0.5 ) { m2 = l * ( s + 1 ); }
else { m2 = l + s - l * s; }
m1 = l * 2 - m2;
h = ( h % 360 ) / 360;
r = hueToRgb( m1, m2, h + 1/3 );
g = hueToRgb( m1, m2, h );
b = hueToRgb( m1, m2, h - 1/3 );
}
return { r: round( r ), g: round( g ), b: round( b ) };
}
function hueToRgb( m1, m2, hue ) {
var v;
if ( hue < 0 ) { hue += 1; }
else if ( hue > 1 ) { hue -= 1; }
if ( 6 * hue < 1 ) { v = m1 + ( m2 - m1 ) * hue * 6; }
else if ( 2 * hue < 1 ) { v = m2; }
else if ( 3 * hue < 2 ) { v = m1 + ( m2 - m1 ) * ( 2/3 - hue ) * 6; }
else { v = m1; }
return 255 * v;
}




var instances = {}; var instances = {};


function Color( val ) { function Color( val ) {
Expand All @@ -15,7 +53,8 @@ PIE.Color = (function() {
* Regular expression for matching rgba colors and extracting their components * Regular expression for matching rgba colors and extracting their components
* @type {RegExp} * @type {RegExp}
*/ */
Color.rgbaRE = /\s*rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d+|\d*\.\d+)\s*\)\s*/; Color.rgbOrRgbaRE = /\s*rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(\d+|\d*\.\d+))?\s*\)\s*/;
Color.hslOrHslaRE = /\s*hsla?\(\s*(\d*\.?\d+)\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*(,\s*(\d+|\d*\.\d+))?\s*\)\s*/;


Color.names = { Color.names = {
"aliceblue":"F0F8FF", "antiquewhite":"FAEBD7", "aqua":"0FF", "aliceblue":"F0F8FF", "antiquewhite":"FAEBD7", "aqua":"0FF",
Expand Down Expand Up @@ -74,32 +113,72 @@ PIE.Color = (function() {
parse: function() { parse: function() {
if( !this._color ) { if( !this._color ) {
var me = this, var me = this,
v = me.val, color = me.val,
vLower, alpha, vLower, m, rgb;
m = v.match( Color.rgbaRE );
if( m ) { // RGB or RGBA colors
me._color = 'rgb(' + m[1] + ',' + m[2] + ',' + m[3] + ')'; if( m = color.match( Color.rgbOrRgbaRE ) ) {
me._alpha = parseFloat( m[4] ); color = me.rgbToHex( +m[1], +m[2], +m[3] );
alpha = ( 5 in m ) ? +m[5] : 1;
}
// HSL or HSLA colors
else if( m = color.match( Color.hslOrHslaRE ) ) {
rgb = hsl2rgb( m[1], m[2], m[3] );
color = me.rgbToHex( rgb.r, rgb.g, rgb.b );
alpha = ( 5 in m ) ? +m[5] : 1;
} }
else { else {
if( ( vLower = v.toLowerCase() ) in Color.names ) { if( Color.names.hasOwnProperty( vLower = color.toLowerCase() ) ) {
v = '#' + Color.names[vLower]; color = '#' + Color.names[vLower];
} }
me._color = v; alpha = ( color === 'transparent' ? 0 : 1 );
me._alpha = ( v === 'transparent' ? 0 : 1 );
} }
me._color = color;
me._alpha = alpha;
} }
}, },


/**
* Converts RGB color channels to a hex value string
*/
rgbToHex: function( r, g, b ) {
return '#' + ( r < 16 ? '0' : '' ) + r.toString( 16 ) +
( g < 16 ? '0' : '' ) + g.toString( 16 ) +
( b < 16 ? '0' : '' ) + b.toString( 16 );
},

/** /**
* Retrieve the value of the color in a format usable by IE natively. This will be the same as * Retrieve the value of the color in a format usable by IE natively. This will be the same as
* the raw input value, except for rgba values which will be converted to an rgb value. * the raw input value, except for rgb(a) and hsl(a) values which will be converted to a hex value.
* @param {Element} el The context element, used to get 'currentColor' keyword value. * @param {Element} el The context element, used to get 'currentColor' keyword value.
* @return {string} Color value * @return {string} Color value
*/ */
colorValue: function( el ) { colorValue: function( el ) {
this.parse(); this.parse();
return this._color === 'currentColor' ? el.currentStyle.color : this._color; return this._color === 'currentColor' ? PIE.getColor( el.currentStyle.color ).colorValue( el ) : this._color;
},

/**
* Retrieve the value of the color in a normalized six-digit hex format.
* @param el
*/
hexValue: function( el ) {
var color = this.colorValue( el );
// At this point the color should be either a 3- or 6-digit hex value, or the string "transparent".

function ch( i ) {
return color.charAt( i );
}

// Fudge transparent to black - should be ignored anyway since its alpha will be 0
if( color === 'transparent' ) {
color = '#000';
}
// Expand 3-digit to 6-digit hex
if( ch(0) === '#' && color.length === 4 ) {
color = '#' + ch(1) + ch(1) + ch(2) + ch(2) + ch(3) + ch(3);
}
return color;
}, },


/** /**
Expand Down
60 changes: 58 additions & 2 deletions tests/color-names.html
Expand Up @@ -4,6 +4,8 @@
<head> <head>
<title>Tests for background gradients</title> <title>Tests for background gradients</title>


<script type="text/javascript" src="../build/PIE_uncompressed.js"></script>

<style type="text/css"> <style type="text/css">


.test { .test {
Expand All @@ -14,17 +16,71 @@
border-radius: 10px; border-radius: 10px;
border: 3px solid; border: 3px solid;
margin: 5px; margin: 5px;
behavior: url(../build/PIE.htc);
} }


</style> </style>
</head> </head>
<body> <body>


<div style="display: none; color: red;" id="currentColorTester">tester for currentColor</div>

<script type="text/javascript"> <script type="text/javascript">
// Some simple unit tests of color parsing
var colorValueTests = {
'aqua': '#0FF',
'beige': '#F5F5DC',
'#123456': '#123456',
'#123': '#123',
'rgb(0, 0, 255)': '#0000ff',
'rgba(0, 0, 255, 0.5)': '#0000ff',
'rgba(0, 0, 255, .5)': '#0000ff',
'hsl(0, 100%, 50%)': '#ff0000',
'hsla(0, 100%, 50%, 0.5)': '#ff0000',
'hsla(0, 100%, 50%, .5)': '#ff0000',
'currentColor': '#F00',
'transparent': 'transparent'
},
hexValueTests = {
'aqua': '#00FFFF',
'beige': '#F5F5DC',
'#123456': '#123456',
'#123': '#112233',
'rgb(0, 0, 255)': '#0000ff',
'rgba(0, 0, 255, 0.5)': '#0000ff',
'rgba(0, 0, 255, .5)': '#0000ff',
'hsl(0, 100%, 50%)': '#ff0000',
'hsla(0, 100%, 50%, 0.5)': '#ff0000',
'hsla(0, 100%, 50%, .5)': '#ff0000',
'currentColor': '#FF0000',
'transparent': '#000000'
},
currentColorTester = document.getElementById('currentColorTester'),
failed = false,
c, val;
for (c in colorValueTests) {
val = PIE.getColor( c ).colorValue( currentColorTester );
if ( val !== colorValueTests[ c ] ) {
document.write('<p style="color:red">PIE.Color#colorValue() failed for "' + c + '": got "' + val + '", expected "' + colorValueTests[c] + '"</p>')
failed = true;
}
}
for (c in hexValueTests) {
val = PIE.getColor( c ).hexValue( currentColorTester );
if ( val !== hexValueTests[ c ] ) {
document.write('<p style="color:red">PIE.Color#hexValue() failed for "' + c + '": got "' + val + '", expected "' + hexValueTests[c] + '"</p>')
failed = true;
}
}
if (!failed) {
document.write('<p style="color:#090">Color parsing tests all passed</p>')
}


// Visual test of color names
var colors = ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumauqamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen"]; var colors = ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumauqamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen"];
for( var i=0, len=colors.length; i < len; i++ ) { for( var i=0, len=colors.length; i < len; i++ ) {
document.write('<div class="test" style="border-color:' + colors[i] + ';">' + colors[i] + '</div>'); document.write('<div class="test" id="test' + i + '" style="border-color:' + colors[i] + ';">' + colors[i] + '</div>');
PIE.attach( document.getElementById('test' + i) );
} }
</script> </script>


Expand Down

0 comments on commit 95737dd

Please sign in to comment.