jquerysvg 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,406 @@
1
+ /* http://keith-wood.name/svg.html
2
+ jQuery DOM compatibility for jQuery SVG v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ (function($) { // Hide scope, no $ conflict
9
+
10
+ /* Support adding class names to SVG nodes. */
11
+ $.fn.addClass = function(origAddClass) {
12
+ return function(classNames) {
13
+ classNames = classNames || '';
14
+ return this.each(function() {
15
+ if ($.svg.isSVGElem(this)) {
16
+ var node = this;
17
+ $.each(classNames.split(/\s+/), function(i, className) {
18
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
19
+ if ($.inArray(className, classes.split(/\s+/)) == -1) {
20
+ classes += (classes ? ' ' : '') + className;
21
+ (node.className ? node.className.baseVal = classes :
22
+ node.setAttribute('class', classes));
23
+ }
24
+ });
25
+ }
26
+ else {
27
+ origAddClass.apply($(this), [classNames]);
28
+ }
29
+ });
30
+ };
31
+ }($.fn.addClass);
32
+
33
+ /* Support removing class names from SVG nodes. */
34
+ $.fn.removeClass = function(origRemoveClass) {
35
+ return function(classNames) {
36
+ classNames = classNames || '';
37
+ return this.each(function() {
38
+ if ($.svg.isSVGElem(this)) {
39
+ var node = this;
40
+ $.each(classNames.split(/\s+/), function(i, className) {
41
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
42
+ classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).
43
+ join(' ');
44
+ (node.className ? node.className.baseVal = classes :
45
+ node.setAttribute('class', classes));
46
+ });
47
+ }
48
+ else {
49
+ origRemoveClass.apply($(this), [classNames]);
50
+ }
51
+ });
52
+ };
53
+ }($.fn.removeClass);
54
+
55
+ /* Support toggling class names on SVG nodes. */
56
+ $.fn.toggleClass = function(origToggleClass) {
57
+ return function(className, state) {
58
+ return this.each(function() {
59
+ if ($.svg.isSVGElem(this)) {
60
+ if (typeof state !== 'boolean') {
61
+ state = !$(this).hasClass(className);
62
+ }
63
+ $(this)[(state ? 'add' : 'remove') + 'Class'](className);
64
+ }
65
+ else {
66
+ origToggleClass.apply($(this), [className, state]);
67
+ }
68
+ });
69
+ };
70
+ }($.fn.toggleClass);
71
+
72
+ /* Support checking class names on SVG nodes. */
73
+ $.fn.hasClass = function(origHasClass) {
74
+ return function(className) {
75
+ className = className || '';
76
+ var found = false;
77
+ this.each(function() {
78
+ if ($.svg.isSVGElem(this)) {
79
+ var classes = (this.className ? this.className.baseVal :
80
+ this.getAttribute('class')).split(/\s+/);
81
+ found = ($.inArray(className, classes) > -1);
82
+ }
83
+ else {
84
+ found = (origHasClass.apply($(this), [className]));
85
+ }
86
+ return !found;
87
+ });
88
+ return found;
89
+ };
90
+ }($.fn.hasClass);
91
+
92
+ /* Support attributes on SVG nodes. */
93
+ $.fn.attr = function(origAttr) {
94
+ return function(name, value, type) {
95
+ if (typeof name === 'string' && value === undefined) {
96
+ var val = origAttr.apply(this, [name]);
97
+ if (val && val.baseVal && val.baseVal.numberOfItems != null) { // Multiple values
98
+ value = '';
99
+ val = val.baseVal;
100
+ if (name == 'transform') {
101
+ for (var i = 0; i < val.numberOfItems; i++) {
102
+ var item = val.getItem(i);
103
+ switch (item.type) {
104
+ case 1: value += ' matrix(' + item.matrix.a + ',' + item.matrix.b + ',' +
105
+ item.matrix.c + ',' + item.matrix.d + ',' +
106
+ item.matrix.e + ',' + item.matrix.f + ')';
107
+ break;
108
+ case 2: value += ' translate(' + item.matrix.e + ',' + item.matrix.f + ')'; break;
109
+ case 3: value += ' scale(' + item.matrix.a + ',' + item.matrix.d + ')'; break;
110
+ case 4: value += ' rotate(' + item.angle + ')'; break; // Doesn't handle new origin
111
+ case 5: value += ' skewX(' + item.angle + ')'; break;
112
+ case 6: value += ' skewY(' + item.angle + ')'; break;
113
+ }
114
+ }
115
+ val = value.substring(1);
116
+ }
117
+ else {
118
+ val = val.getItem(0).valueAsString;
119
+ }
120
+ }
121
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
122
+ }
123
+
124
+ var options = name;
125
+ if (typeof name === 'string') {
126
+ options = {};
127
+ options[name] = value;
128
+ }
129
+ return this.each(function() {
130
+ if ($.svg.isSVGElem(this)) {
131
+ for (var n in options) {
132
+ var val = ($.isFunction(options[n]) ? options[n]() : options[n]);
133
+ (type ? this.style[n] = val : this.setAttribute(n, val));
134
+ }
135
+ }
136
+ else {
137
+ origAttr.apply($(this), [name, value, type]);
138
+ }
139
+ });
140
+ };
141
+ }($.fn.attr);
142
+
143
+ /* Support removing attributes on SVG nodes. */
144
+ $.fn.removeAttr = function(origRemoveAttr) {
145
+ return function(name) {
146
+ return this.each(function() {
147
+ if ($.svg.isSVGElem(this)) {
148
+ (this[name] && this[name].baseVal ? this[name].baseVal.value = '' :
149
+ this.setAttribute(name, ''));
150
+ }
151
+ else {
152
+ origRemoveAttr.apply($(this), [name]);
153
+ }
154
+ });
155
+ };
156
+ }($.fn.removeAttr);
157
+
158
+ /* Add numeric only properties. */
159
+ $.extend($.cssNumber, {
160
+ 'stopOpacity': true,
161
+ 'strokeMitrelimit': true,
162
+ 'strokeOpacity': true
163
+ });
164
+
165
+ /* Support retrieving CSS/attribute values on SVG nodes. */
166
+ if ($.cssProps) {
167
+ $.css = function(origCSS) {
168
+ return function(elem, name, extra) {
169
+ var value = (name.match(/^svg.*/) ? $(elem).attr($.cssProps[name] || name) : '');
170
+ return value || origCSS(elem, name, extra);
171
+ };
172
+ }($.css);
173
+ }
174
+
175
+ /* Determine if any nodes are SVG nodes. */
176
+ function anySVG(checkSet) {
177
+ for (var i = 0; i < checkSet.length; i++) {
178
+ if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {
179
+ return true;
180
+ }
181
+ }
182
+ return false;
183
+ }
184
+
185
+ /* Update Sizzle selectors. */
186
+
187
+ $.expr.relative['+'] = function(origRelativeNext) {
188
+ return function(checkSet, part, isXML) {
189
+ origRelativeNext(checkSet, part, isXML || anySVG(checkSet));
190
+ };
191
+ }($.expr.relative['+']);
192
+
193
+ $.expr.relative['>'] = function(origRelativeChild) {
194
+ return function(checkSet, part, isXML) {
195
+ origRelativeChild(checkSet, part, isXML || anySVG(checkSet));
196
+ };
197
+ }($.expr.relative['>']);
198
+
199
+ $.expr.relative[''] = function(origRelativeDescendant) {
200
+ return function(checkSet, part, isXML) {
201
+ origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));
202
+ };
203
+ }($.expr.relative['']);
204
+
205
+ $.expr.relative['~'] = function(origRelativeSiblings) {
206
+ return function(checkSet, part, isXML) {
207
+ origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));
208
+ };
209
+ }($.expr.relative['~']);
210
+
211
+ $.expr.find.ID = function(origFindId) {
212
+ return function(match, context, isXML) {
213
+ return ($.svg.isSVGElem(context) ?
214
+ [context.ownerDocument.getElementById(match[1])] :
215
+ origFindId(match, context, isXML));
216
+ };
217
+ }($.expr.find.ID);
218
+
219
+ var div = document.createElement('div');
220
+ div.appendChild(document.createComment(''));
221
+ if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found
222
+ $.expr.find.TAG = function(match, context) {
223
+ var results = context.getElementsByTagName(match[1]);
224
+ if (match[1] === '*') { // Filter out possible comments
225
+ var tmp = [];
226
+ for (var i = 0; results[i] || results.item(i); i++) {
227
+ if ((results[i] || results.item(i)).nodeType === 1) {
228
+ tmp.push(results[i] || results.item(i));
229
+ }
230
+ }
231
+ results = tmp;
232
+ }
233
+ return results;
234
+ };
235
+ }
236
+
237
+ $.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {
238
+ match = ' ' + match[1].replace(/\\/g, '') + ' ';
239
+ if (isXML) {
240
+ return match;
241
+ }
242
+ for (var i = 0, elem = {}; elem != null; i++) {
243
+ elem = curLoop[i];
244
+ if (!elem) {
245
+ try {
246
+ elem = curLoop.item(i);
247
+ }
248
+ catch (e) {
249
+ // Ignore
250
+ }
251
+ }
252
+ if (elem) {
253
+ var className = (!$.svg.isSVGElem(elem) ? elem.className :
254
+ (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));
255
+ if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {
256
+ if (!inplace)
257
+ result.push(elem);
258
+ }
259
+ else if (inplace) {
260
+ curLoop[i] = false;
261
+ }
262
+ }
263
+ }
264
+ return false;
265
+ };
266
+
267
+ $.expr.filter.CLASS = function(elem, match) {
268
+ var className = (!$.svg.isSVGElem(elem) ? elem.className :
269
+ (elem.className ? elem.className.baseVal : elem.getAttribute('class')));
270
+ return (' ' + className + ' ').indexOf(match) > -1;
271
+ };
272
+
273
+ $.expr.filter.ATTR = function(origFilterAttr) {
274
+ return function(elem, match) {
275
+ var handler = null;
276
+ if ($.svg.isSVGElem(elem)) {
277
+ handler = match[1];
278
+ $.expr.attrHandle[handler] = function(elem){
279
+ var attr = elem.getAttribute(handler);
280
+ return attr && attr.baseVal || attr;
281
+ };
282
+ }
283
+ var filter = origFilterAttr(elem, match);
284
+ if (handler) {
285
+ $.expr.attrHandle[handler] = null;
286
+ }
287
+ return filter;
288
+ };
289
+ }($.expr.filter.ATTR);
290
+
291
+ /*
292
+ In the removeData function (line 1881, v1.7.2):
293
+
294
+ if ( jQuery.support.deleteExpando ) {
295
+ delete elem[ internalKey ];
296
+ } else {
297
+ try { // SVG
298
+ elem.removeAttribute( internalKey );
299
+ } catch (e) {
300
+ elem[ internalKey ] = null;
301
+ }
302
+ }
303
+
304
+ In the event.add function (line 2985, v1.7.2):
305
+
306
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
307
+ // Bind the global event handler to the element
308
+ try { // SVG
309
+ elem.addEventListener( type, eventHandle, false );
310
+ } catch(e) {
311
+ if ( elem.attachEvent ) {
312
+ elem.attachEvent( "on" + type, eventHandle );
313
+ }
314
+ }
315
+ }
316
+
317
+ In the event.remove function (line 3074, v1.7.2):
318
+
319
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
320
+ try { // SVG
321
+ elem.removeEventListener(type, elemData.handle, false);
322
+ }
323
+ catch (e) {
324
+ if (elem.detachEvent) {
325
+ elem.detachEvent("on" + type, elemData.handle);
326
+ }
327
+ }
328
+ }
329
+
330
+ In the event.fix function (line 3394, v1.7.2):
331
+
332
+ if (event.target.namespaceURI == 'http://www.w3.org/2000/svg') { // SVG
333
+ event.button = [1, 4, 2][event.button];
334
+ }
335
+
336
+ // Add which for click: 1 === left; 2 === middle; 3 === right
337
+ // Note: button is not normalized, so don't use it
338
+ if ( !event.which && button !== undefined ) {
339
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
340
+ }
341
+
342
+ In the Sizzle function (line 4083, v1.7.2):
343
+
344
+ if ( toString.call(checkSet) === "[object Array]" ) {
345
+ if ( !prune ) {
346
+ results.push.apply( results, checkSet );
347
+
348
+ } else if ( context && context.nodeType === 1 ) {
349
+ for ( i = 0; checkSet[i] != null; i++ ) {
350
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
351
+ results.push( set[i] || set.item(i) ); // SVG
352
+ }
353
+ }
354
+
355
+ } else {
356
+ for ( i = 0; checkSet[i] != null; i++ ) {
357
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
358
+ results.push( set[i] || set.item(i) ); // SVG
359
+ }
360
+ }
361
+ }
362
+ } else {...
363
+
364
+ In the fallback for the Sizzle makeArray function (line 4877, v1.7.2):
365
+
366
+ if ( toString.call(array) === "[object Array]" ) {
367
+ Array.prototype.push.apply( ret, array );
368
+
369
+ } else {
370
+ if ( typeof array.length === "number" ) {
371
+ for ( var l = array.length; i &lt; l; i++ ) {
372
+ ret.push( array[i] || array.item(i) ); // SVG
373
+ }
374
+
375
+ } else {
376
+ for ( ; array[i]; i++ ) {
377
+ ret.push( array[i] );
378
+ }
379
+ }
380
+ }
381
+
382
+ In the jQuery.cleandata function (line 6538, v1.7.2):
383
+
384
+ if ( deleteExpando ) {
385
+ delete elem[ jQuery.expando ];
386
+
387
+ } else {
388
+ try { // SVG
389
+ elem.removeAttribute( jQuery.expando );
390
+ } catch (e) {
391
+ // Ignore
392
+ }
393
+ }
394
+
395
+ In the fallback getComputedStyle function (line 6727, v1.7.2):
396
+
397
+ defaultView = (elem.ownerDocument ? elem.ownerDocument.defaultView : elem.defaultView); // SVG
398
+ if ( defaultView &&
399
+ (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
400
+
401
+ ret = computedStyle.getPropertyValue( name );
402
+ ...
403
+
404
+ */
405
+
406
+ })(jQuery);
@@ -0,0 +1,402 @@
1
+ /* http://keith-wood.name/svg.html
2
+ SVG filters for jQuery v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ (function($) { // Hide scope, no $ conflict
9
+
10
+ $.svg.addExtension('filters', SVGFilter);
11
+
12
+ $.extend($.svg._wrapperClass.prototype, {
13
+
14
+ /* Add a filter definition.
15
+ @param parent (element or jQuery) the parent node for the new filter (optional)
16
+ @param id (string) the ID for this filter
17
+ @param x (number) the x-coordinate for the left edge of the filter
18
+ @param y (number) the y-coordinate for the top edge of the filter
19
+ @param width (number) the width of the filter
20
+ @param height (number) the height of the filter
21
+ @param settings (object) additional settings for the filter (optional)
22
+ @return (element) the new filter node */
23
+ filter: function(parent, id, x, y, width, height, settings) {
24
+ var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
25
+ return this._makeNode(args.parent, 'filter', $.extend(
26
+ {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
27
+ args.settings || {}));
28
+ }
29
+ });
30
+
31
+ /* Extension point for SVG filters.
32
+ Access through svg.filters. */
33
+ function SVGFilter(wrapper) {
34
+ this._wrapper = wrapper; // The attached SVG wrapper object
35
+ }
36
+
37
+ $.extend(SVGFilter.prototype, {
38
+
39
+ /* Add a distant light filter.
40
+ @param parent (element or jQuery) the parent node for the new filter (optional)
41
+ @param result (string) the ID of this filter
42
+ @param azimuth (number) the angle (degrees) in the XY plane for the light source
43
+ @param elevation (number) the angle (degrees) in the YZ plane for the light source
44
+ @param settings (object) additional settings for the filter (optional)
45
+ @return (element) the new filter node */
46
+ distantLight: function(parent, result, azimuth, elevation, settings) {
47
+ var args = this._wrapper._args(arguments, ['result', 'azimuth', 'elevation']);
48
+ return this._wrapper._makeNode(args.parent, 'feDistantLight', $.extend(
49
+ {result: args.result, azimuth: args.azimuth, elevation: args.elevation},
50
+ args.settings || {}));
51
+ },
52
+
53
+ /* Add a point light filter.
54
+ @param parent (element or jQuery) the parent node for the new filter (optional)
55
+ @param result (string) the ID of this filter
56
+ @param x (number) the x-coordinate for the light source
57
+ @param y (number) the y-coordinate for the light source
58
+ @param z (number) the z-coordinate for the light source
59
+ @param settings (object) additional settings for the filter (optional)
60
+ @return (element) the new filter node */
61
+ pointLight: function(parent, result, x, y, z, settings) {
62
+ var args = this._wrapper._args(arguments, ['result', 'x', 'y', 'z']);
63
+ return this._wrapper._makeNode(args.parent, 'fePointLight', $.extend(
64
+ {result: args.result, x: args.x, y: args.y, z: args.z}, args.settings || {}));
65
+ },
66
+
67
+ /* Add a spot light filter.
68
+ Specify all of toX, toY, toZ or none of them.
69
+ @param parent (element or jQuery) the parent node for the new filter (optional)
70
+ @param result (string) the ID of this filter
71
+ @param x (number) the x-coordinate for the light source
72
+ @param y (number) the y-coordinate for the light source
73
+ @param z (number) the z-coordinate for the light source
74
+ @param toX (number) the x-coordinate for where the light is pointing (optional)
75
+ @param toY (number) the y-coordinate for where the light is pointing (optional)
76
+ @param toZ (number) the z-coordinate for where the light is pointing (optional)
77
+ @param settings (object) additional settings for the filter (optional)
78
+ @return (element) the new filter node */
79
+ spotLight: function(parent, result, x, y, z, toX, toY, toZ, settings) {
80
+ var args = this._wrapper._args(arguments,
81
+ ['result', 'x', 'y', 'z', 'toX', 'toY', 'toZ'], ['toX']);
82
+ var sets = $.extend({result: args.result, x: args.x, y: args.y, z: args.z},
83
+ (args.toX != null ? {pointsAtX: args.toX, pointsAtY: args.toY,
84
+ pointsAtZ: args.toZ} : {}));
85
+ return this._wrapper._makeNode(args.parent, 'feSpotLight',
86
+ $.extend(sets, args.settings || {}));
87
+ },
88
+
89
+ /* Add a blend filter.
90
+ @param parent (element or jQuery) the parent node for the new filter (optional)
91
+ @param result (string) the ID of this filter
92
+ @param mode (string) normal | multiply | screen | darken | lighten
93
+ @param in1 (string) the first image to blend
94
+ @param in2 (string) the second image to blend
95
+ @param settings (object) additional settings for the filter (optional)
96
+ @return (element) the new filter node */
97
+ blend: function(parent, result, mode, in1, in2, settings) {
98
+ var args = this._wrapper._args(arguments, ['result', 'mode', 'in1', 'in2']);
99
+ return this._wrapper._makeNode(args.parent, 'feBlend', $.extend(
100
+ {result: args.result, mode: args.mode, in_: args.in1, in2: args.in2},
101
+ args.settings || {}));
102
+ },
103
+
104
+ /* Add a colour matrix filter.
105
+ @param parent (element or jQuery) the parent node for the new filter (optional)
106
+ @param result (string) the ID of this filter
107
+ @param in1 (string) the source to colour
108
+ @param type (string) matrix | saturate | hueRotate | luminanceToAlpha
109
+ @param values (number[][]) for 'matrix' the matrix (5x4) values to apply
110
+ (number) for 'saturate' 0.0 to 1.0
111
+ (number) for 'hueRotate' degrees
112
+ (void) for 'luminanceToAlpha'
113
+ @param settings (object) additional settings for the filter (optional)
114
+ @return (element) the new filter node */
115
+ colorMatrix: function(parent, result, in1, type, values, settings) {
116
+ var args = this._wrapper._args(arguments, ['result', 'in1', 'type', 'values']);
117
+ if (isArray(args.values)) {
118
+ var vs = '';
119
+ for (var i = 0; i < args.values.length; i++) {
120
+ vs += (i == 0 ? '' : ' ') + args.values[i].join(' ');
121
+ }
122
+ args.values = vs;
123
+ }
124
+ else if (typeof args.values == 'object') {
125
+ args.settings = args.values;
126
+ args.values = null;
127
+ }
128
+ var sets = $.extend({result: args.result, in_: args.in1, type: args.type},
129
+ (args.values != null ? {values: args.values} : {}));
130
+ return this._wrapper._makeNode(args.parent, 'feColorMatrix',
131
+ $.extend(sets, args.settings || {}));
132
+ },
133
+
134
+ /* Add a component transfer filter.
135
+ @param parent (element or jQuery) the parent node for the new filter (optional)
136
+ @param result (string) the ID of this filter
137
+ @param functions (object[]) one for each of RGB and A (alpha, optional)
138
+ for each entry:
139
+ [0] is (string) identity | table | discrete | linear | gamma
140
+ [1] is (number[]) for 'table' or 'discrete' the list of
141
+ interpolation or step values OR
142
+ (number) for 'linear' the slope, for 'gamma' the amplitude,
143
+ [2] is (number) for 'linear' the intercept, for 'gamma' the exponent,
144
+ [3] is (number) for 'gamma' the offset
145
+ @param settings (object) additional settings for the filter (optional)
146
+ @return (element) the new filter node */
147
+ componentTransfer: function(parent, result, functions, settings) {
148
+ var args = this._wrapper._args(arguments, ['result', 'functions']);
149
+ var node = this._wrapper._makeNode(args.parent, 'feComponentTransfer',
150
+ $.extend({result: args.result}, args.settings || {}));
151
+ var rgba = ['R', 'G', 'B', 'A'];
152
+ for (var i = 0; i < Math.min(4, args.functions.length); i++) {
153
+ var props = args.functions[i];
154
+ var sets = $.extend({type: props[0]},
155
+ (props[0] == 'table' || props[0] == 'discrete' ? {tableValues: props[1].join(' ')} :
156
+ (props[0] == 'linear' ? {slope: props[1], intercept: props[2]} :
157
+ (props[0] == 'gamma' ? {amplitude: props[1],
158
+ exponent: props[2], offset: props[3]} : {}))));
159
+ this._wrapper._makeNode(node, 'feFunc' + rgba[i], sets);
160
+ }
161
+ return node;
162
+ },
163
+
164
+ /* Add a composite filter.
165
+ Specify all of k1, k2, k3, k4 or none of them.
166
+ @param parent (element or jQuery) the parent node for the new filter (optional)
167
+ @param result (string) the ID of this filter
168
+ @param operator (string) over | in | out | atop | xor | arithmetic
169
+ @param in1 (string) the first filter to compose
170
+ @param in2 (string) the second filter to compose
171
+ @param k1 (number) for 'arithmetic' (optional)
172
+ @param k2 (number) for 'arithmetic' (optional)
173
+ @param k3 (number) for 'arithmetic' (optional)
174
+ @param k4 (number) for 'arithmetic' (optional)
175
+ @param settings (object) additional settings for the filter (optional)
176
+ @return (element) the new filter node */
177
+ composite: function(parent, result, operator, in1, in2, k1, k2, k3, k4, settings) {
178
+ var args = this._wrapper._args(arguments, ['result', 'operator',
179
+ 'in1', 'in2', 'k1', 'k2', 'k3', 'k4'], ['k1']);
180
+ var sets = $.extend({result: args.result, operator: args.operator,
181
+ 'in': args.in1, in2: args.in2},
182
+ (args.k1 != null ? {k1: args.k1, k2: args.k2, k3: args.k3, k4: args.k4} : {}));
183
+ return this._wrapper._makeNode(args.parent, 'feComposite',
184
+ $.extend(sets, args.settings || {}));
185
+ },
186
+
187
+ /* Add a convolve matrix filter.
188
+ @param parent (element or jQuery) the parent node for the new filter (optional)
189
+ @param result (string) the ID of this filter
190
+ @param order (int or 'int int') the size(s) of the matrix
191
+ @param matrix (number[][]) the kernel matrix for the convolution
192
+ @param settings (object) additional settings for the filter (optional)
193
+ @return (element) the new filter node */
194
+ convolveMatrix: function(parent, result, order, matrix, settings) {
195
+ var args = this._wrapper._args(arguments, ['result', 'order', 'matrix']);
196
+ var mx = '';
197
+ for (var i = 0; i < args.matrix.length; i++) {
198
+ mx += (i == 0 ? '' : ' ') + args.matrix[i].join(' ');
199
+ }
200
+ args.matrix = mx;
201
+ return this._wrapper._makeNode(args.parent, 'feConvolveMatrix', $.extend(
202
+ {result: args.result, order: args.order, kernelMatrix: args.matrix},
203
+ args.settings || {}));
204
+ },
205
+
206
+ /* Add a diffuse lighting filter.
207
+ @param parent (element or jQuery) the parent node for the new filter (optional)
208
+ @param result (string) the ID of this filter
209
+ @param colour (string) the lighting colour (optional)
210
+ @param settings (object) additional settings for the filter (optional)
211
+ @return (element) the new filter node */
212
+ diffuseLighting: function(parent, result, colour, settings) {
213
+ var args = this._wrapper._args(arguments, ['result', 'colour'], ['colour']);
214
+ return this._wrapper._makeNode(args.parent, 'feDiffuseLighting',
215
+ $.extend($.extend({result: args.result},
216
+ (args.colour ? {lightingColor: args.colour} : {})), args.settings || {}));
217
+ },
218
+
219
+ /* Add a displacement map filter.
220
+ @param parent (element or jQuery) the parent node for the new filter (optional)
221
+ @param result (string) the ID of this filter
222
+ @param in1 (string) the source image
223
+ @param in2 (string) the displacement image
224
+ @param settings (object) additional settings for the filter (optional)
225
+ @return (element) the new filter node */
226
+ displacementMap: function(parent, result, in1, in2, settings) {
227
+ var args = this._wrapper._args(arguments, ['result', 'in1', 'in2']);
228
+ return this._wrapper._makeNode(args.parent, 'feDisplacementMap',
229
+ $.extend({result: args.result, in_: args.in1, in2: args.in2},
230
+ args.settings || {}));
231
+ },
232
+
233
+ /* Add a flood filter.
234
+ Specify all of x, y, width, height or none of them.
235
+ @param parent (element or jQuery) the parent node for the new filter (optional)
236
+ @param result (string) the ID of this filter
237
+ @param x (number) the left coordinate of the rectangle (optional)
238
+ @param y (number) the top coordinate of the rectangle (optional)
239
+ @param width (number) the width of the rectangle (optional)
240
+ @param height (number) the height of the rectangle (optional)
241
+ @param colour (string) the colour to fill with
242
+ @param opacity (number) the opacity 0.0-1.0
243
+ @param settings (object) additional settings for the filter (optional)
244
+ @return (element) the new filter node */
245
+ flood: function(parent, result, x, y, width, height, colour, opacity, settings) {
246
+ var args = this._wrapper._args(arguments,
247
+ ['result', 'x', 'y', 'width', 'height', 'colour', 'opacity']);
248
+ if (arguments.length < 6) {
249
+ args.colour = args.x;
250
+ args.opacity = args.y;
251
+ args.settings = args.width;
252
+ args.x = null;
253
+ }
254
+ var sets = $.extend({result: args.result, floodColor: args.colour,
255
+ floodOpacity: args.opacity}, (args.x != null ?
256
+ {x: args.x, y: args.y, width: args.width, height: args.height} : {}));
257
+ return this._wrapper._makeNode(args.parent, 'feFlood',
258
+ $.extend(sets, args.settings || {}));
259
+ },
260
+
261
+ /* Add a Gaussian blur filter.
262
+ @param parent (element or jQuery) the parent node for the new filter (optional)
263
+ @param result (string) the ID of this filter
264
+ @param in1 (string) the source filter
265
+ @param stdDevX (number) the standard deviation along the x-axis
266
+ @param stdDevY (number) the standard deviation along the y-axis (optional)
267
+ @param settings (object) additional settings for the filter (optional)
268
+ @return (element) the new filter node */
269
+ gaussianBlur: function(parent, result, in1, stdDevX, stdDevY, settings) {
270
+ var args = this._wrapper._args(arguments,
271
+ ['result', 'in1', 'stdDevX', 'stdDevY'], ['stdDevY']);
272
+ return this._wrapper._makeNode(args.parent, 'feGaussianBlur', $.extend(
273
+ {result: args.result, in_: args.in1, stdDeviation: args.stdDevX +
274
+ (args.stdDevY ? ' ' + args.stdDevY : '')}, args.settings || {}));
275
+ },
276
+
277
+ /* Add an image filter.
278
+ @param parent (element or jQuery) the parent node for the new filter (optional)
279
+ @param result (string) the ID of this filter
280
+ @param href (string) the URL of the image
281
+ @param settings (object) additional settings for the filter (optional)
282
+ @return (element) the new filter node */
283
+ image: function(parent, result, href, settings) {
284
+ var args = this._wrapper._args(arguments, ['result', 'href']);
285
+ var node = this._wrapper._makeNode(args.parent, 'feImage', $.extend(
286
+ {result: args.result}, args.settings || {}));
287
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.href);
288
+ return node;
289
+ },
290
+
291
+ /* Add a merge filter.
292
+ @param parent (element or jQuery) the parent node for the new filter (optional)
293
+ @param result (string) the ID of this filter
294
+ @param refs (string[]) the IDs of the filters to merge
295
+ @param settings (object) additional settings for the filter (optional)
296
+ @return (element) the new filter node */
297
+ merge: function(parent, result, refs, settings) {
298
+ var args = this._wrapper._args(arguments, ['result', 'refs']);
299
+ var node = this._wrapper._makeNode(args.parent, 'feMerge', $.extend(
300
+ {result: args.result}, args.settings || {}));
301
+ for (var i = 0; i < args.refs.length; i++) {
302
+ this._wrapper._makeNode(node, 'feMergeNode', {in_: args.refs[i]});
303
+ }
304
+ return node;
305
+ },
306
+
307
+ /* Add a morphology filter.
308
+ @param parent (element or jQuery) the parent node for the new filter (optional)
309
+ @param result (string) the ID of this filter
310
+ @param in1 (string) the source filter
311
+ @param operator (string) erode | dilate
312
+ @param radiusX (number) the size of the operation in the x-axis
313
+ @param radiusY (number) the size of the operation in the y-axis (optional)
314
+ @param settings (object) additional settings for the filter (optional)
315
+ @return (element) the new filter node */
316
+ morphology: function(parent, result, in1, operator, radiusX, radiusY, settings) {
317
+ var args = this._wrapper._args(arguments, ['result', 'in1',
318
+ 'operator', 'radiusX', 'radiusY'], ['radiusY']);
319
+ return this._wrapper._makeNode(args.parent, 'feMorphology', $.extend(
320
+ {result: args.result, in_: args.in1, operator: args.operator,
321
+ radius: args.radiusX + (args.radiusY ? ' ' + args.radiusY : '')},
322
+ args.settings || {}));
323
+ },
324
+
325
+ /* Add an offset filter.
326
+ @param parent (element or jQuery) the parent node for the new filter (optional)
327
+ @param result (string) the ID of this filter
328
+ @param in1 (string) the source filter
329
+ @param dX (number) the offset in the x-axis
330
+ @param dY (number) the offset in the y-axis
331
+ @param settings (object) additional settings for the filter (optional)
332
+ @return (element) the new filter node */
333
+ offset: function(parent, result, in1, dx, dy, settings) {
334
+ var args = this._wrapper._args(arguments, ['result', 'in1', 'dx', 'dy']);
335
+ return this._wrapper._makeNode(args.parent, 'feOffset', $.extend(
336
+ {result: args.result, in_: args.in1, dx: args.dx, dy: args.dy},
337
+ args.settings || {}));
338
+ },
339
+
340
+ /* Add a specular lighting filter.
341
+ Numeric params are only optional if following numeric params are also omitted.
342
+ @param parent (element or jQuery) the parent node for the new filter (optional)
343
+ @param result (string) the ID of this filter
344
+ @param in1 (string) the source filter
345
+ @param surfaceScale (number) the surface height when Ain = 1 (optional)
346
+ @param specularConstant (number) the ks in Phong lighting model (optional)
347
+ @param specularExponent (number) the shininess 1.0-128.0 (optional)
348
+ @param settings (object) additional settings for the filter (optional)
349
+ @return (element) the new filter node */
350
+ specularLighting: function(parent, result, in1, surfaceScale,
351
+ specularConstant, specularExponent, settings) {
352
+ var args = this._wrapper._args(arguments, ['result', 'in1',
353
+ 'surfaceScale', 'specularConstant', 'specularExponent'],
354
+ ['surfaceScale', 'specularConstant', 'specularExponent']);
355
+ return this._wrapper._makeNode(args.parent, 'feSpecularLighting', $.extend(
356
+ {result: args.result, in_: args.in1, surfaceScale: args.surfaceScale,
357
+ specularConstant: args.specularConstant, specularExponent: args.specularExponent},
358
+ args.settings || {}));
359
+ },
360
+
361
+ /* Add a tile filter.
362
+ @param parent (element or jQuery) the parent node for the new filter (optional)
363
+ @param result (string) the ID of this filter
364
+ @param in1 (string) the source filter
365
+ @param x (number) the left coordinate of the rectangle
366
+ @param y (number) the top coordinate of the rectangle
367
+ @param width (number) the width of the rectangle
368
+ @param height (number) the height of the rectangle
369
+ @param settings (object) additional settings for the filter (optional)
370
+ @return (element) the new filter node */
371
+ tile: function(parent, result, in1, x, y, width, height, settings) {
372
+ var args = this._wrapper._args(arguments,
373
+ ['result', 'in1', 'x', 'y', 'width', 'height']);
374
+ return this._wrapper._makeNode(args.parent, 'feTile', $.extend(
375
+ {result: args.result, in_: args.in1, x: args.x, y: args.y,
376
+ width: args.width, height: args.height}, args.settings || {}));
377
+ },
378
+
379
+ /* Add a turbulence filter.
380
+ @param parent (element or jQuery) the parent node for the new filter (optional)
381
+ @param result (string) the ID of this filter
382
+ @param type (string) fractalNoise | turbulence
383
+ @param baseFreq (number or 'number number') the base frequency,
384
+ optionally separated into x- and y-components
385
+ @param octaves (number) the amount of turbulence (optional)
386
+ @param settings (object) additional settings for the filter (optional)
387
+ @return (element) the new filter node */
388
+ turbulence: function(parent, result, type, baseFreq, octaves, settings) {
389
+ var args = this._wrapper._args(arguments, ['result', 'type',
390
+ 'baseFreq', 'octaves'], ['octaves']);
391
+ return this._wrapper._makeNode(args.parent, 'feTurbulence', $.extend(
392
+ {result: args.result, type: args.type, baseFrequency: args.baseFreq,
393
+ numOctaves: args.octaves}, args.settings || {}));
394
+ }
395
+ });
396
+
397
+ /* Determine whether an object is an array. */
398
+ function isArray(a) {
399
+ return (a && a.constructor == Array);
400
+ }
401
+
402
+ })(jQuery)