by Robert C. Barth First Posted August 27, 2011

jQuery, along with jQuery UI provides developers with many effects options. Unfortunately, many of the newer, more complex CSS3 effects cannot be automatically animated using jQuery's built-in animation code. In this post I will show you how to use the step option jQuery's animate method to manipulate just about any property of an element, including any CSS3 property (specifically the linear-gradient value for the background-image property in this example).

CSS3 Linear Gradient

CSS3 introduced a number of new ways to style HTML markup. One of the more complex among them (syntactically) is the linear-gradient value added to the background-image property. The way you specify a linear gradient is as follows:

background-image: linear-gradient( [<point> || <angle>,]? <stop>, <stop> [, <stop>]* )

where:

<stop> <color> [ <percentage> | <length> ]

As you can see, it's kind of complicated so I won't explain the syntax, the w3c draft specification does a good job on its own. (It helps if you've ever used Photoshop to create gradients because it basically uses the same stop concept) Instead, I'll focus on how we can manipulate this syntax within a custom animation to create a custom jQuery effect.

jQuery Step Option

Utilizing the step property of the options of the second call method of jQuery's animate function, you can create custom animations of any type, not just the built-in CSS properties that jQuery knows about. There are many articles posted in many blogs about this, but I first read about it on Ben Nadel's blog. What the step option gives us is a function that jQuery will call for each step of the animation. Meaning that it will calculate the easing, timing, etc, and make this call to your function for each step, providing you with some key information (e.g. the now variable, which gives you the current calculated value of the custom CSS property you asked jQuery to animate; in our example, this property is called 'percent'). This means we can create virtually any animation one can think of.

Custom Animation

Given the step option, and the skeleton jQuery effect plug-in I wrote about last time, we can create an effect plug-in that will do the following:

  1. Accept a times option to specify how many times the animation should run
  2. A duration to specify how long it should run per time (in milliseconds)
  3. A starting angle for the linear-gradient (this plug-in actually does require it to be a numeric angle and not the specification's permitted textual direction parameters).
  4. A stops array, which itself can contain either a color only in each index, or a two-item array specifying the color and the position. Note that if the position is not specified in at least one of the stops, this effect won't animate anything, as it's the positions that the effect animates.

Given those requirements, here's the code:

/*!
* jQuery linear gradient effect plug-in.
* Requires jQuery UI.
* http://norimek.com/blog/page/jQuery-Plug-Ins.aspx
*
* Copyright 2011, Robert C. Barth
* Licensed under the MIT license.
* http://www.opensource.org/licenses/MIT
*
* Date: Sat Aug 27 13:00:00 2011 -0700
*/
(function($, undefined) {

$.effects.lineargradient = function(o) {

	return this.queue(function() {
		
		var $this = $(this), 
			props = [ 'background-image' ],
			times = o.options.times || 1,
			duration = o.duration || 1000,
			angle = o.options.angle || 0,
			stops = o.options.stops;
		
		$.effects.save($this, props);
		$this.css('percent', 0);
		
		for (var i = 0; i < times; i++) {
			
			$this.animate({ percent: 125 }, {
				queue: false,
				duration: duration,
				easing: o.options.easing,
				step: function(now, fx) {
					
					var gradientSpecifier = [ angle.toString() + 'deg, ' ]

					for (var ii = 0, l = stops.length; ii < l; ii++) {
						
						if ($.isArray(stops[ii])) {
							// Color
							gradientSpecifier.push(stops[ii][0].toString() + ' ');
							// Position
							gradientSpecifier.push(String(now + stops[ii][1]) + '%');
						} else {
							// Color only
							gradientSpecifier.push(stops[ii].toString());
						}
						
						if (ii < l - 1) {
							gradientSpecifier.push(', ');
						}
					}
					
					gradientSpecifier = gradientSpecifier.join('');
					
					$(fx.elem).css('background-image', '-webkit-linear-gradient(' + gradientSpecifier + ')');
					$(fx.elem).css('background-image', '-moz-linear-gradient(' + gradientSpecifier + ')');
					$(fx.elem).css('background-image', '-o-linear-gradient(' + gradientSpecifier + ')');
					$(fx.elem).css('background-image', 'linear-gradient(' + gradientSpecifier + ')');
				},
				complete: function() {
					
					$this.css('percent', 0);
					$.effects.restore($this, props);
					
					$this.dequeue();
					
					if (o.callback) {
						o.callback.apply(this, arguments);
					}
				}
			});
		}
	});
};
})(jQuery);

It's actually a pretty simple effect plug-in. It just sets up a custom CSS property iterator ('percent'), setting the value to get to to 125 (jQuery will animate from zero to that, and the completion function sets it back to zero), and on its way toward 125, will call the step function specified, which does the actual animating by creating a string that is the linear-gradient specifier, and setting the background-image CSS property of the specified element to that (since the linear-gradient value is not standardized yet, it sets the background-image property four different ways for Opera, Mozilla, Webkit, and finally the CSS3 standard).

Please note that the stop positions specified in the array are offsets (unlike the CSS value itself which takes positions as percents -- the animation code converts the offsets to percents during the animation). Meaning, if you were to create a gradient at 10%, 20%, 100%, the offsets to put into the array are something like -25, -15, 65. It is important to usually start at -25 or so because the animator goes to +25 so that larger gradients can "complete" (it makes more sense when you watch the gradients themselves animate -- the trailing part needs to disappear for it to look right).

Also note that this plug-in requires jQuery UI. Please reference the jQuery UI in your page when you use it or it won't work!

OK, enough talking already, the example is here. There are a couple of examples of what the plug-in can do, but you can certainly do more with it. The plug-in source code is available via the link below.

jquery.effects.lineargradient.js (1.80 kb)

Tags: , ,

jQuery

blog comments powered by Disqus

Powered by BlogEngine.NET 2.5.0.10

Site LogoCopyright © 2014 Robert C. Barth. All Rights Reserved.

 
 

Bio

This is the blog of Robert C. Barth dedicated to software engineering and (mostly) related things. Robert has over seventeen years of experience engineering software solutions, from architecture to design, development, requirements gathering, technical writing, and UI design. He lives in Chandler, Arizona and when he is not working on software projects you can probably find him riding his Honda CBR1000RR around the south east valley.