Skip to content

Instantly share code, notes, and snippets.

@dominic-p
Last active July 29, 2016 19:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dominic-p/4569265 to your computer and use it in GitHub Desktop.
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…
/*
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);
@dominic-p
Copy link
Author

You can see it in action on jsFiddle

@bjorn-ali-goransson
Copy link

bjorn-ali-goransson commented Jul 29, 2016

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