jQuery-text-shadow
code:script.js
/*!
* Text shadow animation jQuery-plugin
* Copyright 2011 Alex Peattie <alexpeattie@gmail.com>
* Contributor: Edwin Martin <edwin@bitstorm.org>
* Released under the MIT and GPL licenses.
*/
jQuery(function($) {
/**
* Check whether the browser supports RGBA color mode.
*
* @return {boolean} True if the browser support RGBA. False otherwise.
*/
function isRGBACapable() {
var $script = $('script:first'),
color = $script.css('color'),
result = false;
if (/^rgba/.test(color)) {
result = true;
} else {
try {
result = ( color != $script.css('color', 'rgba(0, 0, 0, 0.5)').css('color') );
$script.css('color', color);
} catch (e) {
}
}
return result;
}
$.extend(true, $, {
support: {
'rgba': isRGBACapable()
}
});
/*************************************/
// Extend the animate-function
// We have initialized shadow values
if (!fx.hasOwnProperty('init')) {
// We have to pass the font size to the parseShadow method, to allow the use of em units
var fontSize = $(fx.elem).get(0).style'fontSize' || $(fx.elem).css('fontSize'); var beginShadow = $(fx.elem).get(0).style'textShadow' || $(fx.elem).css('textShadow'); // In cases where text-shadow is none, or is not returned by browser, then set init to false
if(beginShadow == '' || beginShadow == 'none') {
fx.init = false;
return;
}
fx.begin = parseShadow(beginShadow, fontSize);
// In case we can't calculate beginning shadow (possibly unknown style format) then set init to false
if(fx.begin === false) {
fx.init = false;
return;
}
fx.end = $.extend({}, fx.begin, parseShadow(fx.end, fontSize));
fx.init = true;
}
// Flag to skip animation
if (fx.init === false) {
return;
}
fx.elem.style.textShadow = calculateShadow(fx.begin, fx.end, fx.pos);
}
// Calculate an in-between shadow.
function calculateShadow(begin, end, pos) {
var parts = [];
if (typeof end.right != 'undefined') {
parts.push(parseInt(begin.right + pos * (end.right - begin.right)) + 'px '
+ parseInt(begin.bottom + pos * (end.bottom - begin.bottom)) + 'px');
}
if (typeof end.blur != 'undefined') {
parts.push(parseInt(begin.blur + pos * (end.blur - begin.blur)) + 'px');
}
if (typeof end.color != 'undefined') {
var color = 'rgb' + ($.support.rgba ? 'a' : '') + '('
+ parseInt((begin.color0 + pos * (end.color0 - begin.color0))) + ',' + parseInt((begin.color1 + pos * (end.color1 - begin.color1))) + ',' + parseInt((begin.color2 + pos * (end.color2 - begin.color2))); if ($.support.rgba) {
color += ',' + parseFloat(begin.color3 + pos * (end.color3 - begin.color3)); }
color += ')';
parts.push(color);
}
var value = parts.join(' ');
return value;
}
// Parse the shadow value and extract the values.
function parseShadow(shadow, fontSize) {
var match, color, lengths, valpx, parsedShadow = {};
// Parse an CSS-syntax color. Outputs an array r, g, b color = [parseInt(match1, 16), parseInt(match2, 16), parseInt(match3, 16), 1]; color = [parseInt(match1, 16) * 17, parseInt(match2, 16) * 17, parseInt(match3, 16) * 17, 1]; // Match rgb(n, n, n)
} else if (match = /rgb\(\s*(0-9{1,3})\s*,\s*(0-9{1,3})\s*,\s*(0-9{1,3})\s*\)/.exec(shadow)) { color = [parseInt(match1), parseInt(match2), parseInt(match3), 1]; // Match rgba(n, n, n, n)
} else if (match = /rgba\(\s*(0-9{1,3})\s*,\s*(0-9{1,3})\s*,\s*(0-9{1,3})\s*,\s*(0-9\.*)\s*\)/.exec(shadow)) { color = [parseInt(match1), parseInt(match2), parseInt(match3),parseFloat(match4)]; // No browser returns rgb(n%, n%, n%), so little reason to support this format.
// But we can get unknown format, in which case we return false indicating problem
} else {
return false;
}
// Remove the color value from the string for the next round of parsing
lengths = shadow.replace(match0, ''); // Parse offset and blur
if (match = /(-*0-9.+(?:px|em|pt)?)\s+(-*0-9.+(?:px|em|pt)?)\s+(-*0-9.+(?:px|em|pt)?)/.exec(lengths)) { // Rough and ready em/pt > px conversion
valpx = match.slice(1).map(function(v) {
var unit = v.match(/em|pt/);
if (unit == "em") return parseFloat(v) * parseInt(fontSize);
if (unit == "pt") return parseInt(v)/72*96;
return parseInt(v);
});
parsedShadow = {right: valpx0, bottom: valpx1, blur: valpx2}; // In case we can't parse other values from style
} else {
return false;
}
parsedShadow.color = color;
return parsedShadow;
}
});