1 /*!2 * jQuery Color Animations v2.1.13 * https://github.com/jquery/jquery-color4 *5 * Copyright 2012 jQuery Foundation and other contributors6 * Released under the MIT license.7 * http://jquery.org/license8 *9 * Date: Sun Oct 28 15:08:06 2012 -040010 */11 (function( jQuery, undefined ) {1213 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",1415 // plusequals test for += 100 -= 10016 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,17 // a set of RE's that can match strings and generate color tuples.18 stringParsers = [{19 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,20 parse: function( execResult ) {21 return [22 execResult[ 1 ],23 execResult[ 2 ],24 execResult[ 3 ],25 execResult[ 4 ]26 ];27 }28 }, {29 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,30 parse: function( execResult ) {31 return [32 execResult[ 1 ] * 2.55,33 execResult[ 2 ] * 2.55,34 execResult[ 3 ] * 2.55,35 execResult[ 4 ]36 ];37 }38 }, {39 // this regex ignores A-F because it's compared against an already lowercased string40 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,41 parse: function( execResult ) {42 return [43 parseInt( execResult[ 1 ], 16 ),44 parseInt( execResult[ 2 ], 16 ),45 parseInt( execResult[ 3 ], 16 )46 ];47 }48 }, {49 // this regex ignores A-F because it's compared against an already lowercased string50 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,51 parse: function( execResult ) {52 return [53 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),54 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),55 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )56 ];57 }58 }, {59 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,60 space: "hsla",61 parse: function( execResult ) {62 return [63 execResult[ 1 ],64 execResult[ 2 ] / 100,65 execResult[ 3 ] / 100,66 execResult[ 4 ]67 ];68 }69 }],7071 // jQuery.Color( )72 color = jQuery.Color = function( color, green, blue, alpha ) {73 return new jQuery.Color.fn.parse( color, green, blue, alpha );74 },75 spaces = {76 rgba: {77 props: {78 red: {79 idx: 0,80 type: "byte"81 },82 green: {83 idx: 1,84 type: "byte"85 },86 blue: {87 idx: 2,88 type: "byte"89 }90 }91 },9293 hsla: {94 props: {95 hue: {96 idx: 0,97 type: "degrees"98 },99 saturation: {100 idx: 1,101 type: "percent"102 },103 lightness: {104 idx: 2,105 type: "percent"106 }107 }108 }109 },110 propTypes = {111 "byte": {112 floor: true,113 max: 255114 },115 "percent": {116 max: 1117 },118 "degrees": {119 mod: 360,120 floor: true121 }122 },123 support = color.support = {},124125 // element for support tests126 supportElem = jQuery( "<p>" )[ 0 ],127128 // colors = jQuery.Color.names129 colors,130131 // local aliases of functions called often132 each = jQuery.each;133134 // determine rgba support immediately135 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";136 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;137138 // define cache name and alpha properties139 // for rgba and hsla spaces140 each( spaces, function( spaceName, space ) {141 space.cache = "_" + spaceName;142 space.props.alpha = {143 idx: 3,144 type: "percent",145 def: 1146 };147 });148149 function clamp( value, prop, allowEmpty ) {150 var type = propTypes[ prop.type ] || {};151152 if ( value == null ) {153 return (allowEmpty || !prop.def) ? null : prop.def;154 }155156 // ~~ is an short way of doing floor for positive numbers157 value = type.floor ? ~~value : parseFloat( value );158159 // IE will pass in empty strings as value for alpha,160 // which will hit this case161 if ( isNaN( value ) ) {162 return prop.def;163 }164165 if ( type.mod ) {166 // we add mod before modding to make sure that negatives values167 // get converted properly: -10 -> 350168 return (value + type.mod) % type.mod;169 }170171 // for now all property types without mod have min and max172 return 0 > value ? 0 : type.max < value ? type.max : value;173 }174175 function stringParse( string ) {176 var inst = color(),177 rgba = inst._rgba = [];178179 string = string.toLowerCase();180181 each( stringParsers, function( i, parser ) {182 var parsed,183 match = parser.re.exec( string ),184 values = match && parser.parse( match ),185 spaceName = parser.space || "rgba";186187 if ( values ) {188 parsed = inst[ spaceName ]( values );189190 // if this was an rgba parse the assignment might happen twice191 // oh well....192 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];193 rgba = inst._rgba = parsed._rgba;194195 // exit each( stringParsers ) here because we matched196 return false;197 }198 });199200 // Found a stringParser that handled it201 if ( rgba.length ) {202203 // if this came from a parsed string, force "transparent" when alpha is 0204 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)205 if ( rgba.join() === "0,0,0,0" ) {206 jQuery.extend( rgba, colors.transparent );207 }208 return inst;209 }210211 // named colors212 return colors[ string ];213 }214215 color.fn = jQuery.extend( color.prototype, {216 parse: function( red, green, blue, alpha ) {217 if ( red === undefined ) {218 this._rgba = [ null, null, null, null ];219 return this;220 }221 if ( red.jquery || red.nodeType ) {222 red = jQuery( red ).css( green );223 green = undefined;224 }225226 var inst = this,227 type = jQuery.type( red ),228 rgba = this._rgba = [];229230 // more than 1 argument specified - assume ( red, green, blue, alpha )231 if ( green !== undefined ) {232 red = [ red, green, blue, alpha ];233 type = "array";234 }235236 if ( type === "string" ) {237 return this.parse( stringParse( red ) || colors._default );238 }239240 if ( type === "array" ) {241 each( spaces.rgba.props, function( key, prop ) {242 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );243 });244 return this;245 }246247 if ( type === "object" ) {248 if ( red instanceof color ) {249 each( spaces, function( spaceName, space ) {250 if ( red[ space.cache ] ) {251 inst[ space.cache ] = red[ space.cache ].slice();252 }253 });254 } else {255 each( spaces, function( spaceName, space ) {256 var cache = space.cache;257 each( space.props, function( key, prop ) {258259 // if the cache doesn't exist, and we know how to convert260 if ( !inst[ cache ] && space.to ) {261262 // if the value was null, we don't need to copy it263 // if the key was alpha, we don't need to copy it either264 if ( key === "alpha" || red[ key ] == null ) {265 return;266 }267 inst[ cache ] = space.to( inst._rgba );268 }269270 // this is the only case where we allow nulls for ALL properties.271 // call clamp with alwaysAllowEmpty272 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );273 });274275 // everything defined but alpha?276 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {277 // use the default of 1278 inst[ cache ][ 3 ] = 1;279 if ( space.from ) {280 inst._rgba = space.from( inst[ cache ] );281 }282 }283 });284 }285 return this;286 }287 },288 is: function( compare ) {289 var is = color( compare ),290 same = true,291 inst = this;292293 each( spaces, function( _, space ) {294 var localCache,295 isCache = is[ space.cache ];296 if (isCache) {297 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];298 each( space.props, function( _, prop ) {299 if ( isCache[ prop.idx ] != null ) {300 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );301 return same;302 }303 });304 }305 return same;306 });307 return same;308 },309 _space: function() {310 var used = [],311 inst = this;312 each( spaces, function( spaceName, space ) {313 if ( inst[ space.cache ] ) {314 used.push( spaceName );315 }316 });317 return used.pop();318 },319 transition: function( other, distance ) {320 var end = color( other ),321 spaceName = end._space(),322 space = spaces[ spaceName ],323 startColor = this.alpha() === 0 ? color( "transparent" ) : this,324 start = startColor[ space.cache ] || space.to( startColor._rgba ),325 result = start.slice();326327 end = end[ space.cache ];328 each( space.props, function( key, prop ) {329 var index = prop.idx,330 startValue = start[ index ],331 endValue = end[ index ],332 type = propTypes[ prop.type ] || {};333334 // if null, don't override start value335 if ( endValue === null ) {336 return;337 }338 // if null - use end339 if ( startValue === null ) {340 result[ index ] = endValue;341 } else {342 if ( type.mod ) {343 if ( endValue - startValue > type.mod / 2 ) {344 startValue += type.mod;345 } else if ( startValue - endValue > type.mod / 2 ) {346 startValue -= type.mod;347 }348 }349 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );350 }351 });352 return this[ spaceName ]( result );353 },354 blend: function( opaque ) {355 // if we are already opaque - return ourself356 if ( this._rgba[ 3 ] === 1 ) {357 return this;358 }359360 var rgb = this._rgba.slice(),361 a = rgb.pop(),362 blend = color( opaque )._rgba;363364 return color( jQuery.map( rgb, function( v, i ) {365 return ( 1 - a ) * blend[ i ] + a * v;366 }));367 },368 toRgbaString: function() {369 var prefix = "rgba(",370 rgba = jQuery.map( this._rgba, function( v, i ) {371 return v == null ? ( i > 2 ? 1 : 0 ) : v;372 });373374 if ( rgba[ 3 ] === 1 ) {375 rgba.pop();376 prefix = "rgb(";377 }378379 return prefix + rgba.join() + ")";380 },381 toHslaString: function() {382 var prefix = "hsla(",383 hsla = jQuery.map( this.hsla(), function( v, i ) {384 if ( v == null ) {385 v = i > 2 ? 1 : 0;386 }387388 // catch 1 and 2389 if ( i && i < 3 ) {390 v = Math.round( v * 100 ) + "%";391 }392 return v;393 });394395 if ( hsla[ 3 ] === 1 ) {396 hsla.pop();397 prefix = "hsl(";398 }399 return prefix + hsla.join() + ")";400 },401 toHexString: function( includeAlpha ) {402 var rgba = this._rgba.slice(),403 alpha = rgba.pop();404405 if ( includeAlpha ) {406 rgba.push( ~~( alpha * 255 ) );407 }408409 return "#" + jQuery.map( rgba, function( v ) {410411 // default to 0 when nulls exist412 v = ( v || 0 ).toString( 16 );413 return v.length === 1 ? "0" + v : v;414 }).join("");415 },416 toString: function() {417 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();418 }419 });420 color.fn.parse.prototype = color.fn;421422 // hsla conversions adapted from:423 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021424425 function hue2rgb( p, q, h ) {426 h = ( h + 1 ) % 1;427 if ( h * 6 < 1 ) {428 return p + (q - p) * h * 6;429 }430 if ( h * 2 < 1) {431 return q;432 }433 if ( h * 3 < 2 ) {434 return p + (q - p) * ((2/3) - h) * 6;435 }436 return p;437 }438439 spaces.hsla.to = function ( rgba ) {440 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {441 return [ null, null, null, rgba[ 3 ] ];442 }443 var r = rgba[ 0 ] / 255,444 g = rgba[ 1 ] / 255,445 b = rgba[ 2 ] / 255,446 a = rgba[ 3 ],447 max = Math.max( r, g, b ),448 min = Math.min( r, g, b ),449 diff = max - min,450 add = max + min,451 l = add * 0.5,452 h, s;453454 if ( min === max ) {455 h = 0;456 } else if ( r === max ) {457 h = ( 60 * ( g - b ) / diff ) + 360;458 } else if ( g === max ) {459 h = ( 60 * ( b - r ) / diff ) + 120;460 } else {461 h = ( 60 * ( r - g ) / diff ) + 240;462 }463464 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%465 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)466 if ( diff === 0 ) {467 s = 0;468 } else if ( l <= 0.5 ) {469 s = diff / add;470 } else {471 s = diff / ( 2 - add );472 }473 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];474 };475476 spaces.hsla.from = function ( hsla ) {477 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {478 return [ null, null, null, hsla[ 3 ] ];479 }480 var h = hsla[ 0 ] / 360,481 s = hsla[ 1 ],482 l = hsla[ 2 ],483 a = hsla[ 3 ],484 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,485 p = 2 * l - q;486487 return [488 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),489 Math.round( hue2rgb( p, q, h ) * 255 ),490 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),491 a492 ];493 };494495496 each( spaces, function( spaceName, space ) {497 var props = space.props,498 cache = space.cache,499 to = space.to,500 from = space.from;501502 // makes rgba() and hsla()503 color.fn[ spaceName ] = function( value ) {504505 // generate a cache for this space if it doesn't exist506 if ( to && !this[ cache ] ) {507 this[ cache ] = to( this._rgba );508 }509 if ( value === undefined ) {510 return this[ cache ].slice();511 }512513 var ret,514 type = jQuery.type( value ),515 arr = ( type === "array" || type === "object" ) ? value : arguments,516 local = this[ cache ].slice();517518 each( props, function( key, prop ) {519 var val = arr[ type === "object" ? key : prop.idx ];520 if ( val == null ) {521 val = local[ prop.idx ];522 }523 local[ prop.idx ] = clamp( val, prop );524 });525526 if ( from ) {527 ret = color( from( local ) );528 ret[ cache ] = local;529 return ret;530 } else {531 return color( local );532 }533 };534535 // makes red() green() blue() alpha() hue() saturation() lightness()536 each( props, function( key, prop ) {537 // alpha is included in more than one space538 if ( color.fn[ key ] ) {539 return;540 }541 color.fn[ key ] = function( value ) {542 var vtype = jQuery.type( value ),543 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),544 local = this[ fn ](),545 cur = local[ prop.idx ],546 match;547548 if ( vtype === "undefined" ) {549 return cur;550 }551552 if ( vtype === "function" ) {553 value = value.call( this, cur );554 vtype = jQuery.type( value );555 }556 if ( value == null && prop.empty ) {557 return this;558 }559 if ( vtype === "string" ) {560 match = rplusequals.exec( value );561 if ( match ) {562 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );563 }564 }565 local[ prop.idx ] = value;566 return this[ fn ]( local );567 };568 });569 });570571 // add cssHook and .fx.step function for each named hook.572 // accept a space separated string of properties573 color.hook = function( hook ) {574 var hooks = hook.split( " " );575 each( hooks, function( i, hook ) {576 jQuery.cssHooks[ hook ] = {577 set: function( elem, value ) {578 var parsed, curElem,579 backgroundColor = "";580581 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {582 value = color( parsed || value );583 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {584 curElem = hook === "backgroundColor" ? elem.parentNode : elem;585 while (586 (backgroundColor === "" || backgroundColor === "transparent") &&587 curElem && curElem.style588 ) {589 try {590 backgroundColor = jQuery.css( curElem, "backgroundColor" );591 curElem = curElem.parentNode;592 } catch ( e ) {593 }594 }595596 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?597 backgroundColor :598 "_default" );599 }600601 value = value.toRgbaString();602 }603 try {604 elem.style[ hook ] = value;605 } catch( e ) {606 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'607 }608 }609 };610 jQuery.fx.step[ hook ] = function( fx ) {611 if ( !fx.colorInit ) {612 fx.start = color( fx.elem, hook );613 fx.end = color( fx.end );614 fx.colorInit = true;615 }616 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );617 };618 });619620 };621622 color.hook( stepHooks );623624 jQuery.cssHooks.borderColor = {625 expand: function( value ) {626 var expanded = {};627628 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {629 expanded[ "border" + part + "Color" ] = value;630 });631 return expanded;632 }633 };634635 // Basic color names only.636 // Usage of any of the other color names requires adding yourself or including637 // jquery.color.svg-names.js.638 colors = jQuery.Color.names = {639 // 4.1. Basic color keywords640 aqua: "#00ffff",641 black: "#000000",642 blue: "#0000ff",643 fuchsia: "#ff00ff",644 gray: "#808080",645 green: "#008000",646 lime: "#00ff00",647 maroon: "#800000",648 navy: "#000080",649 olive: "#808000",650 purple: "#800080",651 red: "#ff0000",652 silver: "#c0c0c0",653 teal: "#008080",654 white: "#ffffff",655 yellow: "#ffff00",656657 // 4.2.3. ‘transparent’ color keyword658 transparent: [ null, null, null, 0 ],659660 _default: "#ffffff"661 };662663 })( jQuery );1 /*! 2 * jQuery Color Animations v2.1.1 3 * https://github.com/jquery/jquery-color 4 * 5 * Copyright 2012 jQuery Foundation and other contributors 6 * Released under the MIT license. 7 * http://jquery.org/license 8 * 9 * Date: Sun Oct 28 15:08:06 2012 -0400 10 */ 11 (function( jQuery, undefined ) { 12 13 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 14 15 // plusequals test for += 100 -= 100 16 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 17 // a set of RE's that can match strings and generate color tuples. 18 stringParsers = [{ 19 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 20 parse: function( execResult ) { 21 return [ 22 execResult[ 1 ], 23 execResult[ 2 ], 24 execResult[ 3 ], 25 execResult[ 4 ] 26 ]; 27 } 28 }, { 29 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 30 parse: function( execResult ) { 31 return [ 32 execResult[ 1 ] * 2.55, 33 execResult[ 2 ] * 2.55, 34 execResult[ 3 ] * 2.55, 35 execResult[ 4 ] 36 ]; 37 } 38 }, { 39 // this regex ignores A-F because it's compared against an already lowercased string 40 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 41 parse: function( execResult ) { 42 return [ 43 parseInt( execResult[ 1 ], 16 ), 44 parseInt( execResult[ 2 ], 16 ), 45 parseInt( execResult[ 3 ], 16 ) 46 ]; 47 } 48 }, { 49 // this regex ignores A-F because it's compared against an already lowercased string 50 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 51 parse: function( execResult ) { 52 return [ 53 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 54 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 55 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 56 ]; 57 } 58 }, { 59 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 60 space: "hsla", 61 parse: function( execResult ) { 62 return [ 63 execResult[ 1 ], 64 execResult[ 2 ] / 100, 65 execResult[ 3 ] / 100, 66 execResult[ 4 ] 67 ]; 68 } 69 }], 70 71 // jQuery.Color( ) 72 color = jQuery.Color = function( color, green, blue, alpha ) { 73 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 74 }, 75 spaces = { 76 rgba: { 77 props: { 78 red: { 79 idx: 0, 80 type: "byte" 81 }, 82 green: { 83 idx: 1, 84 type: "byte" 85 }, 86 blue: { 87 idx: 2, 88 type: "byte" 89 } 90 } 91 }, 92 93 hsla: { 94 props: { 95 hue: { 96 idx: 0, 97 type: "degrees" 98 }, 99 saturation: { 100 idx: 1, 101 type: "percent" 102 }, 103 lightness: { 104 idx: 2, 105 type: "percent" 106 } 107 } 108 } 109 }, 110 propTypes = { 111 "byte": { 112 floor: true, 113 max: 255 114 }, 115 "percent": { 116 max: 1 117 }, 118 "degrees": { 119 mod: 360, 120 floor: true 121 } 122 }, 123 support = color.support = {}, 124 125 // element for support tests 126 supportElem = jQuery( "<p>" )[ 0 ], 127 128 // colors = jQuery.Color.names 129 colors, 130 131 // local aliases of functions called often 132 each = jQuery.each; 133 134 // determine rgba support immediately 135 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 136 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 137 138 // define cache name and alpha properties 139 // for rgba and hsla spaces 140 each( spaces, function( spaceName, space ) { 141 space.cache = "_" + spaceName; 142 space.props.alpha = { 143 idx: 3, 144 type: "percent", 145 def: 1 146 }; 147 }); 148 149 function clamp( value, prop, allowEmpty ) { 150 var type = propTypes[ prop.type ] || {}; 151 152 if ( value == null ) { 153 return (allowEmpty || !prop.def) ? null : prop.def; 154 } 155 156 // ~~ is an short way of doing floor for positive numbers 157 value = type.floor ? ~~value : parseFloat( value ); 158 159 // IE will pass in empty strings as value for alpha, 160 // which will hit this case 161 if ( isNaN( value ) ) { 162 return prop.def; 163 } 164 165 if ( type.mod ) { 166 // we add mod before modding to make sure that negatives values 167 // get converted properly: -10 -> 350 168 return (value + type.mod) % type.mod; 169 } 170 171 // for now all property types without mod have min and max 172 return 0 > value ? 0 : type.max < value ? type.max : value; 173 } 174 175 function stringParse( string ) { 176 var inst = color(), 177 rgba = inst._rgba = []; 178 179 string = string.toLowerCase(); 180 181 each( stringParsers, function( i, parser ) { 182 var parsed, 183 match = parser.re.exec( string ), 184 values = match && parser.parse( match ), 185 spaceName = parser.space || "rgba"; 186 187 if ( values ) { 188 parsed = inst[ spaceName ]( values ); 189 190 // if this was an rgba parse the assignment might happen twice 191 // oh well.... 192 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 193 rgba = inst._rgba = parsed._rgba; 194 195 // exit each( stringParsers ) here because we matched 196 return false; 197 } 198 }); 199 200 // Found a stringParser that handled it 201 if ( rgba.length ) { 202 203 // if this came from a parsed string, force "transparent" when alpha is 0 204 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 205 if ( rgba.join() === "0,0,0,0" ) { 206 jQuery.extend( rgba, colors.transparent ); 207 } 208 return inst; 209 } 210 211 // named colors 212 return colors[ string ]; 213 } 214 215 color.fn = jQuery.extend( color.prototype, { 216 parse: function( red, green, blue, alpha ) { 217 if ( red === undefined ) { 218 this._rgba = [ null, null, null, null ]; 219 return this; 220 } 221 if ( red.jquery || red.nodeType ) { 222 red = jQuery( red ).css( green ); 223 green = undefined; 224 } 225 226 var inst = this, 227 type = jQuery.type( red ), 228 rgba = this._rgba = []; 229 230 // more than 1 argument specified - assume ( red, green, blue, alpha ) 231 if ( green !== undefined ) { 232 red = [ red, green, blue, alpha ]; 233 type = "array"; 234 } 235 236 if ( type === "string" ) { 237 return this.parse( stringParse( red ) || colors._default ); 238 } 239 240 if ( type === "array" ) { 241 each( spaces.rgba.props, function( key, prop ) { 242 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 243 }); 244 return this; 245 } 246 247 if ( type === "object" ) { 248 if ( red instanceof color ) { 249 each( spaces, function( spaceName, space ) { 250 if ( red[ space.cache ] ) { 251 inst[ space.cache ] = red[ space.cache ].slice(); 252 } 253 }); 254 } else { 255 each( spaces, function( spaceName, space ) { 256 var cache = space.cache; 257 each( space.props, function( key, prop ) { 258 259 // if the cache doesn't exist, and we know how to convert 260 if ( !inst[ cache ] && space.to ) { 261 262 // if the value was null, we don't need to copy it 263 // if the key was alpha, we don't need to copy it either 264 if ( key === "alpha" || red[ key ] == null ) { 265 return; 266 } 267 inst[ cache ] = space.to( inst._rgba ); 268 } 269 270 // this is the only case where we allow nulls for ALL properties. 271 // call clamp with alwaysAllowEmpty 272 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 273 }); 274 275 // everything defined but alpha? 276 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 277 // use the default of 1 278 inst[ cache ][ 3 ] = 1; 279 if ( space.from ) { 280 inst._rgba = space.from( inst[ cache ] ); 281 } 282 } 283 }); 284 } 285 return this; 286 } 287 }, 288 is: function( compare ) { 289 var is = color( compare ), 290 same = true, 291 inst = this; 292 293 each( spaces, function( _, space ) { 294 var localCache, 295 isCache = is[ space.cache ]; 296 if (isCache) { 297 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 298 each( space.props, function( _, prop ) { 299 if ( isCache[ prop.idx ] != null ) { 300 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 301 return same; 302 } 303 }); 304 } 305 return same; 306 }); 307 return same; 308 }, 309 _space: function() { 310 var used = [], 311 inst = this; 312 each( spaces, function( spaceName, space ) { 313 if ( inst[ space.cache ] ) { 314 used.push( spaceName ); 315 } 316 }); 317 return used.pop(); 318 }, 319 transition: function( other, distance ) { 320 var end = color( other ), 321 spaceName = end._space(), 322 space = spaces[ spaceName ], 323 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 324 start = startColor[ space.cache ] || space.to( startColor._rgba ), 325 result = start.slice(); 326 327 end = end[ space.cache ]; 328 each( space.props, function( key, prop ) { 329 var index = prop.idx, 330 startValue = start[ index ], 331 endValue = end[ index ], 332 type = propTypes[ prop.type ] || {}; 333 334 // if null, don't override start value 335 if ( endValue === null ) { 336 return; 337 } 338 // if null - use end 339 if ( startValue === null ) { 340 result[ index ] = endValue; 341 } else { 342 if ( type.mod ) { 343 if ( endValue - startValue > type.mod / 2 ) { 344 startValue += type.mod; 345 } else if ( startValue - endValue > type.mod / 2 ) { 346 startValue -= type.mod; 347 } 348 } 349 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 350 } 351 }); 352 return this[ spaceName ]( result ); 353 }, 354 blend: function( opaque ) { 355 // if we are already opaque - return ourself 356 if ( this._rgba[ 3 ] === 1 ) { 357 return this; 358 } 359 360 var rgb = this._rgba.slice(), 361 a = rgb.pop(), 362 blend = color( opaque )._rgba; 363 364 return color( jQuery.map( rgb, function( v, i ) { 365 return ( 1 - a ) * blend[ i ] + a * v; 366 })); 367 }, 368 toRgbaString: function() { 369 var prefix = "rgba(", 370 rgba = jQuery.map( this._rgba, function( v, i ) { 371 return v == null ? ( i > 2 ? 1 : 0 ) : v; 372 }); 373 374 if ( rgba[ 3 ] === 1 ) { 375 rgba.pop(); 376 prefix = "rgb("; 377 } 378 379 return prefix + rgba.join() + ")"; 380 }, 381 toHslaString: function() { 382 var prefix = "hsla(", 383 hsla = jQuery.map( this.hsla(), function( v, i ) { 384 if ( v == null ) { 385 v = i > 2 ? 1 : 0; 386 } 387 388 // catch 1 and 2 389 if ( i && i < 3 ) { 390 v = Math.round( v * 100 ) + "%"; 391 } 392 return v; 393 }); 394 395 if ( hsla[ 3 ] === 1 ) { 396 hsla.pop(); 397 prefix = "hsl("; 398 } 399 return prefix + hsla.join() + ")"; 400 }, 401 toHexString: function( includeAlpha ) { 402 var rgba = this._rgba.slice(), 403 alpha = rgba.pop(); 404 405 if ( includeAlpha ) { 406 rgba.push( ~~( alpha * 255 ) ); 407 } 408 409 return "#" + jQuery.map( rgba, function( v ) { 410 411 // default to 0 when nulls exist 412 v = ( v || 0 ).toString( 16 ); 413 return v.length === 1 ? "0" + v : v; 414 }).join(""); 415 }, 416 toString: function() { 417 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 418 } 419 }); 420 color.fn.parse.prototype = color.fn; 421 422 // hsla conversions adapted from: 423 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 424 425 function hue2rgb( p, q, h ) { 426 h = ( h + 1 ) % 1; 427 if ( h * 6 < 1 ) { 428 return p + (q - p) * h * 6; 429 } 430 if ( h * 2 < 1) { 431 return q; 432 } 433 if ( h * 3 < 2 ) { 434 return p + (q - p) * ((2/3) - h) * 6; 435 } 436 return p; 437 } 438 439 spaces.hsla.to = function ( rgba ) { 440 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 441 return [ null, null, null, rgba[ 3 ] ]; 442 } 443 var r = rgba[ 0 ] / 255, 444 g = rgba[ 1 ] / 255, 445 b = rgba[ 2 ] / 255, 446 a = rgba[ 3 ], 447 max = Math.max( r, g, b ), 448 min = Math.min( r, g, b ), 449 diff = max - min, 450 add = max + min, 451 l = add * 0.5, 452 h, s; 453 454 if ( min === max ) { 455 h = 0; 456 } else if ( r === max ) { 457 h = ( 60 * ( g - b ) / diff ) + 360; 458 } else if ( g === max ) { 459 h = ( 60 * ( b - r ) / diff ) + 120; 460 } else { 461 h = ( 60 * ( r - g ) / diff ) + 240; 462 } 463 464 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 465 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 466 if ( diff === 0 ) { 467 s = 0; 468 } else if ( l <= 0.5 ) { 469 s = diff / add; 470 } else { 471 s = diff / ( 2 - add ); 472 } 473 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 474 }; 475 476 spaces.hsla.from = function ( hsla ) { 477 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 478 return [ null, null, null, hsla[ 3 ] ]; 479 } 480 var h = hsla[ 0 ] / 360, 481 s = hsla[ 1 ], 482 l = hsla[ 2 ], 483 a = hsla[ 3 ], 484 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 485 p = 2 * l - q; 486 487 return [ 488 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 489 Math.round( hue2rgb( p, q, h ) * 255 ), 490 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 491 a 492 ]; 493 }; 494 495 496 each( spaces, function( spaceName, space ) { 497 var props = space.props, 498 cache = space.cache, 499 to = space.to, 500 from = space.from; 501 502 // makes rgba() and hsla() 503 color.fn[ spaceName ] = function( value ) { 504 505 // generate a cache for this space if it doesn't exist 506 if ( to && !this[ cache ] ) { 507 this[ cache ] = to( this._rgba ); 508 } 509 if ( value === undefined ) { 510 return this[ cache ].slice(); 511 } 512 513 var ret, 514 type = jQuery.type( value ), 515 arr = ( type === "array" || type === "object" ) ? value : arguments, 516 local = this[ cache ].slice(); 517 518 each( props, function( key, prop ) { 519 var val = arr[ type === "object" ? key : prop.idx ]; 520 if ( val == null ) { 521 val = local[ prop.idx ]; 522 } 523 local[ prop.idx ] = clamp( val, prop ); 524 }); 525 526 if ( from ) { 527 ret = color( from( local ) ); 528 ret[ cache ] = local; 529 return ret; 530 } else { 531 return color( local ); 532 } 533 }; 534 535 // makes red() green() blue() alpha() hue() saturation() lightness() 536 each( props, function( key, prop ) { 537 // alpha is included in more than one space 538 if ( color.fn[ key ] ) { 539 return; 540 } 541 color.fn[ key ] = function( value ) { 542 var vtype = jQuery.type( value ), 543 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 544 local = this[ fn ](), 545 cur = local[ prop.idx ], 546 match; 547 548 if ( vtype === "undefined" ) { 549 return cur; 550 } 551 552 if ( vtype === "function" ) { 553 value = value.call( this, cur ); 554 vtype = jQuery.type( value ); 555 } 556 if ( value == null && prop.empty ) { 557 return this; 558 } 559 if ( vtype === "string" ) { 560 match = rplusequals.exec( value ); 561 if ( match ) { 562 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 563 } 564 } 565 local[ prop.idx ] = value; 566 return this[ fn ]( local ); 567 }; 568 }); 569 }); 570 571 // add cssHook and .fx.step function for each named hook. 572 // accept a space separated string of properties 573 color.hook = function( hook ) { 574 var hooks = hook.split( " " ); 575 each( hooks, function( i, hook ) { 576 jQuery.cssHooks[ hook ] = { 577 set: function( elem, value ) { 578 var parsed, curElem, 579 backgroundColor = ""; 580 581 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { 582 value = color( parsed || value ); 583 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 584 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 585 while ( 586 (backgroundColor === "" || backgroundColor === "transparent") && 587 curElem && curElem.style 588 ) { 589 try { 590 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 591 curElem = curElem.parentNode; 592 } catch ( e ) { 593 } 594 } 595 596 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 597 backgroundColor : 598 "_default" ); 599 } 600 601 value = value.toRgbaString(); 602 } 603 try { 604 elem.style[ hook ] = value; 605 } catch( e ) { 606 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 607 } 608 } 609 }; 610 jQuery.fx.step[ hook ] = function( fx ) { 611 if ( !fx.colorInit ) { 612 fx.start = color( fx.elem, hook ); 613 fx.end = color( fx.end ); 614 fx.colorInit = true; 615 } 616 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 617 }; 618 }); 619 620 }; 621 622 color.hook( stepHooks ); 623 624 jQuery.cssHooks.borderColor = { 625 expand: function( value ) { 626 var expanded = {}; 627 628 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 629 expanded[ "border" + part + "Color" ] = value; 630 }); 631 return expanded; 632 } 633 }; 634 635 // Basic color names only. 636 // Usage of any of the other color names requires adding yourself or including 637 // jquery.color.svg-names.js. 638 colors = jQuery.Color.names = { 639 // 4.1. Basic color keywords 640 aqua: "#00ffff", 641 black: "#000000", 642 blue: "#0000ff", 643 fuchsia: "#ff00ff", 644 gray: "#808080", 645 green: "#008000", 646 lime: "#00ff00", 647 maroon: "#800000", 648 navy: "#000080", 649 olive: "#808000", 650 purple: "#800080", 651 red: "#ff0000", 652 silver: "#c0c0c0", 653 teal: "#008080", 654 white: "#ffffff", 655 yellow: "#ffff00", 656 657 // 4.2.3. ‘transparent’ color keyword 658 transparent: [ null, null, null, 0 ], 659 660 _default: "#ffffff" 661 }; 662 663 })( jQuery );1 /*! 2 * jQuery Color Animations v2.1.1 3 * https://github.com/jquery/jquery-color 4 * 5 * Copyright 2012 jQuery Foundation and other contributors 6 * Released under the MIT license. 7 * http://jquery.org/license 8 * 9 * Date: Sun Oct 28 15:08:06 2012 -0400 10 */ 11 (function( jQuery, undefined ) { 12 13 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 14 15 // plusequals test for += 100 -= 100 16 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 17 // a set of RE's that can match strings and generate color tuples. 18 stringParsers = [{ 19 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 20 parse: function( execResult ) { 21 return [ 22 execResult[ 1 ], 23 execResult[ 2 ], 24 execResult[ 3 ], 25 execResult[ 4 ] 26 ]; 27 } 28 }, { 29 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 30 parse: function( execResult ) { 31 return [ 32 execResult[ 1 ] * 2.55, 33 execResult[ 2 ] * 2.55, 34 execResult[ 3 ] * 2.55, 35 execResult[ 4 ] 36 ]; 37 } 38 }, { 39 // this regex ignores A-F because it's compared against an already lowercased string 40 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, 41 parse: function( execResult ) { 42 return [ 43 parseInt( execResult[ 1 ], 16 ), 44 parseInt( execResult[ 2 ], 16 ), 45 parseInt( execResult[ 3 ], 16 ) 46 ]; 47 } 48 }, { 49 // this regex ignores A-F because it's compared against an already lowercased string 50 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, 51 parse: function( execResult ) { 52 return [ 53 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 54 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 55 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) 56 ]; 57 } 58 }, { 59 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 60 space: "hsla", 61 parse: function( execResult ) { 62 return [ 63 execResult[ 1 ], 64 execResult[ 2 ] / 100, 65 execResult[ 3 ] / 100, 66 execResult[ 4 ] 67 ]; 68 } 69 }], 70 71 // jQuery.Color( ) 72 color = jQuery.Color = function( color, green, blue, alpha ) { 73 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 74 }, 75 spaces = { 76 rgba: { 77 props: { 78 red: { 79 idx: 0, 80 type: "byte" 81 }, 82 green: { 83 idx: 1, 84 type: "byte" 85 }, 86 blue: { 87 idx: 2, 88 type: "byte" 89 } 90 } 91 }, 92 93 hsla: { 94 props: { 95 hue: { 96 idx: 0, 97 type: "degrees" 98 }, 99 saturation: { 100 idx: 1, 101 type: "percent" 102 }, 103 lightness: { 104 idx: 2, 105 type: "percent" 106 } 107 } 108 } 109 }, 110 propTypes = { 111 "byte": { 112 floor: true, 113 max: 255 114 }, 115 "percent": { 116 max: 1 117 }, 118 "degrees": { 119 mod: 360, 120 floor: true 121 } 122 }, 123 support = color.support = {}, 124 125 // element for support tests 126 supportElem = jQuery( "<p>" )[ 0 ], 127 128 // colors = jQuery.Color.names 129 colors, 130 131 // local aliases of functions called often 132 each = jQuery.each; 133 134 // determine rgba support immediately 135 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 136 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 137 138 // define cache name and alpha properties 139 // for rgba and hsla spaces 140 each( spaces, function( spaceName, space ) { 141 space.cache = "_" + spaceName; 142 space.props.alpha = { 143 idx: 3, 144 type: "percent", 145 def: 1 146 }; 147 }); 148 149 function clamp( value, prop, allowEmpty ) { 150 var type = propTypes[ prop.type ] || {}; 151 152 if ( value == null ) { 153 return (allowEmpty || !prop.def) ? null : prop.def; 154 } 155 156 // ~~ is an short way of doing floor for positive numbers 157 value = type.floor ? ~~value : parseFloat( value ); 158 159 // IE will pass in empty strings as value for alpha, 160 // which will hit this case 161 if ( isNaN( value ) ) { 162 return prop.def; 163 } 164 165 if ( type.mod ) { 166 // we add mod before modding to make sure that negatives values 167 // get converted properly: -10 -> 350 168 return (value + type.mod) % type.mod; 169 } 170 171 // for now all property types without mod have min and max 172 return 0 > value ? 0 : type.max < value ? type.max : value; 173 } 174 175 function stringParse( string ) { 176 var inst = color(), 177 rgba = inst._rgba = []; 178 179 string = string.toLowerCase(); 180 181 each( stringParsers, function( i, parser ) { 182 var parsed, 183 match = parser.re.exec( string ), 184 values = match && parser.parse( match ), 185 spaceName = parser.space || "rgba"; 186 187 if ( values ) { 188 parsed = inst[ spaceName ]( values ); 189 190 // if this was an rgba parse the assignment might happen twice 191 // oh well.... 192 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 193 rgba = inst._rgba = parsed._rgba; 194 195 // exit each( stringParsers ) here because we matched 196 return false; 197 } 198 }); 199 200 // Found a stringParser that handled it 201 if ( rgba.length ) { 202 203 // if this came from a parsed string, force "transparent" when alpha is 0 204 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 205 if ( rgba.join() === "0,0,0,0" ) { 206 jQuery.extend( rgba, colors.transparent ); 207 } 208 return inst; 209 } 210 211 // named colors 212 return colors[ string ]; 213 } 214 215 color.fn = jQuery.extend( color.prototype, { 216 parse: function( red, green, blue, alpha ) { 217 if ( red === undefined ) { 218 this._rgba = [ null, null, null, null ]; 219 return this; 220 } 221 if ( red.jquery || red.nodeType ) { 222 red = jQuery( red ).css( green ); 223 green = undefined; 224 } 225 226 var inst = this, 227 type = jQuery.type( red ), 228 rgba = this._rgba = []; 229 230 // more than 1 argument specified - assume ( red, green, blue, alpha ) 231 if ( green !== undefined ) { 232 red = [ red, green, blue, alpha ]; 233 type = "array"; 234 } 235 236 if ( type === "string" ) { 237 return this.parse( stringParse( red ) || colors._default ); 238 } 239 240 if ( type === "array" ) { 241 each( spaces.rgba.props, function( key, prop ) { 242 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 243 }); 244 return this; 245 } 246 247 if ( type === "object" ) { 248 if ( red instanceof color ) { 249 each( spaces, function( spaceName, space ) { 250 if ( red[ space.cache ] ) { 251 inst[ space.cache ] = red[ space.cache ].slice(); 252 } 253 }); 254 } else { 255 each( spaces, function( spaceName, space ) { 256 var cache = space.cache; 257 each( space.props, function( key, prop ) { 258 259 // if the cache doesn't exist, and we know how to convert 260 if ( !inst[ cache ] && space.to ) { 261 262 // if the value was null, we don't need to copy it 263 // if the key was alpha, we don't need to copy it either 264 if ( key === "alpha" || red[ key ] == null ) { 265 return; 266 } 267 inst[ cache ] = space.to( inst._rgba ); 268 } 269 270 // this is the only case where we allow nulls for ALL properties. 271 // call clamp with alwaysAllowEmpty 272 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 273 }); 274 275 // everything defined but alpha? 276 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 277 // use the default of 1 278 inst[ cache ][ 3 ] = 1; 279 if ( space.from ) { 280 inst._rgba = space.from( inst[ cache ] ); 281 } 282 } 283 }); 284 } 285 return this; 286 } 287 }, 288 is: function( compare ) { 289 var is = color( compare ), 290 same = true, 291 inst = this; 292 293 each( spaces, function( _, space ) { 294 var localCache, 295 isCache = is[ space.cache ]; 296 if (isCache) { 297 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 298 each( space.props, function( _, prop ) { 299 if ( isCache[ prop.idx ] != null ) { 300 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 301 return same; 302 } 303 }); 304 } 305 return same; 306 }); 307 return same; 308 }, 309 _space: function() { 310 var used = [], 311 inst = this; 312 each( spaces, function( spaceName, space ) { 313 if ( inst[ space.cache ] ) { 314 used.push( spaceName ); 315 } 316 }); 317 return used.pop(); 318 }, 319 transition: function( other, distance ) { 320 var end = color( other ), 321 spaceName = end._space(), 322 space = spaces[ spaceName ], 323 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 324 start = startColor[ space.cache ] || space.to( startColor._rgba ), 325 result = start.slice(); 326 327 end = end[ space.cache ]; 328 each( space.props, function( key, prop ) { 329 var index = prop.idx, 330 startValue = start[ index ], 331 endValue = end[ index ], 332 type = propTypes[ prop.type ] || {}; 333 334 // if null, don't override start value 335 if ( endValue === null ) { 336 return; 337 } 338 // if null - use end 339 if ( startValue === null ) { 340 result[ index ] = endValue; 341 } else { 342 if ( type.mod ) { 343 if ( endValue - startValue > type.mod / 2 ) { 344 startValue += type.mod; 345 } else if ( startValue - endValue > type.mod / 2 ) { 346 startValue -= type.mod; 347 } 348 } 349 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 350 } 351 }); 352 return this[ spaceName ]( result ); 353 }, 354 blend: function( opaque ) { 355 // if we are already opaque - return ourself 356 if ( this._rgba[ 3 ] === 1 ) { 357 return this; 358 } 359 360 var rgb = this._rgba.slice(), 361 a = rgb.pop(), 362 blend = color( opaque )._rgba; 363 364 return color( jQuery.map( rgb, function( v, i ) { 365 return ( 1 - a ) * blend[ i ] + a * v; 366 })); 367 }, 368 toRgbaString: function() { 369 var prefix = "rgba(", 370 rgba = jQuery.map( this._rgba, function( v, i ) { 371 return v == null ? ( i > 2 ? 1 : 0 ) : v; 372 }); 373 374 if ( rgba[ 3 ] === 1 ) { 375 rgba.pop(); 376 prefix = "rgb("; 377 } 378 379 return prefix + rgba.join() + ")"; 380 }, 381 toHslaString: function() { 382 var prefix = "hsla(", 383 hsla = jQuery.map( this.hsla(), function( v, i ) { 384 if ( v == null ) { 385 v = i > 2 ? 1 : 0; 386 } 387 388 // catch 1 and 2 389 if ( i && i < 3 ) { 390 v = Math.round( v * 100 ) + "%"; 391 } 392 return v; 393 }); 394 395 if ( hsla[ 3 ] === 1 ) { 396 hsla.pop(); 397 prefix = "hsl("; 398 } 399 return prefix + hsla.join() + ")"; 400 }, 401 toHexString: function( includeAlpha ) { 402 var rgba = this._rgba.slice(), 403 alpha = rgba.pop(); 404 405 if ( includeAlpha ) { 406 rgba.push( ~~( alpha * 255 ) ); 407 } 408 409 return "#" + jQuery.map( rgba, function( v ) { 410 411 // default to 0 when nulls exist 412 v = ( v || 0 ).toString( 16 ); 413 return v.length === 1 ? "0" + v : v; 414 }).join(""); 415 }, 416 toString: function() { 417 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 418 } 419 }); 420 color.fn.parse.prototype = color.fn; 421 422 // hsla conversions adapted from: 423 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 424 425 function hue2rgb( p, q, h ) { 426 h = ( h + 1 ) % 1; 427 if ( h * 6 < 1 ) { 428 return p + (q - p) * h * 6; 429 } 430 if ( h * 2 < 1) { 431 return q; 432 } 433 if ( h * 3 < 2 ) { 434 return p + (q - p) * ((2/3) - h) * 6; 435 } 436 return p; 437 } 438 439 spaces.hsla.to = function ( rgba ) { 440 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 441 return [ null, null, null, rgba[ 3 ] ]; 442 } 443 var r = rgba[ 0 ] / 255, 444 g = rgba[ 1 ] / 255, 445 b = rgba[ 2 ] / 255, 446 a = rgba[ 3 ], 447 max = Math.max( r, g, b ), 448 min = Math.min( r, g, b ), 449 diff = max - min, 450 add = max + min, 451 l = add * 0.5, 452 h, s; 453 454 if ( min === max ) { 455 h = 0; 456 } else if ( r === max ) { 457 h = ( 60 * ( g - b ) / diff ) + 360; 458 } else if ( g === max ) { 459 h = ( 60 * ( b - r ) / diff ) + 120; 460 } else { 461 h = ( 60 * ( r - g ) / diff ) + 240; 462 } 463 464 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 465 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 466 if ( diff === 0 ) { 467 s = 0; 468 } else if ( l <= 0.5 ) { 469 s = diff / add; 470 } else { 471 s = diff / ( 2 - add ); 472 } 473 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; 474 }; 475 476 spaces.hsla.from = function ( hsla ) { 477 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 478 return [ null, null, null, hsla[ 3 ] ]; 479 } 480 var h = hsla[ 0 ] / 360, 481 s = hsla[ 1 ], 482 l = hsla[ 2 ], 483 a = hsla[ 3 ], 484 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 485 p = 2 * l - q; 486 487 return [ 488 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 489 Math.round( hue2rgb( p, q, h ) * 255 ), 490 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 491 a 492 ]; 493 }; 494 495 496 each( spaces, function( spaceName, space ) { 497 var props = space.props, 498 cache = space.cache, 499 to = space.to, 500 from = space.from; 501 502 // makes rgba() and hsla() 503 color.fn[ spaceName ] = function( value ) { 504 505 // generate a cache for this space if it doesn't exist 506 if ( to && !this[ cache ] ) { 507 this[ cache ] = to( this._rgba ); 508 } 509 if ( value === undefined ) { 510 return this[ cache ].slice(); 511 } 512 513 var ret, 514 type = jQuery.type( value ), 515 arr = ( type === "array" || type === "object" ) ? value : arguments, 516 local = this[ cache ].slice(); 517 518 each( props, function( key, prop ) { 519 var val = arr[ type === "object" ? key : prop.idx ]; 520 if ( val == null ) { 521 val = local[ prop.idx ]; 522 } 523 local[ prop.idx ] = clamp( val, prop ); 524 }); 525 526 if ( from ) { 527 ret = color( from( local ) ); 528 ret[ cache ] = local; 529 return ret; 530 } else { 531 return color( local ); 532 } 533 }; 534 535 // makes red() green() blue() alpha() hue() saturation() lightness() 536 each( props, function( key, prop ) { 537 // alpha is included in more than one space 538 if ( color.fn[ key ] ) { 539 return; 540 } 541 color.fn[ key ] = function( value ) { 542 var vtype = jQuery.type( value ), 543 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), 544 local = this[ fn ](), 545 cur = local[ prop.idx ], 546 match; 547 548 if ( vtype === "undefined" ) { 549 return cur; 550 } 551 552 if ( vtype === "function" ) { 553 value = value.call( this, cur ); 554 vtype = jQuery.type( value ); 555 } 556 if ( value == null && prop.empty ) { 557 return this; 558 } 559 if ( vtype === "string" ) { 560 match = rplusequals.exec( value ); 561 if ( match ) { 562 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 563 } 564 } 565 local[ prop.idx ] = value; 566 return this[ fn ]( local ); 567 }; 568 }); 569 }); 570 571 // add cssHook and .fx.step function for each named hook. 572 // accept a space separated string of properties 573 color.hook = function( hook ) { 574 var hooks = hook.split( " " ); 575 each( hooks, function( i, hook ) { 576 jQuery.cssHooks[ hook ] = { 577 set: function( elem, value ) { 578 var parsed, curElem, 579 backgroundColor = ""; 580 581 if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { 582 value = color( parsed || value ); 583 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 584 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 585 while ( 586 (backgroundColor === "" || backgroundColor === "transparent") && 587 curElem && curElem.style 588 ) { 589 try { 590 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 591 curElem = curElem.parentNode; 592 } catch ( e ) { 593 } 594 } 595 596 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 597 backgroundColor : 598 "_default" ); 599 } 600 601 value = value.toRgbaString(); 602 } 603 try { 604 elem.style[ hook ] = value; 605 } catch( e ) { 606 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 607 } 608 } 609 }; 610 jQuery.fx.step[ hook ] = function( fx ) { 611 if ( !fx.colorInit ) { 612 fx.start = color( fx.elem, hook ); 613 fx.end = color( fx.end ); 614 fx.colorInit = true; 615 } 616 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 617 }; 618 }); 619 620 }; 621 622 color.hook( stepHooks ); 623 624 jQuery.cssHooks.borderColor = { 625 expand: function( value ) { 626 var expanded = {}; 627 628 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { 629 expanded[ "border" + part + "Color" ] = value; 630 }); 631 return expanded; 632 } 633 }; 634 635 // Basic color names only. 636 // Usage of any of the other color names requires adding yourself or including 637 // jquery.color.svg-names.js. 638 colors = jQuery.Color.names = { 639 // 4.1. Basic color keywords 640 aqua: "#00ffff", 641 black: "#000000", 642 blue: "#0000ff", 643 fuchsia: "#ff00ff", 644 gray: "#808080", 645 green: "#008000", 646 lime: "#00ff00", 647 maroon: "#800000", 648 navy: "#000080", 649 olive: "#808000", 650 purple: "#800080", 651 red: "#ff0000", 652 silver: "#c0c0c0", 653 teal: "#008080", 654 white: "#ffffff", 655 yellow: "#ffff00", 656 657 // 4.2.3. ‘transparent’ color keyword 658 transparent: [ null, null, null, 0 ], 659 660 _default: "#ffffff" 661 }; 662 663 })( jQuery );
联系我们 |
---|
文章看不懂?联系我们为您免费解答!免费助力个人,小企站点! |
① 电话:020-2206-9892 |
② QQ咨询:1025174874 |
③ 邮件:info@361sale.com |
④ 工作时间:周一至周五,9:30-18:30,节假日休息 |
THE END
暂无评论内容