/* http://keith-wood.name/svg.html
SVG filters for jQuery v1.4.5.
Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
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
$.svg.addExtension('filters', SVGFilter);
$.extend($.svg._wrapperClass.prototype, {
/* Add a filter definition.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param id (string) the ID for this filter
@param x (number) the x-coordinate for the left edge of the filter
@param y (number) the y-coordinate for the top edge of the filter
@param width (number) the width of the filter
@param height (number) the height of the filter
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
filter: function(parent, id, x, y, width, height, settings) {
var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
return this._makeNode(args.parent, 'filter', $.extend(
{id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
args.settings || {}));
}
});
/* Extension point for SVG filters.
Access through svg.filters. */
function SVGFilter(wrapper) {
this._wrapper = wrapper; // The attached SVG wrapper object
}
$.extend(SVGFilter.prototype, {
/* Add a distant light filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param azimuth (number) the angle (degrees) in the XY plane for the light source
@param elevation (number) the angle (degrees) in the YZ plane for the light source
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
distantLight: function(parent, result, azimuth, elevation, settings) {
var args = this._wrapper._args(arguments, ['result', 'azimuth', 'elevation']);
return this._wrapper._makeNode(args.parent, 'feDistantLight', $.extend(
{result: args.result, azimuth: args.azimuth, elevation: args.elevation},
args.settings || {}));
},
/* Add a point light filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param x (number) the x-coordinate for the light source
@param y (number) the y-coordinate for the light source
@param z (number) the z-coordinate for the light source
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
pointLight: function(parent, result, x, y, z, settings) {
var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'z']);
return this._wrapper._makeNode(args.parent, 'fePointLight', $.extend(
{result: args.result, x: args.x, y: args.y, z: args.z}, args.settings || {}));
},
/* Add a spot light filter.
Specify all of toX, toY, toZ or none of them.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param x (number) the x-coordinate for the light source
@param y (number) the y-coordinate for the light source
@param z (number) the z-coordinate for the light source
@param toX (number) the x-coordinate for where the light is pointing (optional)
@param toY (number) the y-coordinate for where the light is pointing (optional)
@param toZ (number) the z-coordinate for where the light is pointing (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
spotLight: function(parent, result, x, y, z, toX, toY, toZ, settings) {
var args = this._wrapper._args(arguments,
['result', 'x', 'y', 'z', 'toX', 'toY', 'toZ'], ['toX']);
var sets = $.extend({result: args.result, x: args.x, y: args.y, z: args.z},
(args.toX != null ? {pointsAtX: args.toX, pointsAtY: args.toY,
pointsAtZ: args.toZ} : {}));
return this._wrapper._makeNode(args.parent, 'feSpotLight',
$.extend(sets, args.settings || {}));
},
/* Add a blend filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param mode (string) normal | multiply | screen | darken | lighten
@param in1 (string) the first image to blend
@param in2 (string) the second image to blend
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
blend: function(parent, result, mode, in1, in2, settings) {
var args = this._wrapper._args(arguments, ['result', 'mode', 'in1', 'in2']);
return this._wrapper._makeNode(args.parent, 'feBlend', $.extend(
{result: args.result, mode: args.mode, in_: args.in1, in2: args.in2},
args.settings || {}));
},
/* Add a colour matrix filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source to colour
@param type (string) matrix | saturate | hueRotate | luminanceToAlpha
@param values (number[][]) for 'matrix' the matrix (5x4) values to apply
(number) for 'saturate' 0.0 to 1.0
(number) for 'hueRotate' degrees
(void) for 'luminanceToAlpha'
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
colorMatrix: function(parent, result, in1, type, values, settings) {
var args = this._wrapper._args(arguments, ['result', 'in1', 'type', 'values']);
if (isArray(args.values)) {
var vs = '';
for (var i = 0; i < args.values.length; i++) {
vs += (i == 0 ? '' : ' ') + args.values[i].join(' ');
}
args.values = vs;
}
else if (typeof args.values == 'object') {
args.settings = args.values;
args.values = null;
}
var sets = $.extend({result: args.result, in_: args.in1, type: args.type},
(args.values != null ? {values: args.values} : {}));
return this._wrapper._makeNode(args.parent, 'feColorMatrix',
$.extend(sets, args.settings || {}));
},
/* Add a component transfer filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param functions (object[]) one for each of RGB and A (alpha, optional)
for each entry:
[0] is (string) identity | table | discrete | linear | gamma
[1] is (number[]) for 'table' or 'discrete' the list of
interpolation or step values OR
(number) for 'linear' the slope, for 'gamma' the amplitude,
[2] is (number) for 'linear' the intercept, for 'gamma' the exponent,
[3] is (number) for 'gamma' the offset
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
componentTransfer: function(parent, result, functions, settings) {
var args = this._wrapper._args(arguments, ['result', 'functions']);
var node = this._wrapper._makeNode(args.parent, 'feComponentTransfer',
$.extend({result: args.result}, args.settings || {}));
var rgba = ['R', 'G', 'B', 'A'];
for (var i = 0; i < Math.min(4, args.functions.length); i++) {
var props = args.functions[i];
var sets = $.extend({type: props[0]},
(props[0] == 'table' || props[0] == 'discrete' ? {tableValues: props[1].join(' ')} :
(props[0] == 'linear' ? {slope: props[1], intercept: props[2]} :
(props[0] == 'gamma' ? {amplitude: props[1],
exponent: props[2], offset: props[3]} : {}))));
this._wrapper._makeNode(node, 'feFunc' + rgba[i], sets);
}
return node;
},
/* Add a composite filter.
Specify all of k1, k2, k3, k4 or none of them.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param operator (string) over | in | out | atop | xor | arithmetic
@param in1 (string) the first filter to compose
@param in2 (string) the second filter to compose
@param k1 (number) for 'arithmetic' (optional)
@param k2 (number) for 'arithmetic' (optional)
@param k3 (number) for 'arithmetic' (optional)
@param k4 (number) for 'arithmetic' (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
composite: function(parent, result, operator, in1, in2, k1, k2, k3, k4, settings) {
var args = this._wrapper._args(arguments, ['result', 'operator',
'in1', 'in2', 'k1', 'k2', 'k3', 'k4'], ['k1']);
var sets = $.extend({result: args.result, operator: args.operator,
'in': args.in1, in2: args.in2},
(args.k1 != null ? {k1: args.k1, k2: args.k2, k3: args.k3, k4: args.k4} : {}));
return this._wrapper._makeNode(args.parent, 'feComposite',
$.extend(sets, args.settings || {}));
},
/* Add a convolve matrix filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param order (int or 'int int') the size(s) of the matrix
@param matrix (number[][]) the kernel matrix for the convolution
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
convolveMatrix: function(parent, result, order, matrix, settings) {
var args = this._wrapper._args(arguments, ['result', 'order', 'matrix']);
var mx = '';
for (var i = 0; i < args.matrix.length; i++) {
mx += (i == 0 ? '' : ' ') + args.matrix[i].join(' ');
}
args.matrix = mx;
return this._wrapper._makeNode(args.parent, 'feConvolveMatrix', $.extend(
{result: args.result, order: args.order, kernelMatrix: args.matrix},
args.settings || {}));
},
/* Add a diffuse lighting filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param colour (string) the lighting colour (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
diffuseLighting: function(parent, result, colour, settings) {
var args = this._wrapper._args(arguments, ['result', 'colour'], ['colour']);
return this._wrapper._makeNode(args.parent, 'feDiffuseLighting',
$.extend($.extend({result: args.result},
(args.colour ? {lightingColor: args.colour} : {})), args.settings || {}));
},
/* Add a displacement map filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source image
@param in2 (string) the displacement image
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
displacementMap: function(parent, result, in1, in2, settings) {
var args = this._wrapper._args(arguments, ['result', 'in1', 'in2']);
return this._wrapper._makeNode(args.parent, 'feDisplacementMap',
$.extend({result: args.result, in_: args.in1, in2: args.in2},
args.settings || {}));
},
/* Add a flood filter.
Specify all of x, y, width, height or none of them.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param x (number) the left coordinate of the rectangle (optional)
@param y (number) the top coordinate of the rectangle (optional)
@param width (number) the width of the rectangle (optional)
@param height (number) the height of the rectangle (optional)
@param colour (string) the colour to fill with
@param opacity (number) the opacity 0.0-1.0
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
flood: function(parent, result, x, y, width, height, colour, opacity, settings) {
var args = this._wrapper._args(arguments,
['result', 'x', 'y', 'width', 'height', 'colour', 'opacity']);
if (arguments.length < 6) {
args.colour = args.x;
args.opacity = args.y;
args.settings = args.width;
args.x = null;
}
var sets = $.extend({result: args.result, floodColor: args.colour,
floodOpacity: args.opacity}, (args.x != null ?
{x: args.x, y: args.y, width: args.width, height: args.height} : {}));
return this._wrapper._makeNode(args.parent, 'feFlood',
$.extend(sets, args.settings || {}));
},
/* Add a Gaussian blur filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source filter
@param stdDevX (number) the standard deviation along the x-axis
@param stdDevY (number) the standard deviation along the y-axis (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
gaussianBlur: function(parent, result, in1, stdDevX, stdDevY, settings) {
var args = this._wrapper._args(arguments,
['result', 'in1', 'stdDevX', 'stdDevY'], ['stdDevY']);
return this._wrapper._makeNode(args.parent, 'feGaussianBlur', $.extend(
{result: args.result, in_: args.in1, stdDeviation: args.stdDevX +
(args.stdDevY ? ' ' + args.stdDevY : '')}, args.settings || {}));
},
/* Add an image filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param href (string) the URL of the image
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
image: function(parent, result, href, settings) {
var args = this._wrapper._args(arguments, ['result', 'href']);
var node = this._wrapper._makeNode(args.parent, 'feImage', $.extend(
{result: args.result}, args.settings || {}));
node.setAttributeNS($.svg.xlinkNS, 'href', args.href);
return node;
},
/* Add a merge filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param refs (string[]) the IDs of the filters to merge
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
merge: function(parent, result, refs, settings) {
var args = this._wrapper._args(arguments, ['result', 'refs']);
var node = this._wrapper._makeNode(args.parent, 'feMerge', $.extend(
{result: args.result}, args.settings || {}));
for (var i = 0; i < args.refs.length; i++) {
this._wrapper._makeNode(node, 'feMergeNode', {in_: args.refs[i]});
}
return node;
},
/* Add a morphology filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source filter
@param operator (string) erode | dilate
@param radiusX (number) the size of the operation in the x-axis
@param radiusY (number) the size of the operation in the y-axis (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
morphology: function(parent, result, in1, operator, radiusX, radiusY, settings) {
var args = this._wrapper._args(arguments, ['result', 'in1',
'operator', 'radiusX', 'radiusY'], ['radiusY']);
return this._wrapper._makeNode(args.parent, 'feMorphology', $.extend(
{result: args.result, in_: args.in1, operator: args.operator,
radius: args.radiusX + (args.radiusY ? ' ' + args.radiusY : '')},
args.settings || {}));
},
/* Add an offset filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source filter
@param dX (number) the offset in the x-axis
@param dY (number) the offset in the y-axis
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
offset: function(parent, result, in1, dx, dy, settings) {
var args = this._wrapper._args(arguments, ['result', 'in1', 'dx', 'dy']);
return this._wrapper._makeNode(args.parent, 'feOffset', $.extend(
{result: args.result, in_: args.in1, dx: args.dx, dy: args.dy},
args.settings || {}));
},
/* Add a specular lighting filter.
Numeric params are only optional if following numeric params are also omitted.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source filter
@param surfaceScale (number) the surface height when Ain = 1 (optional)
@param specularConstant (number) the ks in Phong lighting model (optional)
@param specularExponent (number) the shininess 1.0-128.0 (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
specularLighting: function(parent, result, in1, surfaceScale,
specularConstant, specularExponent, settings) {
var args = this._wrapper._args(arguments, ['result', 'in1',
'surfaceScale', 'specularConstant', 'specularExponent'],
['surfaceScale', 'specularConstant', 'specularExponent']);
return this._wrapper._makeNode(args.parent, 'feSpecularLighting', $.extend(
{result: args.result, in_: args.in1, surfaceScale: args.surfaceScale,
specularConstant: args.specularConstant, specularExponent: args.specularExponent},
args.settings || {}));
},
/* Add a tile filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param in1 (string) the source filter
@param x (number) the left coordinate of the rectangle
@param y (number) the top coordinate of the rectangle
@param width (number) the width of the rectangle
@param height (number) the height of the rectangle
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
tile: function(parent, result, in1, x, y, width, height, settings) {
var args = this._wrapper._args(arguments,
['result', 'in1', 'x', 'y', 'width', 'height']);
return this._wrapper._makeNode(args.parent, 'feTile', $.extend(
{result: args.result, in_: args.in1, x: args.x, y: args.y,
width: args.width, height: args.height}, args.settings || {}));
},
/* Add a turbulence filter.
@param parent (element or jQuery) the parent node for the new filter (optional)
@param result (string) the ID of this filter
@param type (string) fractalNoise | turbulence
@param baseFreq (number or 'number number') the base frequency,
optionally separated into x- and y-components
@param octaves (number) the amount of turbulence (optional)
@param settings (object) additional settings for the filter (optional)
@return (element) the new filter node */
turbulence: function(parent, result, type, baseFreq, octaves, settings) {
var args = this._wrapper._args(arguments, ['result', 'type',
'baseFreq', 'octaves'], ['octaves']);
return this._wrapper._makeNode(args.parent, 'feTurbulence', $.extend(
{result: args.result, type: args.type, baseFrequency: args.baseFreq,
numOctaves: args.octaves}, args.settings || {}));
}
});
/* Determine whether an object is an array. */
function isArray(a) {
return (a && a.constructor == Array);
}
})(jQuery)