source: products/qPloneTabs/trunk/skins/qPloneTabs/javascripts/effects.js @ 1

Last change on this file since 1 was 1, checked in by myroslav, 19 years ago

Building directory structure

File size: 30.7 KB
Line 
1// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2// Contributors:
3//  Justin Palmer (http://encytemedia.com/)
4//  Mark Pilgrim (http://diveintomark.org/)
5//  Martin Bialasinki
6//
7// See scriptaculous.js for full license. 
8
9/* ------------- element ext -------------- */ 
10 
11// converts rgb() and #xxx to #xxxxxx format, 
12// returns self (or first argument) if not convertable 
13String.prototype.parseColor = function() { 
14  color = "#"; 
15  if(this.slice(0,4) == "rgb(") { 
16    var cols = this.slice(4,this.length-1).split(','); 
17    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 
18  } else { 
19    if(this.slice(0,1) == '#') { 
20      if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 
21      if(this.length==7) color = this.toLowerCase(); 
22    } 
23  } 
24  return(color.length==7 ? color : (arguments[0] || this)); 
25} 
26
27Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { 
28  var children = $(element).childNodes; 
29  var text     = ""; 
30  var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i"); 
31 
32  for (var i = 0; i < children.length; i++) { 
33    if(children[i].nodeType==3) { 
34      text+=children[i].nodeValue; 
35    } else { 
36      if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) 
37        text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); 
38    } 
39  } 
40 
41  return text;
42}
43
44Element.setContentZoom = function(element, percent) { 
45  element = $(element); 
46  element.style.fontSize = (percent/100) + "em";   
47  if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); 
48}
49
50Element.getOpacity = function(element){ 
51  var opacity; 
52  if (opacity = Element.getStyle(element, "opacity")) 
53    return parseFloat(opacity); 
54  if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/)) 
55    if(opacity[1]) return parseFloat(opacity[1]) / 100; 
56  return 1.0; 
57}
58
59Element.setOpacity = function(element, value){ 
60  element= $(element); 
61  var els = element.style; 
62  if (value == 1){ 
63    els.opacity = '0.999999'; 
64    if(/MSIE/.test(navigator.userAgent)) 
65      els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,''); 
66  } else { 
67    if(value < 0.00001) value = 0; 
68    els.opacity = value; 
69    if(/MSIE/.test(navigator.userAgent)) 
70      els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + 
71        "alpha(opacity="+value*100+")"; 
72  }   
73} 
74 
75Element.getInlineOpacity = function(element){ 
76  element= $(element); 
77  var op; 
78  op = element.style.opacity; 
79  if (typeof op != "undefined" && op != "") return op; 
80  return ""; 
81} 
82 
83Element.setInlineOpacity = function(element, value){ 
84  element= $(element); 
85  var els = element.style; 
86  els.opacity = value; 
87} 
88 
89Element.childrenWithClassName = function(element, className) { 
90  return $A($(element).getElementsByTagName('*')).select(
91    function(c) { return Element.hasClassName(c, className) });
92} 
93 
94/*--------------------------------------------------------------------------*/
95
96var Effect = {
97  tagifyText: function(element) {
98    var tagifyStyle = "position:relative";
99    if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ";zoom:1";
100    element = $(element);
101    $A(element.childNodes).each( function(child) {
102      if(child.nodeType==3) {
103        child.nodeValue.toArray().each( function(character) {
104          element.insertBefore(
105            Builder.node('span',{style: tagifyStyle},
106              character == " " ? String.fromCharCode(160) : character), 
107              child);
108        });
109        Element.remove(child);
110      }
111    });
112  },
113  multiple: function(element, effect) {
114    var elements;
115    if(((typeof element == 'object') || 
116        (typeof element == 'function')) && 
117       (element.length))
118      elements = element;
119    else
120      elements = $(element).childNodes;
121     
122    var options = Object.extend({
123      speed: 0.1,
124      delay: 0.0
125    }, arguments[2] || {});
126    var speed = options.speed;
127    var delay = options.delay;
128
129    $A(elements).each( function(element, index) {
130      new effect(element, Object.extend(options, { delay: delay + index * speed }));
131    });
132  }
133};
134
135var Effect2 = Effect; // deprecated
136
137/* ------------- transitions ------------- */
138
139Effect.Transitions = {}
140
141Effect.Transitions.linear = function(pos) {
142  return pos;
143}
144Effect.Transitions.sinoidal = function(pos) {
145  return (-Math.cos(pos*Math.PI)/2) + 0.5;
146}
147Effect.Transitions.reverse  = function(pos) {
148  return 1-pos;
149}
150Effect.Transitions.flicker = function(pos) {
151  return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
152}
153Effect.Transitions.wobble = function(pos) {
154  return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
155}
156Effect.Transitions.pulse = function(pos) {
157  return (Math.floor(pos*10) % 2 == 0 ? 
158    (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
159}
160Effect.Transitions.none = function(pos) {
161  return 0;
162}
163Effect.Transitions.full = function(pos) {
164  return 1;
165}
166
167/* ------------- core effects ------------- */
168
169Effect.Queue = {
170  effects:  [],
171  _each: function(iterator) {
172    this.effects._each(iterator);
173  },
174  interval: null,
175  add: function(effect) {
176    var timestamp = new Date().getTime();
177   
178    switch(effect.options.queue) {
179      case 'front':
180        // move unstarted effects after this effect 
181        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
182            e.startOn  += effect.finishOn;
183            e.finishOn += effect.finishOn;
184          });
185        break;
186      case 'end':
187        // start effect after last queued effect has finished
188        timestamp = this.effects.pluck('finishOn').max() || timestamp;
189        break;
190    }
191   
192    effect.startOn  += timestamp;
193    effect.finishOn += timestamp;
194    this.effects.push(effect);
195    if(!this.interval) 
196      this.interval = setInterval(this.loop.bind(this), 40);
197  },
198  remove: function(effect) {
199    this.effects = this.effects.reject(function(e) { return e==effect });
200    if(this.effects.length == 0) {
201      clearInterval(this.interval);
202      this.interval = null;
203    }
204  },
205  loop: function() {
206    var timePos = new Date().getTime();
207    this.effects.invoke('loop', timePos);
208  }
209}
210Object.extend(Effect.Queue, Enumerable);
211
212Effect.Base = function() {};
213Effect.Base.prototype = {
214  position: null,
215  setOptions: function(options) {
216    this.options = Object.extend({
217      transition: Effect.Transitions.sinoidal,
218      duration:   1.0,   // seconds
219      fps:        25.0,  // max. 25fps due to Effect.Queue implementation
220      sync:       false, // true for combining
221      from:       0.0,
222      to:         1.0,
223      delay:      0.0,
224      queue:      'parallel'
225    }, options || {});
226  },
227  start: function(options) {
228    this.setOptions(options || {});
229    this.currentFrame = 0;
230    this.state        = 'idle';
231    this.startOn      = this.options.delay*1000;
232    this.finishOn     = this.startOn + (this.options.duration*1000);
233    this.event('beforeStart');
234    if(!this.options.sync) Effect.Queue.add(this);
235  },
236  loop: function(timePos) {
237    if(timePos >= this.startOn) {
238      if(timePos >= this.finishOn) {
239        this.render(1.0);
240        this.cancel();
241        this.event('beforeFinish');
242        if(this.finish) this.finish(); 
243        this.event('afterFinish');
244        return; 
245      }
246      var pos   = (timePos - this.startOn) / (this.finishOn - this.startOn);
247      var frame = Math.round(pos * this.options.fps * this.options.duration);
248      if(frame > this.currentFrame) {
249        this.render(pos);
250        this.currentFrame = frame;
251      }
252    }
253  },
254  render: function(pos) {
255    if(this.state == 'idle') {
256      this.state = 'running';
257      this.event('beforeSetup');
258      if(this.setup) this.setup();
259      this.event('afterSetup');
260    }
261    if(this.options.transition) pos = this.options.transition(pos);
262    pos *= (this.options.to-this.options.from);
263    pos += this.options.from;
264    this.position = pos;
265    this.event('beforeUpdate');
266    if(this.update) this.update(pos);
267    this.event('afterUpdate');
268  },
269  cancel: function() {
270    if(!this.options.sync) Effect.Queue.remove(this);
271    this.state = 'finished';
272  },
273  event: function(eventName) {
274    if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
275    if(this.options[eventName]) this.options[eventName](this);
276  }
277}
278
279Effect.Parallel = Class.create();
280Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
281  initialize: function(effects) {
282    this.effects = effects || [];
283    this.start(arguments[1]);
284  },
285  update: function(position) {
286    this.effects.invoke('render', position);
287  },
288  finish: function(position) {
289    this.effects.each( function(effect) {
290      effect.render(1.0);
291      effect.cancel();
292      effect.event('beforeFinish');
293      if(effect.finish) effect.finish(position);
294      effect.event('afterFinish');
295    });
296  }
297});
298
299Effect.Opacity = Class.create();
300Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
301  initialize: function(element) {
302    this.element = $(element);
303    // make this work on IE on elements without 'layout'
304    if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
305      this.element.style.zoom = 1;
306    var options = Object.extend({
307      from: Element.getOpacity(this.element) || 0.0,
308      to:   1.0
309    }, arguments[1] || {});
310    this.start(options);
311  },
312  update: function(position) {
313    Element.setOpacity(this.element, position);
314  }
315});
316
317Effect.MoveBy = Class.create();
318Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
319  initialize: function(element, toTop, toLeft) {
320    this.element      = $(element);
321    this.toTop        = toTop;
322    this.toLeft       = toLeft;
323    this.start(arguments[3]);
324  },
325  setup: function() {
326    // Bug in Opera: Opera returns the "real" position of a static element or
327    // relative element that does not have top/left explicitly set.
328    // ==> Always set top and left for position relative elements in your stylesheets
329    // (to 0 if you do not need them)
330   
331    Element.makePositioned(this.element);
332    this.originalTop  = parseFloat(Element.getStyle(this.element,'top')  || '0');
333    this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
334  },
335  update: function(position) {
336    var topd  = this.toTop  * position + this.originalTop;
337    var leftd = this.toLeft * position + this.originalLeft;
338    this.setPosition(topd, leftd);
339  },
340  setPosition: function(topd, leftd) {
341    this.element.style.top  = topd  + "px";
342    this.element.style.left = leftd + "px";
343  }
344});
345
346Effect.Scale = Class.create();
347Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
348  initialize: function(element, percent) {
349    this.element = $(element)
350    var options = Object.extend({
351      scaleX: true,
352      scaleY: true,
353      scaleContent: true,
354      scaleFromCenter: false,
355      scaleMode: 'box',        // 'box' or 'contents' or {} with provided values
356      scaleFrom: 100.0,
357      scaleTo:   percent
358    }, arguments[2] || {});
359    this.start(options);
360  },
361  setup: function() {
362    var effect = this;
363   
364    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
365    this.elementPositioning = Element.getStyle(this.element,'position');
366   
367    effect.originalStyle = {};
368    ['top','left','width','height','fontSize'].each( function(k) {
369      effect.originalStyle[k] = effect.element.style[k];
370    });
371     
372    this.originalTop  = this.element.offsetTop;
373    this.originalLeft = this.element.offsetLeft;
374   
375    var fontSize = Element.getStyle(this.element,'font-size') || "100%";
376    ['em','px','%'].each( function(fontSizeType) {
377      if(fontSize.indexOf(fontSizeType)>0) {
378        effect.fontSize     = parseFloat(fontSize);
379        effect.fontSizeType = fontSizeType;
380      }
381    });
382   
383    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
384   
385    this.dims = null;
386    if(this.options.scaleMode=='box')
387      this.dims = [this.element.clientHeight, this.element.clientWidth];
388    if(/^content/.test(this.options.scaleMode))
389      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
390    if(!this.dims)
391      this.dims = [this.options.scaleMode.originalHeight,
392                   this.options.scaleMode.originalWidth];
393  },
394  update: function(position) {
395    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
396    if(this.options.scaleContent && this.fontSize)
397      this.element.style.fontSize = this.fontSize*currentScale + this.fontSizeType;
398    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
399  },
400  finish: function(position) {
401    if (this.restoreAfterFinish) {
402      var effect = this;
403      ['top','left','width','height','fontSize'].each( function(k) {
404        effect.element.style[k] = effect.originalStyle[k];
405      });
406    }
407  },
408  setDimensions: function(height, width) {
409    var els = this.element.style;
410    if(this.options.scaleX) els.width = width + 'px';
411    if(this.options.scaleY) els.height = height + 'px';
412    if(this.options.scaleFromCenter) {
413      var topd  = (height - this.dims[0])/2;
414      var leftd = (width  - this.dims[1])/2;
415      if(this.elementPositioning == 'absolute') {
416        if(this.options.scaleY) els.top = this.originalTop-topd + "px";
417        if(this.options.scaleX) els.left = this.originalLeft-leftd + "px";
418      } else {
419        if(this.options.scaleY) els.top = -topd + "px";
420        if(this.options.scaleX) els.left = -leftd + "px";
421      }
422    }
423  }
424});
425
426Effect.Highlight = Class.create();
427Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
428  initialize: function(element) {
429    this.element = $(element);
430    var options = Object.extend({
431      startcolor:   "#ffff99"
432    }, arguments[1] || {});
433    this.start(options);
434  },
435  setup: function() {
436    // Prevent executing on elements not in the layout flow
437    if(this.element.style.display=='none') { this.cancel(); return; }
438    // Disable background image during the effect
439    this.oldBgImage = this.element.style.backgroundImage;
440    this.element.style.backgroundImage = "none";
441    if(!this.options.endcolor)
442      this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
443    if (typeof this.options.restorecolor == "undefined")
444      this.options.restorecolor = this.element.style.backgroundColor;
445    // init color calculations
446    this.colors_base = [
447      parseInt(this.options.startcolor.slice(1,3),16),
448      parseInt(this.options.startcolor.slice(3,5),16),
449      parseInt(this.options.startcolor.slice(5),16) ];
450    this.colors_delta = [
451      parseInt(this.options.endcolor.slice(1,3),16)-this.colors_base[0],
452      parseInt(this.options.endcolor.slice(3,5),16)-this.colors_base[1],
453      parseInt(this.options.endcolor.slice(5),16)-this.colors_base[2]];
454  },
455  update: function(position) {
456    var effect = this; var colors = $R(0,2).map( function(i){ 
457      return Math.round(effect.colors_base[i]+(effect.colors_delta[i]*position))
458    });
459    this.element.style.backgroundColor = "#" +
460      colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart();
461  },
462  finish: function() {
463    this.element.style.backgroundColor = this.options.restorecolor;
464    this.element.style.backgroundImage = this.oldBgImage;
465  }
466});
467
468Effect.ScrollTo = Class.create();
469Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
470  initialize: function(element) {
471    this.element = $(element);
472    this.start(arguments[1] || {});
473  },
474  setup: function() {
475    Position.prepare();
476    var offsets = Position.cumulativeOffset(this.element);
477    var max = window.innerHeight ? 
478      window.height - window.innerHeight :
479      document.body.scrollHeight - 
480        (document.documentElement.clientHeight ? 
481          document.documentElement.clientHeight : document.body.clientHeight);
482    this.scrollStart = Position.deltaY;
483    this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
484  },
485  update: function(position) {
486    Position.prepare();
487    window.scrollTo(Position.deltaX, 
488      this.scrollStart + (position*this.delta));
489  }
490});
491
492/* ------------- combination effects ------------- */
493
494Effect.Fade = function(element) {
495  var oldOpacity = Element.getInlineOpacity(element);
496  var options = Object.extend({
497  from: Element.getOpacity(element) || 1.0,
498  to:   0.0,
499  afterFinishInternal: function(effect) 
500    { if (effect.options.to == 0) {
501        Element.hide(effect.element);
502        Element.setInlineOpacity(effect.element, oldOpacity);
503      } 
504    }
505  }, arguments[1] || {});
506  return new Effect.Opacity(element,options);
507}
508
509Effect.Appear = function(element) {
510  var options = Object.extend({
511  from: (Element.getStyle(element, "display") == "none" ? 0.0 : Element.getOpacity(element) || 0.0),
512  to:   1.0,
513  beforeSetup: function(effect) 
514    { Element.setOpacity(effect.element, effect.options.from);
515      Element.show(effect.element); }
516  }, arguments[1] || {});
517  return new Effect.Opacity(element,options);
518}
519
520Effect.Puff = function(element) {
521  element = $(element);
522  var oldOpacity = Element.getInlineOpacity(element);
523  var oldPosition = element.style.position;
524  return new Effect.Parallel(
525   [ new Effect.Scale(element, 200, 
526      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
527     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
528     Object.extend({ duration: 1.0, 
529      beforeSetupInternal: function(effect) 
530       { effect.effects[0].element.style.position = 'absolute'; },
531      afterFinishInternal: function(effect)
532       { Element.hide(effect.effects[0].element);
533         effect.effects[0].element.style.position = oldPosition;
534         Element.setInlineOpacity(effect.effects[0].element, oldOpacity); }
535     }, arguments[1] || {})
536   );
537}
538
539Effect.BlindUp = function(element) {
540  element = $(element);
541  Element.makeClipping(element);
542  return new Effect.Scale(element, 0, 
543    Object.extend({ scaleContent: false, 
544      scaleX: false, 
545      restoreAfterFinish: true,
546      afterFinishInternal: function(effect)
547        { 
548          Element.hide(effect.element);
549          Element.undoClipping(effect.element);
550        } 
551    }, arguments[1] || {})
552  );
553}
554
555Effect.BlindDown = function(element) {
556  element = $(element);
557  var oldHeight = element.style.height;
558  var elementDimensions = Element.getDimensions(element);
559  return new Effect.Scale(element, 100, 
560    Object.extend({ scaleContent: false, 
561      scaleX: false,
562      scaleFrom: 0,
563      scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
564      restoreAfterFinish: true,
565      afterSetup: function(effect) {
566        Element.makeClipping(effect.element);
567        effect.element.style.height = "0px";
568        Element.show(effect.element); 
569      }, 
570      afterFinishInternal: function(effect) {
571        Element.undoClipping(effect.element);
572        effect.element.style.height = oldHeight;
573      }
574    }, arguments[1] || {})
575  );
576}
577
578Effect.SwitchOff = function(element) {
579  element = $(element);
580  var oldOpacity = Element.getInlineOpacity(element);
581  return new Effect.Appear(element, { 
582    duration: 0.4,
583    from: 0,
584    transition: Effect.Transitions.flicker,
585    afterFinishInternal: function(effect) {
586      new Effect.Scale(effect.element, 1, { 
587        duration: 0.3, scaleFromCenter: true,
588        scaleX: false, scaleContent: false, restoreAfterFinish: true,
589        beforeSetup: function(effect) { 
590          Element.makePositioned(effect.element); 
591          Element.makeClipping(effect.element);
592        },
593        afterFinishInternal: function(effect) { 
594          Element.hide(effect.element); 
595          Element.undoClipping(effect.element);
596          Element.undoPositioned(effect.element);
597          Element.setInlineOpacity(effect.element, oldOpacity);
598        }
599      })
600    }
601  });
602}
603
604Effect.DropOut = function(element) {
605  element = $(element);
606  var oldTop = element.style.top;
607  var oldLeft = element.style.left;
608  var oldOpacity = Element.getInlineOpacity(element);
609  return new Effect.Parallel(
610    [ new Effect.MoveBy(element, 100, 0, { sync: true }), 
611      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
612    Object.extend(
613      { duration: 0.5,
614        beforeSetup: function(effect) { 
615          Element.makePositioned(effect.effects[0].element); },
616        afterFinishInternal: function(effect) { 
617          Element.hide(effect.effects[0].element); 
618          Element.undoPositioned(effect.effects[0].element);
619          effect.effects[0].element.style.left = oldLeft;
620          effect.effects[0].element.style.top = oldTop;
621          Element.setInlineOpacity(effect.effects[0].element, oldOpacity); } 
622      }, arguments[1] || {}));
623}
624
625Effect.Shake = function(element) {
626  element = $(element);
627  var oldTop = element.style.top;
628  var oldLeft = element.style.left;
629  return new Effect.MoveBy(element, 0, 20, 
630    { duration: 0.05, afterFinishInternal: function(effect) {
631  new Effect.MoveBy(effect.element, 0, -40, 
632    { duration: 0.1, afterFinishInternal: function(effect) {
633  new Effect.MoveBy(effect.element, 0, 40, 
634    { duration: 0.1, afterFinishInternal: function(effect) {
635  new Effect.MoveBy(effect.element, 0, -40, 
636    { duration: 0.1, afterFinishInternal: function(effect) {
637  new Effect.MoveBy(effect.element, 0, 40, 
638    { duration: 0.1, afterFinishInternal: function(effect) {
639  new Effect.MoveBy(effect.element, 0, -20, 
640    { duration: 0.05, afterFinishInternal: function(effect) {
641        Element.undoPositioned(effect.element);
642        effect.element.style.left = oldLeft;
643        effect.element.style.top = oldTop;
644  }}) }}) }}) }}) }}) }});
645}
646
647Effect.SlideDown = function(element) {
648  element = $(element);
649  Element.cleanWhitespace(element);
650  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
651  var oldInnerBottom = element.firstChild.style.bottom;
652  var elementDimensions = Element.getDimensions(element);
653  return new Effect.Scale(element, 100, 
654   Object.extend({ scaleContent: false, 
655    scaleX: false, 
656    scaleFrom: 0,
657    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},   
658    restoreAfterFinish: true,
659    afterSetup: function(effect) {
660      Element.makePositioned(effect.element.firstChild);
661      if (window.opera) effect.element.firstChild.style.top = "";
662      Element.makeClipping(effect.element);
663      element.style.height = '0';
664      Element.show(element); 
665    }, 
666    afterUpdateInternal: function(effect) { 
667      effect.element.firstChild.style.bottom = 
668        (effect.dims[0] - effect.element.clientHeight) + 'px'; },
669    afterFinishInternal: function(effect) { 
670      Element.undoClipping(effect.element); 
671      Element.undoPositioned(effect.element.firstChild);
672      effect.element.firstChild.style.bottom = oldInnerBottom; }
673    }, arguments[1] || {})
674  );
675}
676 
677Effect.SlideUp = function(element) {
678  element = $(element);
679  Element.cleanWhitespace(element);
680  var oldInnerBottom = element.firstChild.style.bottom;
681  return new Effect.Scale(element, 0, 
682   Object.extend({ scaleContent: false, 
683    scaleX: false, 
684    scaleMode: 'box',
685    scaleFrom: 100,
686    restoreAfterFinish: true,
687    beforeStartInternal: function(effect) { 
688      Element.makePositioned(effect.element.firstChild);
689      if (window.opera) effect.element.firstChild.style.top = "";
690      Element.makeClipping(effect.element);
691      Element.show(element); 
692    }, 
693    afterUpdateInternal: function(effect) { 
694     effect.element.firstChild.style.bottom = 
695       (effect.dims[0] - effect.element.clientHeight) + 'px'; },
696    afterFinishInternal: function(effect) { 
697        Element.hide(effect.element);
698        Element.undoClipping(effect.element); 
699        Element.undoPositioned(effect.element.firstChild);
700        effect.element.firstChild.style.bottom = oldInnerBottom; }
701   }, arguments[1] || {})
702  );
703}
704
705Effect.Squish = function(element) {
706  // Bug in opera makes the TD containing this element expand for a instance after finish
707  return new Effect.Scale(element, window.opera ? 1 : 0, 
708    { restoreAfterFinish: true,
709      beforeSetup: function(effect) { 
710        Element.makeClipping(effect.element); }, 
711      afterFinishInternal: function(effect) { 
712        Element.hide(effect.element); 
713        Element.undoClipping(effect.element); } 
714  });
715}
716
717Effect.Grow = function(element) {
718  element = $(element);
719  var options = arguments[1] || {};
720 
721  var elementDimensions = Element.getDimensions(element);
722  var originalWidth = elementDimensions.width;
723  var originalHeight = elementDimensions.height;
724  var oldTop = element.style.top;
725  var oldLeft = element.style.left;
726  var oldHeight = element.style.height;
727  var oldWidth = element.style.width;
728  var oldOpacity = Element.getInlineOpacity(element);
729 
730  var direction = options.direction || 'center';
731  var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
732  var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
733  var opacityTransition = options.opacityTransition || Effect.Transitions.full;
734 
735  var initialMoveX, initialMoveY;
736  var moveX, moveY;
737 
738  switch (direction) {
739    case 'top-left':
740      initialMoveX = initialMoveY = moveX = moveY = 0; 
741      break;
742    case 'top-right':
743      initialMoveX = originalWidth;
744      initialMoveY = moveY = 0;
745      moveX = -originalWidth;
746      break;
747    case 'bottom-left':
748      initialMoveX = moveX = 0;
749      initialMoveY = originalHeight;
750      moveY = -originalHeight;
751      break;
752    case 'bottom-right':
753      initialMoveX = originalWidth;
754      initialMoveY = originalHeight;
755      moveX = -originalWidth;
756      moveY = -originalHeight;
757      break;
758    case 'center':
759      initialMoveX = originalWidth / 2;
760      initialMoveY = originalHeight / 2;
761      moveX = -originalWidth / 2;
762      moveY = -originalHeight / 2;
763      break;
764  }
765 
766  return new Effect.MoveBy(element, initialMoveY, initialMoveX, { 
767    duration: 0.01, 
768    beforeSetup: function(effect) { 
769      Element.hide(effect.element);
770      Element.makeClipping(effect.element);
771      Element.makePositioned(effect.element);
772    },
773    afterFinishInternal: function(effect) {
774      new Effect.Parallel(
775        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }),
776          new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: moveTransition }),
777          new Effect.Scale(effect.element, 100, {
778            scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth }, 
779            sync: true, scaleFrom: window.opera ? 1 : 0, transition: scaleTransition, restoreAfterFinish: true})
780        ], Object.extend({
781             beforeSetup: function(effect) {
782              effect.effects[0].element.style.height = 0;
783              Element.show(effect.effects[0].element);
784             },             
785             afterFinishInternal: function(effect) {
786               var el = effect.effects[0].element;
787               var els = el.style;
788               Element.undoClipping(el); 
789               Element.undoPositioned(el);
790               els.top = oldTop;
791               els.left = oldLeft;
792               els.height = oldHeight;
793               els.width = originalWidth + 'px';
794               Element.setInlineOpacity(el, oldOpacity);
795             }
796           }, options)
797      )
798    }
799  });
800}
801
802Effect.Shrink = function(element) {
803  element = $(element);
804  var options = arguments[1] || {};
805 
806  var originalWidth = element.clientWidth;
807  var originalHeight = element.clientHeight;
808  var oldTop = element.style.top;
809  var oldLeft = element.style.left;
810  var oldHeight = element.style.height;
811  var oldWidth = element.style.width;
812  var oldOpacity = Element.getInlineOpacity(element);
813
814  var direction = options.direction || 'center';
815  var moveTransition = options.moveTransition || Effect.Transitions.sinoidal;
816  var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal;
817  var opacityTransition = options.opacityTransition || Effect.Transitions.none;
818 
819  var moveX, moveY;
820 
821  switch (direction) {
822    case 'top-left':
823      moveX = moveY = 0;
824      break;
825    case 'top-right':
826      moveX = originalWidth;
827      moveY = 0;
828      break;
829    case 'bottom-left':
830      moveX = 0;
831      moveY = originalHeight;
832      break;
833    case 'bottom-right':
834      moveX = originalWidth;
835      moveY = originalHeight;
836      break;
837    case 'center': 
838      moveX = originalWidth / 2;
839      moveY = originalHeight / 2;
840      break;
841  }
842 
843  return new Effect.Parallel(
844    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: opacityTransition }),
845      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: scaleTransition, restoreAfterFinish: true}),
846      new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition })
847    ], Object.extend({           
848         beforeStartInternal: function(effect) { 
849           Element.makePositioned(effect.effects[0].element);
850           Element.makeClipping(effect.effects[0].element);
851         },
852         afterFinishInternal: function(effect) {
853           var el = effect.effects[0].element;
854           var els = el.style;
855           Element.hide(el);
856           Element.undoClipping(el); 
857           Element.undoPositioned(el);
858           els.top = oldTop;
859           els.left = oldLeft;
860           els.height = oldHeight;
861           els.width = oldWidth;
862           Element.setInlineOpacity(el, oldOpacity);
863         }
864       }, options)
865  );
866}
867
868Effect.Pulsate = function(element) {
869  element = $(element);
870  var options    = arguments[1] || {};
871  var oldOpacity = Element.getInlineOpacity(element);
872  var transition = options.transition || Effect.Transitions.sinoidal;
873  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
874  reverser.bind(transition);
875  return new Effect.Opacity(element, 
876    Object.extend(Object.extend({  duration: 3.0, from: 0,
877      afterFinishInternal: function(effect) { Element.setInlineOpacity(effect.element, oldOpacity); }
878    }, options), {transition: reverser}));
879}
880
881Effect.Fold = function(element) {
882  element = $(element);
883  var originalTop = element.style.top;
884  var originalLeft = element.style.left;
885  var originalWidth = element.style.width;
886  var originalHeight = element.style.height;
887  Element.makeClipping(element);
888  return new Effect.Scale(element, 5, Object.extend({   
889    scaleContent: false,
890    scaleX: false,
891    afterFinishInternal: function(effect) {
892    new Effect.Scale(element, 1, { 
893      scaleContent: false, 
894      scaleY: false,
895      afterFinishInternal: function(effect) { 
896        Element.hide(effect.element); 
897        Element.undoClipping(effect.element); 
898        effect.element.style.top = originalTop;
899        effect.element.style.left = originalLeft;
900        effect.element.style.width = originalWidth;
901        effect.element.style.height = originalHeight;
902      } });
903  }}, arguments[1] || {}));
904}
Note: See TracBrowser for help on using the repository browser.