Improved docs for FX module, merging method descriptions and marking optional arguments
[jquery.git] / src / fx / fx.js
1 jQuery.fn.extend({\r
2 \r
3         // overwrite the old show method\r
4         _show: jQuery.fn.show,\r
5         \r
6         /**\r
7          * Show all matched elements using a graceful animation and firing an\r
8          * optional callback after completion.\r
9          *\r
10          * The height, width, and opacity of each of the matched elements \r
11          * are changed dynamically according to the specified speed.\r
12          *\r
13          * @example $("p").show("slow");\r
14          *\r
15          * @example $("p").show("slow",function(){\r
16          *   alert("Animation Done.");\r
17          * });\r
18          *\r
19          * @name show\r
20          * @type jQuery\r
21          * @param String|Number speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
22          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
23          * @cat Effects/Animations\r
24          * @see hide(String|Number,Function)\r
25          */\r
26         show: function(speed,callback){\r
27                 return speed ? this.animate({\r
28                         height: "show", width: "show", opacity: "show"\r
29                 }, speed, callback) : this._show();\r
30         },\r
31         \r
32         // Overwrite the old hide method\r
33         _hide: jQuery.fn.hide,\r
34         \r
35         /**\r
36          * Hide all matched elements using a graceful animation and firing an\r
37          * optional callback after completion.\r
38          *\r
39          * The height, width, and opacity of each of the matched elements \r
40          * are changed dynamically according to the specified speed.\r
41          *\r
42          * @example $("p").hide("slow");\r
43          *\r
44          * @example $("p").hide("slow",function(){\r
45          *   alert("Animation Done.");\r
46          * });\r
47          *\r
48          * @name hide\r
49          * @type jQuery\r
50          * @param String|Number speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
51          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
52          * @cat Effects/Animations\r
53          * @see show(String|Number,Function)\r
54          */\r
55         hide: function(speed,callback){\r
56                 return speed ? this.animate({\r
57                         height: "hide", width: "hide", opacity: "hide"\r
58                 }, speed, callback) : this._hide();\r
59         },\r
60         \r
61         /**\r
62          * Reveal all matched elements by adjusting their height and firing an\r
63          * optional callback after completion.\r
64          *\r
65          * Only the height is adjusted for this animation, causing all matched\r
66          * elements to be revealed in a "sliding" manner.\r
67          *\r
68          * @example $("p").slideDown("slow");\r
69          *\r
70          * @example $("p").slideDown("slow",function(){\r
71          *   alert("Animation Done.");\r
72          * });\r
73          *\r
74          * @name slideDown\r
75          * @type jQuery\r
76          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
77          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
78          * @cat Effects/Animations\r
79          */\r
80         slideDown: function(speed,callback){\r
81                 return this.animate({height: "show"}, speed, callback);\r
82         },\r
83         \r
84         /**\r
85          * Hide all matched elements by adjusting their height and firing an\r
86          * optional callback after completion.\r
87          *\r
88          * Only the height is adjusted for this animation, causing all matched\r
89          * elements to be hidden in a "sliding" manner.\r
90          *\r
91          * @example $("p").slideUp("slow");\r
92          *\r
93          * @example $("p").slideUp("slow",function(){\r
94          *   alert("Animation Done.");\r
95          * });\r
96          *\r
97          * @name slideUp\r
98          * @type jQuery\r
99          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
100          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
101          * @cat Effects/Animations\r
102          */\r
103         slideUp: function(speed,callback){\r
104                 return this.animate({height: "hide"}, speed, callback);\r
105         },\r
106 \r
107         /**\r
108          * Toggle the visibility of all matched elements by adjusting their height and firing an\r
109          * optional callback after completion.\r
110          *\r
111          * Only the height is adjusted for this animation, causing all matched\r
112          * elements to be hidden in a "sliding" manner.\r
113          *\r
114          * @example $("p").slideToggle("slow");\r
115          *\r
116          * @example $("p").slideToggle("slow",function(){\r
117          *   alert("Animation Done.");\r
118          * });\r
119          *\r
120          * @name slideToggle\r
121          * @type jQuery\r
122          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
123          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
124          * @cat Effects/Animations\r
125          */\r
126         slideToggle: function(speed,callback){\r
127                 return this.each(function(){\r
128                         var state = jQuery(this).is(":hidden") ? "show" : "hide";\r
129                         jQuery(this).animate({height: state}, speed, callback);\r
130                 });\r
131         },\r
132         \r
133         /**\r
134          * Fade in all matched elements by adjusting their opacity and firing an\r
135          * optional callback after completion.\r
136          *\r
137          * Only the opacity is adjusted for this animation, meaning that\r
138          * all of the matched elements should already have some form of height\r
139          * and width associated with them.\r
140          *\r
141          * @example $("p").fadeIn("slow");\r
142          *\r
143          * @example $("p").fadeIn("slow",function(){\r
144          *   alert("Animation Done.");\r
145          * });\r
146          *\r
147          * @name fadeIn\r
148          * @type jQuery\r
149          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
150          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
151          * @cat Effects/Animations\r
152          */\r
153         fadeIn: function(speed,callback){\r
154                 return this.animate({opacity: "show"}, speed, callback);\r
155         },\r
156         \r
157         /**\r
158          * Fade out all matched elements by adjusting their opacity and firing an\r
159          * optional callback after completion.\r
160          *\r
161          * Only the opacity is adjusted for this animation, meaning that\r
162          * all of the matched elements should already have some form of height\r
163          * and width associated with them.\r
164          *\r
165          * @example $("p").fadeOut("slow");\r
166          *\r
167          * @example $("p").fadeOut("slow",function(){\r
168          *   alert("Animation Done.");\r
169          * });\r
170          *\r
171          * @name fadeOut\r
172          * @type jQuery\r
173          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
174          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
175          * @cat Effects/Animations\r
176          */\r
177         fadeOut: function(speed,callback){\r
178                 return this.animate({opacity: "hide"}, speed, callback);\r
179         },\r
180         \r
181         /**\r
182          * Fade the opacity of all matched elements to a specified opacity and firing an\r
183          * optional callback after completion.\r
184          *\r
185          * Only the opacity is adjusted for this animation, meaning that\r
186          * all of the matched elements should already have some form of height\r
187          * and width associated with them.\r
188          *\r
189          * @example $("p").fadeTo("slow", 0.5);\r
190          *\r
191          * @example $("p").fadeTo("slow", 0.5, function(){\r
192          *   alert("Animation Done.");\r
193          * });\r
194          *\r
195          * @name fadeTo\r
196          * @type jQuery\r
197          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
198          * @param Number opacity The opacity to fade to (a number from 0 to 1).\r
199          * @param Function callback (optional) A function to be executed whenever the animation completes.\r
200          * @cat Effects/Animations\r
201          */\r
202         fadeTo: function(speed,to,callback){\r
203                 return this.animate({opacity: to}, speed, callback);\r
204         },\r
205         \r
206         /**\r
207          * A function for making your own, custom, animations. The key aspect of\r
208          * this function is the object of style properties that will be animated,\r
209          * and to what end. Each key within the object represents a style property\r
210          * that will also be animated (for example: "height", "top", or "opacity").\r
211          *\r
212          * The value associated with the key represents to what end the property\r
213          * will be animated. If a number is provided as the value, then the style\r
214          * property will be transitioned from its current state to that new number.\r
215          * Oterwise if the string "hide", "show", or "toggle" is provided, a default\r
216          * animation will be constructed for that property.\r
217          *\r
218          * @example $("p").animate({\r
219          *   height: 'toggle', opacity: 'toggle'\r
220          * }, "slow");\r
221          *\r
222          * @example $("p").animate({\r
223          *   left: 50, opacity: 'show'\r
224          * }, 500);\r
225          *\r
226          * @name animate\r
227          * @type jQuery\r
228          * @param Hash params A set of style attributes that you wish to animate, and to what end.\r
229          * @param Object speed A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).\r
230          * @param Function callback A function to be executed whenever the animation completes.\r
231          * @cat Effects/Animations\r
232          */\r
233         animate: function(prop,speed,callback) {\r
234                 return this.queue(function(){\r
235                 \r
236                         this.curAnim = jQuery.extend({}, prop);\r
237                         \r
238                         for ( var p in prop ) {\r
239                                 var e = new jQuery.fx( this, jQuery.speed(speed,callback), p );\r
240                                 if ( prop[p].constructor == Number )\r
241                                         e.custom( e.cur(), prop[p] );\r
242                                 else\r
243                                         e[ prop[p] ]( prop );\r
244                         }\r
245                         \r
246                 });\r
247         },\r
248         \r
249         /**\r
250          *\r
251          * @private\r
252          */\r
253         queue: function(type,fn){\r
254                 if ( !fn ) {\r
255                         fn = type;\r
256                         type = "fx";\r
257                 }\r
258         \r
259                 return this.each(function(){\r
260                         if ( !this.queue )\r
261                                 this.queue = {};\r
262         \r
263                         if ( !this.queue[type] )\r
264                                 this.queue[type] = [];\r
265         \r
266                         this.queue[type].push( fn );\r
267                 \r
268                         if ( this.queue[type].length == 1 )\r
269                                 fn.apply(this);\r
270                 });\r
271         }\r
272 \r
273 });\r
274 \r
275 jQuery.extend({\r
276         \r
277         speed: function(s,o) {\r
278                 o = o || {};\r
279                 \r
280                 if ( o.constructor == Function )\r
281                         o = { complete: o };\r
282                 \r
283                 var ss = { slow: 600, fast: 200 };\r
284                 o.duration = (s && s.constructor == Number ? s : ss[s]) || 400;\r
285         \r
286                 // Queueing\r
287                 o.oldComplete = o.complete;\r
288                 o.complete = function(){\r
289                         jQuery.dequeue(this, "fx");\r
290                         if ( o.oldComplete && o.oldComplete.constructor == Function )\r
291                                 o.oldComplete.apply( this );\r
292                 };\r
293         \r
294                 return o;\r
295         },\r
296         \r
297         queue: {},\r
298         \r
299         dequeue: function(elem,type){\r
300                 type = type || "fx";\r
301         \r
302                 if ( elem.queue && elem.queue[type] ) {\r
303                         // Remove self\r
304                         elem.queue[type].shift();\r
305         \r
306                         // Get next function\r
307                         var f = elem.queue[type][0];\r
308                 \r
309                         if ( f ) f.apply( elem );\r
310                 }\r
311         },\r
312 \r
313         /*\r
314          * I originally wrote fx() as a clone of moo.fx and in the process\r
315          * of making it small in size the code became illegible to sane\r
316          * people. You've been warned.\r
317          */\r
318         \r
319         fx: function( elem, options, prop ){\r
320 \r
321                 var z = this;\r
322 \r
323                 // The users options\r
324                 z.o = {\r
325                         duration: options.duration || 400,\r
326                         complete: options.complete,\r
327                         step: options.step\r
328                 };\r
329 \r
330                 // The element\r
331                 z.el = elem;\r
332 \r
333                 // The styles\r
334                 var y = z.el.style;\r
335                 \r
336                 // Store display property\r
337                 var oldDisplay = jQuery.css(z.el, 'display');\r
338                 // Set display property to block for animation\r
339                 y.display = "block";\r
340                 // Make sure that nothing sneaks out\r
341                 y.overflow = "hidden";\r
342 \r
343                 // Simple function for setting a style value\r
344                 z.a = function(){\r
345                         if ( options.step )\r
346                                 options.step.apply( elem, [ z.now ] );\r
347 \r
348                         if ( prop == "opacity" )\r
349                                 jQuery.attr(y, "opacity", z.now); // Let attr handle opacity\r
350                         else if ( parseInt(z.now) ) // My hate for IE will never die\r
351                                 y[prop] = parseInt(z.now) + "px";\r
352                 };\r
353 \r
354                 // Figure out the maximum number to run to\r
355                 z.max = function(){\r
356                         return parseFloat( jQuery.css(z.el,prop) );\r
357                 };\r
358 \r
359                 // Get the current size\r
360                 z.cur = function(){\r
361                         var r = parseFloat( jQuery.curCSS(z.el, prop) );\r
362                         return r && r > -10000 ? r : z.max();\r
363                 };\r
364 \r
365                 // Start an animation from one number to another\r
366                 z.custom = function(from,to){\r
367                         z.startTime = (new Date()).getTime();\r
368                         z.now = from;\r
369                         z.a();\r
370 \r
371                         z.timer = setInterval(function(){\r
372                                 z.step(from, to);\r
373                         }, 13);\r
374                 };\r
375 \r
376                 // Simple 'show' function\r
377                 z.show = function(){\r
378                         if ( !z.el.orig ) z.el.orig = {};\r
379 \r
380                         // Remember where we started, so that we can go back to it later\r
381                         z.el.orig[prop] = this.cur();\r
382 \r
383                         z.o.show = true;\r
384 \r
385                         // Begin the animation\r
386                         z.custom(0, z.el.orig[prop]);\r
387 \r
388                         // Stupid IE, look what you made me do\r
389                         if ( prop != "opacity" )\r
390                                 y[prop] = "1px";\r
391                 };\r
392 \r
393                 // Simple 'hide' function\r
394                 z.hide = function(){\r
395                         if ( !z.el.orig ) z.el.orig = {};\r
396 \r
397                         // Remember where we started, so that we can go back to it later\r
398                         z.el.orig[prop] = this.cur();\r
399 \r
400                         z.o.hide = true;\r
401 \r
402                         // Begin the animation\r
403                         z.custom(z.el.orig[prop], 0);\r
404                 };\r
405                 \r
406                 //Simple 'toggle' function\r
407                 z.toggle = function() {\r
408                         if ( !z.el.orig ) z.el.orig = {};\r
409 \r
410                         // Remember where we started, so that we can go back to it later\r
411                         z.el.orig[prop] = this.cur();\r
412 \r
413                         if(oldDisplay == 'none')  {\r
414                                 z.o.show = true;\r
415                                 \r
416                                 // Stupid IE, look what you made me do\r
417                                 if ( prop != "opacity" )\r
418                                         y[prop] = "1px";\r
419 \r
420                                 // Begin the animation\r
421                                 z.custom(0, z.el.orig[prop]);   \r
422                         } else {\r
423                                 z.o.hide = true;\r
424 \r
425                                 // Begin the animation\r
426                                 z.custom(z.el.orig[prop], 0);\r
427                         }               \r
428                 };\r
429 \r
430                 // Each step of an animation\r
431                 z.step = function(firstNum, lastNum){\r
432                         var t = (new Date()).getTime();\r
433 \r
434                         if (t > z.o.duration + z.startTime) {\r
435                                 // Stop the timer\r
436                                 clearInterval(z.timer);\r
437                                 z.timer = null;\r
438 \r
439                                 z.now = lastNum;\r
440                                 z.a();\r
441 \r
442                                 if (z.el.curAnim) z.el.curAnim[ prop ] = true;\r
443 \r
444                                 var done = true;\r
445                                 for ( var i in z.el.curAnim )\r
446                                         if ( z.el.curAnim[i] !== true )\r
447                                                 done = false;\r
448 \r
449                                 if ( done ) {\r
450                                         // Reset the overflow\r
451                                         y.overflow = '';\r
452                                         \r
453                                         // Reset the display\r
454                                         y.display = oldDisplay;\r
455                                         if (jQuery.css(z.el, 'display') == 'none')\r
456                                                 y.display = 'block';\r
457 \r
458                                         // Hide the element if the "hide" operation was done\r
459                                         if ( z.o.hide ) \r
460                                                 y.display = 'none';\r
461 \r
462                                         // Reset the properties, if the item has been hidden or shown\r
463                                         if ( z.o.hide || z.o.show )\r
464                                                 for ( var p in z.el.curAnim )\r
465                                                         if (p == "opacity")\r
466                                                                 jQuery.attr(y, p, z.el.orig[p]);\r
467                                                         else\r
468                                                                 y[p] = '';\r
469                                 }\r
470 \r
471                                 // If a callback was provided, execute it\r
472                                 if( done && z.o.complete && z.o.complete.constructor == Function )\r
473                                         // Execute the complete function\r
474                                         z.o.complete.apply( z.el );\r
475                         } else {\r
476                                 // Figure out where in the animation we are and set the number\r
477                                 var p = (t - this.startTime) / z.o.duration;\r
478                                 z.now = ((-Math.cos(p*Math.PI)/2) + 0.5) * (lastNum-firstNum) + firstNum;\r
479 \r
480                                 // Perform the next step of the animation\r
481                                 z.a();\r
482                         }\r
483                 };\r
484         \r
485         }\r
486 \r
487 });\r