Last active
November 15, 2024 15:57
-
-
Save dominic-p/4569265 to your computer and use it in GitHub Desktop.
A super simple jQuery plugin to fade one color into another on selected elements. It seems to work, but there are some things I'd like to improve:- Add transparency (rgba) handling in an intelligent way, right now it defaults to white, but it would be nice if it could default to transparent without sacrificing old browser support and without blo…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Color Fade | |
Requires: jQuery 1.7.1+ (probably much lower) | |
Description: Simple color animation. Fades one color into another on the selected element(s) | |
Arguments: | |
- target (object) The target color in this format [r,g,b] defaults to white or yellow if fade_settings.flash is true | |
- fade_settings (object) See code for documentation | |
Usage: | |
// Fade the background color of "#element" to rgb: 255, 253, 196 | |
$( '#element' ).colorFade( [255, 253, 196] ); | |
*/ | |
(function($) { | |
var methods = { | |
/* | |
Method to take a color input and check it and conform it to the | |
format that we need | |
Arguments: | |
- color (string) The color we are checking | |
*/ | |
conform_color : function( color ) { | |
// If it's already array, no need to mess with it | |
if ( typeof color === 'object' ) { return color; } | |
if ( typeof color !== 'string' || !color || 'rgb(' !== color.substring( 0, 4 ) ) { | |
return [255,255,255]; | |
} | |
// Convert original color into array of number strings | |
color = color.replace( /[^0-9,]/gi, '' ).split( ',' ); | |
// Parse array of number strings into array of integers | |
return $.map( color, function( str ) { return parseInt( str ); }); | |
} | |
}; | |
$.fn.colorFade = function( target, fade_settings ) { | |
var settings = $.extend({ | |
duration : 400, // (int) How long it should take to fade the colors | |
cb : $.noop, // (function) A callback function to be fired when fading is complete | |
prop : 'backgroundColor', // (sring) The CSS property whose color we are fading (defaults to backgroundColor) | |
flash : false // (bool) Whether we are just flashing the color and we should revert to the original when we're done | |
}, fade_settings ); | |
// Default flash color if none is provided | |
if ( !target && settings.flash ) { target = [255,253,196]; } | |
// Conform the target color to our specs | |
target = methods.conform_color( target ); | |
// Return 'this' to maintain chainability | |
return this.each(function() { | |
var $this = $(this), | |
original = methods.conform_color( $this.css( settings.prop ) ); | |
// Create a dummy element to animate so we can use a step function (don't insert element into DOM) | |
$( '<div />' ).animate({ 'width' : 100 }, { | |
duration : ( settings.flash ) ? 175 : settings.duration, | |
easing : 'swing', | |
// Fade the colors in the step function | |
step : function( now, fx ) { | |
var completion = ( now - fx.start ) / ( fx.end - fx.start ); | |
$this.css( settings.prop, 'rgb(' | |
+ Math.round( original[0] + ( ( target[0] - original[0] ) * completion ) ) + ',' | |
+ Math.round( original[1] + ( ( target[1] - original[1] ) * completion ) ) + ',' | |
+ Math.round( original[2] + ( ( target[2] - original[2] ) * completion ) ) + ')' | |
); | |
}, | |
// Fire the callback if one was provided | |
complete : function() { | |
if ( settings.flash ) { | |
// Set flash to false as this will be the fade back to the original color | |
settings.flash = false; | |
// If a duration wasn't specified we set a longer default than normal | |
if ( typeof fade_settings != 'object' || !( 'duration' in fade_settings ) ) { | |
settings.duration = 2000; | |
} | |
$this.colorFade( original, settings ); | |
return; | |
} | |
// Call the callback | |
settings.cb(); | |
} | |
}); | |
}); | |
}; | |
})(jQuery); |
My take on this
$.fn.colorFade = function (colorOrSettings) {
function parseColor(value) {
if (value.indexOf('rgb') != -1) {
return $.map(value.replace(/[^0-9,]/gi, '').split(','), function (i) { return parseInt(i); });
}
if (value.charAt(0) == '#' && value.length == '#b00000'.length) {
value = value.substr(1);
return [
parseInt(value.substr(0, 2), 16),
parseInt(value.substr(2, 2), 16),
parseInt(value.substr(4, 2), 16)
];
}
return; // returns undefined
}
var settings = $.extend(
{
duration: 400,
easing: 'swing',
prop: 'backgroundColor'
},
typeof colorOrSettings == 'string' ? { color: colorOrSettings } : colorOrSettings
);
var target = parseColor(settings.color);
return this.each(function () {
var element = $(this);
var source = parseColor(element.css(settings.prop));
$({ completion: 0 }).animate({ completion: 1 }, {
duration: settings.duration,
easing: settings.easing,
step: function (completion) {
var r = source[0] + ((target[0] - source[0]) * completion);
var g = source[1] + ((target[1] - source[1]) * completion);
var b = source[2] + ((target[2] - source[2]) * completion);
element.css(settings.prop, 'rgb(' + $.map([r, g, b], Math.round).join(',') + ')');
}
});
});
};
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can see it in action on jsFiddle