Mercurial > hg > digilib-old
view client/digitallibrary/jquery/svg/jquery.svganim.js @ 761:16778bd2de7c jquery
added setScaleMode. no compensation for change in scaling yet.
author | robcast |
---|---|
date | Wed, 09 Feb 2011 10:22:29 +0100 |
parents | ccf67eaf97ee |
children |
line wrap: on
line source
/* http://keith-wood.name/svg.html SVG attribute animations for jQuery v1.4.3. Written by Keith Wood (kbwood{at}iinet.com.au) June 2008. Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. Please attribute the author if you use it. */ (function($) { // Hide scope, no $ conflict // Enable animation for all of these SVG numeric attributes - // named as svg-* or svg* (with first character upper case) $.each(['x', 'y', 'width', 'height', 'rx', 'ry', 'cx', 'cy', 'r', 'x1', 'y1', 'x2', 'y2', 'stroke-width', 'strokeWidth', 'opacity', 'fill-opacity', 'fillOpacity', 'stroke-opacity', 'strokeOpacity', 'font-size', 'fontSize'], function(i, attrName) { var ccName = attrName.charAt(0).toUpperCase() + attrName.substr(1); $.fx.step['svg' + ccName] = $.fx.step['svg-' + attrName] = function(fx) { var realAttrName = $.svg._attrNames[attrName] || attrName; var attr = fx.elem.attributes.getNamedItem(realAttrName); if (!fx.set) { fx.start = (attr ? parseFloat(attr.nodeValue) : 0); var offset = fx.options.curAnim['svg-' + attrName] || fx.options.curAnim['svg' + ccName]; if (/^[+-]=/.exec(offset)) { fx.end = fx.start + parseFloat(offset.replace(/=/, '')); } $(fx.elem).css(realAttrName, ''); fx.set = true; } var value = (fx.pos * (fx.end - fx.start) + fx.start) + (fx.unit == '%' ? '%' : ''); (attr ? attr.nodeValue = value : fx.elem.setAttribute(realAttrName, value)); }; } ); // Enable animation for the SVG viewBox attribute $.fx.step['svgViewBox'] = $.fx.step['svg-viewBox'] = function(fx) { var attr = fx.elem.attributes.getNamedItem('viewBox'); if (!fx.set) { fx.start = parseViewBox(attr ? attr.nodeValue : ''); var offset = fx.options.curAnim['svg-viewBox'] || fx.options.curAnim['svgViewBox']; fx.end = parseViewBox(offset); if (/^[+-]=/.exec(offset)) { offset = offset.split(' '); while (offset.length < 4) { offset.push('0'); } for (var i = 0; i < 4; i++) { if (/^[+-]=/.exec(offset[i])) { fx.end[i] = fx.start[i] + parseFloat(offset[i].replace(/=/, '')); } } } fx.set = true; } var value = $.map(fx.start, function(n, i) { return (fx.pos * (fx.end[i] - n) + n); }).join(' '); (attr ? attr.nodeValue = value : fx.elem.setAttribute('viewBox', value)); }; /* Parse a viewBox definition: x, y, width, height. @param value (string) the definition @return (number[4]) the extracted values */ function parseViewBox(value) { var viewBox = value.split(' '); for (var i = 0; i < viewBox.length; i++) { viewBox[i] = parseFloat(viewBox[i]); if (isNaN(viewBox[i])) { viewBox[i] = 0; } } while (viewBox.length < 4) { viewBox.push(0); } return viewBox; } // Enable animation for the SVG transform attribute $.fx.step['svgTransform'] = $.fx.step['svg-transform'] = function(fx) { var attr = fx.elem.attributes.getNamedItem('transform'); if (!fx.set) { fx.start = parseTransform(attr ? attr.nodeValue : ''); fx.end = parseTransform(fx.end, fx.start); fx.set = true; } var transform = ''; for (var i = 0; i < fx.end.order.length; i++) { switch (fx.end.order.charAt(i)) { case 't': transform += (fx.start.translateX != fx.end.translateX || fx.start.translateY != fx.end.translateY ? ' translate(' + (fx.pos * (fx.end.translateX - fx.start.translateX) + fx.start.translateX) + ',' + (fx.pos * (fx.end.translateY - fx.start.translateY) + fx.start.translateY) + ')' : ''); break; case 's': transform += (fx.start.scaleX != fx.end.scaleX || fx.start.scaleY != fx.end.scaleY ? ' scale(' + (fx.pos * (fx.end.scaleX - fx.start.scaleX) + fx.start.scaleX) + ',' + (fx.pos * (fx.end.scaleY - fx.start.scaleY) + fx.start.scaleY) + ')' : ''); break; case 'r': transform += (fx.start.rotateA != fx.end.rotateA || fx.start.rotateX != fx.end.rotateX || fx.start.rotateY != fx.end.rotateY ? ' rotate(' + (fx.pos * (fx.end.rotateA - fx.start.rotateA) + fx.start.rotateA) + ',' + (fx.pos * (fx.end.rotateX - fx.start.rotateX) + fx.start.rotateX) + ',' + (fx.pos * (fx.end.rotateY - fx.start.rotateY) + fx.start.rotateY) + ')' : ''); break; case 'x': transform += (fx.start.skewX != fx.end.skewX ? ' skewX(' + (fx.pos * (fx.end.skewX - fx.start.skewX) + fx.start.skewX) + ')' : ''); case 'y': transform += (fx.start.skewY != fx.end.skewY ? ' skewY(' + (fx.pos * (fx.end.skewY - fx.start.skewY) + fx.start.skewY) + ')' : ''); break; case 'm': var matrix = ''; for (var j = 0; j < 6; j++) { matrix += ',' + (fx.pos * (fx.end.matrix[j] - fx.start.matrix[j]) + fx.start.matrix[j]); } transform += ' matrix(' + matrix.substr(1) + ')'; break; } } (attr ? attr.nodeValue = transform : fx.elem.setAttribute('transform', transform)); }; /* Decode a transform string and extract component values. @param value (string) the transform string to parse @param original (object) the settings from the original node @return (object) the combined transformation attributes */ function parseTransform(value, original) { value = value || ''; if (typeof value == 'object') { value = value.nodeValue; } var transform = $.extend({translateX: 0, translateY: 0, scaleX: 0, scaleY: 0, rotateA: 0, rotateX: 0, rotateY: 0, skewX: 0, skewY: 0, matrix: [0, 0, 0, 0, 0, 0]}, original || {}); transform.order = ''; var pattern = /([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g; var result = pattern.exec(value); while (result) { switch (result[1]) { case 'translate': transform.order += 't'; transform.translateX = parseFloat(result[2]); transform.translateY = (result[3] ? parseFloat(result[3]) : 0); break; case 'scale': transform.order += 's'; transform.scaleX = parseFloat(result[2]); transform.scaleY = (result[3] ? parseFloat(result[3]) : transform.scaleX); break; case 'rotate': transform.order += 'r'; transform.rotateA = parseFloat(result[2]); transform.rotateX = (result[3] ? parseFloat(result[3]) : 0); transform.rotateY = (result[4] ? parseFloat(result[4]) : 0); break; case 'skewX': transform.order += 'x'; transform.skewX = parseFloat(result[2]); break; case 'skewY': transform.order += 'y'; transform.skewY = parseFloat(result[2]); break; case 'matrix': transform.order += 'm'; transform.matrix = [parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]), parseFloat(result[5]), parseFloat(result[6]), parseFloat(result[7])]; break; } result = pattern.exec(value); } return transform; } // Enable animation for all of these SVG colour properties - based on jquery.color.js $.each(['fill', 'stroke'], function(i, attrName) { var ccName = attrName.charAt(0).toUpperCase() + attrName.substr(1); $.fx.step['svg' + ccName] = $.fx.step['svg-' + attrName] = function(fx) { if (!fx.set) { fx.start = getColour(fx.elem, attrName); var toNone = (fx.end == 'none'); fx.end = (toNone ? getColour(fx.elem.parentNode, attrName) : getRGB(fx.end)); fx.end[3] = toNone; $(fx.elem).css(attrName, ''); fx.set = true; } var attr = fx.elem.attributes.getNamedItem(attrName); var colour = 'rgb(' + [ Math.min(Math.max(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 0), 255), Math.min(Math.max(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 0), 255), Math.min(Math.max(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 0), 255) ].join(',') + ')'; colour = (fx.end[3] && fx.state == 1 ? 'none' : colour); (attr ? attr.nodeValue = colour : fx.elem.setAttribute(attrName, colour)); } } ); /* Find this attribute value somewhere up the node hierarchy. @param elem (element) the starting element to find the attribute @param attr (string) the attribute name @return (number[3]) RGB components for the attribute colour */ function getColour(elem, attr) { var colour; do { colour = (elem.attributes && elem.attributes.getNamedItem(attr) ? elem.attributes.getNamedItem(attr).nodeValue : ''); // Keep going until we find an element that has colour, or exit SVG if ((colour != '' && colour != 'none') || $(elem).hasClass('hasSVG')) { break; } } while (elem = elem.parentNode); return getRGB(colour); } /* Parse strings looking for common colour formats. @param colour (string) colour description to parse @return (number[3]) RGB components of this colour */ function getRGB(colour) { var result; // Check if we're already dealing with an array of colors if (colour && colour.constructor == Array && (colour.length == 3 || colour.length == 4)) { return colour; } // Look for rgb(num,num,num) if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(colour)) { return [parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10)]; } // Look for rgb(num%,num%,num%) if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(colour)) { return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55]; } // Look for #a0b1c2 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(colour)) { return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)]; } // Look for #abc if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(colour)) { return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)]; } // Otherwise, we're most likely dealing with a named color return colours[$.trim(colour).toLowerCase()] || colours['none']; } // The SVG named colours var colours = { '': [255, 255, 255, 1], none: [255, 255, 255, 1], aliceblue: [240, 248, 255], antiquewhite: [250, 235, 215], aqua: [ 0, 255, 255], aquamarine: [127, 255, 212], azure: [240, 255, 255], beige: [245, 245, 220], bisque: [255, 228, 196], black: [ 0, 0, 0], blanchedalmond: [255, 235, 205], blue: [ 0, 0, 255], blueviolet: [138, 43, 226], brown: [165, 42, 42], burlywood: [222, 184, 135], cadetblue: [ 95, 158, 160], chartreuse: [127, 255, 0], chocolate: [210, 105, 30], coral: [255, 127, 80], cornflowerblue: [100, 149, 237], cornsilk: [255, 248, 220], crimson: [220, 20, 60], cyan: [ 0, 255, 255], darkblue: [ 0, 0, 139], darkcyan: [ 0, 139, 139], darkgoldenrod: [184, 134, 11], darkgray: [169, 169, 169], darkgreen: [ 0, 100, 0], darkgrey: [169, 169, 169], darkkhaki: [189, 183, 107], darkmagenta: [139, 0, 139], darkolivegreen: [ 85, 107, 47], darkorange: [255, 140, 0], darkorchid: [153, 50, 204], darkred: [139, 0, 0], darksalmon: [233, 150, 122], darkseagreen: [143, 188, 143], darkslateblue: [ 72, 61, 139], darkslategray: [ 47, 79, 79], darkslategrey: [ 47, 79, 79], darkturquoise: [ 0, 206, 209], darkviolet: [148, 0, 211], deeppink: [255, 20, 147], deepskyblue: [ 0, 191, 255], dimgray: [105, 105, 105], dimgrey: [105, 105, 105], dodgerblue: [ 30, 144, 255], firebrick: [178, 34, 34], floralwhite: [255, 250, 240], forestgreen: [ 34, 139, 34], fuchsia: [255, 0, 255], gainsboro: [220, 220, 220], ghostwhite: [248, 248, 255], gold: [255, 215, 0], goldenrod: [218, 165, 32], gray: [128, 128, 128], grey: [128, 128, 128], green: [ 0, 128, 0], greenyellow: [173, 255, 47], honeydew: [240, 255, 240], hotpink: [255, 105, 180], indianred: [205, 92, 92], indigo: [ 75, 0, 130], ivory: [255, 255, 240], khaki: [240, 230, 140], lavender: [230, 230, 250], lavenderblush: [255, 240, 245], lawngreen: [124, 252, 0], lemonchiffon: [255, 250, 205], lightblue: [173, 216, 230], lightcoral: [240, 128, 128], lightcyan: [224, 255, 255], lightgoldenrodyellow: [250, 250, 210], lightgray: [211, 211, 211], lightgreen: [144, 238, 144], lightgrey: [211, 211, 211], lightpink: [255, 182, 193], lightsalmon: [255, 160, 122], lightseagreen: [ 32, 178, 170], lightskyblue: [135, 206, 250], lightslategray: [119, 136, 153], lightslategrey: [119, 136, 153], lightsteelblue: [176, 196, 222], lightyellow: [255, 255, 224], lime: [ 0, 255, 0], limegreen: [ 50, 205, 50], linen: [250, 240, 230], magenta: [255, 0, 255], maroon: [128, 0, 0], mediumaquamarine: [102, 205, 170], mediumblue: [ 0, 0, 205], mediumorchid: [186, 85, 211], mediumpurple: [147, 112, 219], mediumseagreen: [ 60, 179, 113], mediumslateblue: [123, 104, 238], mediumspringgreen: [ 0, 250, 154], mediumturquoise: [ 72, 209, 204], mediumvioletred: [199, 21, 133], midnightblue: [ 25, 25, 112], mintcream: [245, 255, 250], mistyrose: [255, 228, 225], moccasin: [255, 228, 181], navajowhite: [255, 222, 173], navy: [ 0, 0, 128], oldlace: [253, 245, 230], olive: [128, 128, 0], olivedrab: [107, 142, 35], orange: [255, 165, 0], orangered: [255, 69, 0], orchid: [218, 112, 214], palegoldenrod: [238, 232, 170], palegreen: [152, 251, 152], paleturquoise: [175, 238, 238], palevioletred: [219, 112, 147], papayawhip: [255, 239, 213], peachpuff: [255, 218, 185], peru: [205, 133, 63], pink: [255, 192, 203], plum: [221, 160, 221], powderblue: [176, 224, 230], purple: [128, 0, 128], red: [255, 0, 0], rosybrown: [188, 143, 143], royalblue: [ 65, 105, 225], saddlebrown: [139, 69, 19], salmon: [250, 128, 114], sandybrown: [244, 164, 96], seagreen: [ 46, 139, 87], seashell: [255, 245, 238], sienna: [160, 82, 45], silver: [192, 192, 192], skyblue: [135, 206, 235], slateblue: [106, 90, 205], slategray: [112, 128, 144], slategrey: [112, 128, 144], snow: [255, 250, 250], springgreen: [ 0, 255, 127], steelblue: [ 70, 130, 180], tan: [210, 180, 140], teal: [ 0, 128, 128], thistle: [216, 191, 216], tomato: [255, 99, 71], turquoise: [ 64, 224, 208], violet: [238, 130, 238], wheat: [245, 222, 179], white: [255, 255, 255], whitesmoke: [245, 245, 245], yellow: [255, 255, 0], yellowgreen: [154, 205, 50] }; })(jQuery);