// script.aculo.us effects.js v1.7.1_beta2, Tue May 15 15:15:45 EDT 2007
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/
// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor =
function () {
var color =
'#' ;
if (
this .slice(0,4) ==
'rgb(' ) {
var cols =
this .slice(4,
this .length-1).split(
',' );
var i=0;
do { color += parseInt(cols[i]).toColorPart() }
while (++i<3);
}
else {
if (
this .slice(0,1) ==
'#' ) {
if (
this .length==4)
for (
var i=1;i<4;i++) color += (
this .charAt(i) +
this .charAt(i)).toLow
erCase();
if (this .length==7) color = this .toLowerCase();
}
}
return (color.length==7 ? color : (arguments[0] || this ));
}
/*--------------------------------------------------------------------------*/
Element.collectTextNodes = function (element) {
return $A($(element).childNodes).collect( function (node) {
return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : '' ));
}).flatten().join('' );
}
Element.collectTextNodesIgnoreClass = function (element, className) {
return $A($(element).childNodes).collect( function (node) {
return (node.nodeType==3 ? node.nodeValue :
((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : '' ));
}).flatten().join('' );
}
Element.setContentZoom = function (element, percent) {
element = $(element);
element.setStyle({fontSize: (percent/100) + 'em' });
if (Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
}
Element.getInlineOpacity = function (element){
return $(element).style.opacity || '' ;
}
Element.forceRerendering = function (element) {
try {
element = $(element);
var n = document.createTextNode(' ' );
element.appendChild(n);
element.removeChild(n);
} catch (e) { }
};
/*--------------------------------------------------------------------------*/
Array.prototype.call = function () {
var args = arguments;
this .each(function (f){ f.apply(this , args) });
}
/*--------------------------------------------------------------------------*/
var Effect = {
_elementDoesNotExistError: {
name: 'ElementDoesNotExistError' ,
message: 'The specified DOM element does not exist, but is required for this effect to operate'
},
tagifyText: function (element) {
if (typeof Builder == 'undefined' )
throw ("Effect.tagifyText requires including script.aculo.us' builder.js library" );
var tagifyStyle = 'position:relative' ;
if (Prototype.Browser.IE) tagifyStyle += ';zoom:1' ;
element = $(element);
$A(element.childNodes).each( function (child) {
if (child.nodeType==3) {
child.nodeValue.toArray().each( function (character) {
element.insertBefore(
Builder.node('span' ,{style: tagifyStyle},
character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
}
});
},
multiple: function (element, effect) {
var elements;
if (((typeof element == 'object' ) ||
(typeof element == 'function' )) &&
(element.length))
elements = element;
else
elements = $(element).childNodes;
var options = Object.extend({
speed: 0.1,
delay: 0.0
}, arguments[2] || {});
var masterDelay = options.delay;
$A(elements).each( function (element, index) {
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
});
},
PAIRS: {
'slide' : ['SlideDown' ,'SlideUp' ],
'blind' : ['BlindDown' ,'BlindUp' ],
'appear' : ['Appear' ,'Fade' ]
},
toggle: function (element, effect) {
element = $(element);
effect = (effect || 'appear' ).toLowerCase();
var options = Object.extend({
queue: { position:'end' , scope:(element.id || 'global' ), limit: 1 }
}, arguments[2] || {});
Effect[element.visible() ?
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
}
};
var Effect2 = Effect; // deprecated
/* ------------- transitions ------------- */
Effect.Transitions = {
linear: Prototype.K,
sinoidal: function (pos) {
return (-Math.cos(pos*Math.PI)/2) + 0.5;
},
reverse: function (pos) {
return 1-pos;
},
flicker: function (pos) {
var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
return (pos > 1 ? 1 : pos);
},
wobble: function (pos) {
return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
},
pulse: function (pos, pulses) {
pulses = pulses || 5;
return (
Math.round((pos % (1/pulses)) * pulses) == 0 ?
((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
);
},
none: function (pos) {
return 0;
},
full: function (pos) {
return 1;
}
};
/* ------------- core effects ------------- */
Effect.ScopedQueue = Class .create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
initialize: function () {
this .effects = [];
this .interval = null ;
},
_each: function (iterator) {
this .effects._each(iterator);
},
add: function (effect) {
var timestamp = new Date().getTime();
var position = (typeof effect.options.queue == 'string' ) ?
effect.options.queue : effect.options.queue.position;
switch (position) {
case 'front' :
// move unstarted effects after this effect
this .effects.findAll(function (e){ return e.state=='idle' }).each( function (e) {
e.startOn += effect.finishOn;
e.finishOn += effect.finishOn;
});
break ;
case 'with-last' :
timestamp = this .effects.pluck('startOn' ).max() || timestamp;
break ;
case 'end' :
// start effect after last queued effect has finished
timestamp = this .effects.pluck('finishOn' ).max() || timestamp;
break ;
}
effect.startOn += timestamp;
effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this .effects.length < effect.options.queue.limit))
this .effects.push(effect);
if (!this .interval)
this .interval = setInterval(this .loop.bind(this ), 15);
},
remove: function (effect) {
this .effects = this .effects.reject(function (e) { return e==effect });
if (this .effects.length == 0) {
clearInterval(this .interval);
this .interval = null ;
}
},
loop: function () {
var timePos = new Date().getTime();
for (var i=0, len=this .effects.length;i<len;i++)
this .effects[i] && this .effects[i].loop(timePos);
}
});
Effect.Queues = {
instances: $H(),
get: function (queueName) {
if (typeof queueName != 'string' ) return queueName;
if (!this .instances[queueName])
this .instances[queueName] = new Effect.ScopedQueue();
return this .instances[queueName];
}
}
Effect.Queue = Effect.Queues.get('global' );
Effect.DefaultOptions = {
transition: Effect.Transitions.sinoidal,
duration: 1.0, // seconds
fps: 100, // 100= assume 66fps max.
sync: false , // true for combining
from: 0.0,
to: 1.0,
delay: 0.0,
queue: 'parallel'
}
Effect.Base = function () {};
Effect.Base.prototype = {
position: null ,
start: function (options) {
function codeForEvent(options,eventName){
return (
(options[eventName+'Internal' ] ? 'this.options.' +eventName+'Internal(this);' : '' ) +
(options[eventName] ? 'this.options.' +eventName+'(this);' : '' )
);
}
if (options.transition === false ) options.transition = Effect.Transitions.linear;
this .options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
this .currentFrame = 0;
this .state = 'idle' ;
this .startOn = this .options.delay*1000;
this .finishOn = this .startOn+(this .options.duration*1000);
this .fromToDelta = this .options.to-this.options.from;
this .totalTime = this .finishOn-this.startOn;
this .totalFrames = this .options.fps*this .options.duration;
eval('this.render = function(pos){ ' +
'if(this.state=="idle"){this.state="running";' +
codeForEvent(options,'beforeSetup' )+
(this .setup ? 'this.setup();' :'' )+
codeForEvent(options,'afterSetup' )+
'};if(this.state=="running"){' +
'pos=this.options.transition(pos)*' +this .fromToDelta+'+' +this .options.from+';' +
'this.position=pos;' +
codeForEvent(options,'beforeUpdate' )+
(this .update ? 'this.update(pos);' :'' )+
codeForEvent(options,'afterUpdate' )+
'}}' );
this .event('beforeStart' );
if (!this .options.sync)
Effect.Queues.get(typeof this .options.queue == 'string' ?
'global' : this .options.queue.scope).add(this );
},
loop: function (timePos) {
if (timePos >= this .startOn) {
if (timePos >= this .finishOn) {
this .render(1.0);
this .cancel();
this .event('beforeFinish' );
if (this .finish) this .finish();
this .event('afterFinish' );
return ;
}
var pos = (timePos - this .startOn) / this .totalTime,
frame = Math.round(pos * this .totalFrames);
if (frame > this .currentFrame) {
this .render(pos);
this .currentFrame = frame;
}
}
},
cancel: function () {
if (!this .options.sync)
Effect.Queues.get(typeof this .options.queue == 'string' ?
'global' : this .options.queue.scope).remove(this );
this .state = 'finished' ;
},
event: function (eventName) {
if (this .options[eventName + 'Internal' ]) this .options[eventName + 'Internal' ](this );
if (this .options[eventName]) this .options[eventName](this );
},
inspect: function () {
var data = $H();
for (property in this )
if (typeof this [property] != 'function' ) data[property] = this [property];
return '# + data.inspect() + ',options:' + $H(this .options).inspect() + '>' ;
}
}
Effect.Parallel = Class .create();
Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
initialize: function (effects) {
this .effects = effects || [];
this .start(arguments[1]);
},
update: function (position) {
this .effects.invoke('render' , position);
},
finish: function (position) {
this .effects.each( function (effect) {
effect.render(1.0);
effect.cancel();
effect.event('beforeFinish' );
if (effect.finish) effect.finish(position);
effect.event('afterFinish' );
});
}
});
Effect.Event = Class .create();
Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
initialize: function () {
var options = Object.extend({
duration: 0
}, arguments[0] || {});
this .start(options);
},
update: Prototype.emptyFunction
});
Effect.Opacity = Class .create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
initialize: function (element) {
this .element = $(element);
if (!this .element) throw (Effect._elementDoesNotExistError);
// make this work on IE on elements without 'layout'
if (Prototype.Browser.IE && (!this .element.currentStyle.hasLayout))
this .element.setStyle({zoom: 1});
var options = Object.extend({
from: this .element.getOpacity() || 0.0,
to: 1.0
}, arguments[1] || {});
this .start(options);
},
update: function (position) {
this .element.setOpacity(position);
}
});
Effect.Move = Class .create();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
initialize: function (element) {
this .element = $(element);
if (!this .element) throw (Effect._elementDoesNotExistError);
var options = Object.extend({
x: 0,
y: 0,
mode: 'relative'
}, arguments[1] || {});
this .start(options);
},
setup: function () {
// Bug in Opera: Opera returns the "real" position of a static element or
// relative element that does not have top/left explicitly set.
// ==> Always set top and left for position relative elements in your stylesheets
// (to 0 if you do not need them)
this .element.makePositioned();
this .originalLeft = parseFloat(this .element.getStyle('left' ) || '0' );
this .originalTop = parseFloat(this .element.getStyle('top' ) || '0' );
if (this .options.mode == 'absolute' ) {
// absolute movement, so we need to calc deltaX and deltaY
this .options.x = this .options.x - this .originalLeft;
this .options.y = this .options.y - this .originalTop;
}
},
update: function (position) {
this .element.setStyle({
left: Math.round(this .options.x * position + this .originalLeft) + 'px' ,
top: Math.round(this .options.y * position + this .originalTop) + 'px'
});
}
});
// for backwards compatibility
Effect.MoveBy = function (element, toTop, toLeft) {
return new Effect.Move(element,
Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
};
Effect.Scale = Class .create();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
initialize: function (element, percent) {
this .element = $(element);
if (!this .element) throw (Effect._elementDoesNotExistError);
var options = Object.extend({
scaleX: true ,
scaleY: true ,
scaleContent: true ,
scaleFromCenter: false ,
scaleMode: 'box' , // 'box' or 'contents' or {} with provided values
scaleFrom: 100.0,
scaleTo: percent
}, arguments[2] || {});
this .start(options);
},
setup: function () {
this .restoreAfterFinish = this .options.restoreAfterFinish || false ;
this .elementPositioning = this .element.getStyle('position' );
this .originalStyle = {};
['top' ,'left' ,'width' ,'height' ,'fontSize' ].each( function (k) {
this .originalStyle[k] = this .element.style[k];
}.bind(this ));
this .originalTop = this .element.offsetTop;
this .originalLeft = this .element.offsetLeft;
var fontSize = this .element.getStyle('font-size' ) || '100%' ;
['em' ,'px' ,'%' ,'pt' ].each( function (fontSizeType) {
if (fontSize.indexOf(fontSizeType)>0) {
this .fontSize = parseFloat(fontSize);
this .fontSizeType = fontSizeType;
}
}.bind(this ));
this .factor = (this .options.scaleTo - this .options.scaleFrom)/100;
this .dims = null ;
if (this .options.scaleMode=='box' )
this .dims = [this .element.offsetHeight, this .element.offsetWidth];
if (/^content/.test(this .options.scaleMode))
this .dims = [this .element.scrollHeight, this .element.scrollWidth];
if (!this .dims)
this .dims = [this .options.scaleMode.originalHeight,
this .options.scaleMode.originalWidth];
},
update: function (position) {
var currentScale = (this .options.scaleFrom/100.0) + (this .factor * position);
if (this .options.scaleContent && this .fontSize)
this .element.setStyle({fontSize: this .fontSize * currentScale + this .fontSizeType });
this .setDimensions(this .dims[0] * currentScale, this .dims[1] * currentScale);
},
finish: function (position) {
if (this .restoreAfterFinish) this .element.setStyle(this .originalStyle);
},
setDimensions: function (height, width) {
var d = {};
if (this .options.scaleX) d.width = Math.round(width) + 'px' ;
if (this .options.scaleY) d.height = Math.round(height) + 'px' ;
if (this .options.scaleFromCenter) {
var topd = (height - this .dims[0])/2;
var leftd = (width - this .dims[1])/2;
if (this .elementPositioning == 'absolute' ) {
if (this .options.scaleY) d.top = this .originalTop-topd + 'px' ;
if (this .options.scaleX) d.left = this .originalLeft-leftd + 'px' ;
} else {
if (this .options.scaleY) d.top = -topd + 'px' ;
if (this .options.scaleX) d.left = -leftd + 'px' ;
}
}
this .element.setStyle(d);
}
});
Effect.Highlight = Class .create();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
initialize: function (element) {
this .element = $(element);
if (!this .element) throw (Effect._elementDoesNotExistError);
var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
this .start(options);
},
setup: function () {
// Prevent executing on elements not in the layout flow
if (this .element.getStyle('display' )=='none' ) { this .cancel(); return ; }
// Disable background image during the effect
this .oldStyle = {};
if (!this .options.keepBackgroundImage) {
this .oldStyle.backgroundImage = this .element.getStyle('background-image' );
this .element.setStyle({backgroundImage: 'none' });
}
if (!this .options.endcolor)
this .options.endcolor = this .element.getStyle('background-color' ).parseColor('#ffffff' );
if (!this .options.restorecolor)
this .options.restorecolor = this .element.getStyle('background-color' );
// init color calculations
this ._base = $R(0,2).map(function (i){ return parseInt(this .options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this ));
this ._delta = $R(0,2).map(function (i){ return parseInt(this .options.endcolor.slice(i*2+1,i*2+3),16)-this ._base[i] }.bind(this ));
},
update: function (position) {
this .element.setStyle({backgroundColor: $R(0,2).inject('#' ,function (m,v,i){
return m+(Math.round(this ._base[i]+(this ._delta[i]*position)).toColorPart()); }.bind(this )) });
},
finish: function () {
this .element.setStyle(Object.extend(this .oldStyle, {
backgroundColor: this .options.restorecolor
}));
}
});
Effect.ScrollTo = Class .create();
Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
initialize: function (element) {
this .element = $(element);
this .start(arguments[1] || {});
},
setup: function () {
Position.prepare();
var offsets = Position.cumulativeOffset(this .element);
if (this .options.offset) offsets[1] += this .options.offset;
var max = window.innerHeight ?
window.height - window.innerHeight :
document.body.scrollHeight -
(document.documentElement.clientHeight ?
document.documentElement.clientHeight : document.body.clientHeight);
this .scrollStart = Position.deltaY;
this .delta = (offsets[1] > max ? max : offsets[1]) - this .scrollStart;
},
update: function (position) {
Position.prepare();
window.scrollTo(Position.deltaX,
this .scrollStart + (position*this .delta));
}
});
/* ------------- combination effects ------------- */
Effect.Fade = function (element) {
element = $(element);
var oldOpacity = element.getInlineOpacity();
var options = Object.extend({
from: element.getOpacity() || 1.0,
to: 0.0,
afterFinishInternal: function (effect) {
if (effect.options.to!=0) return ;
effect.element.hide().setStyle({opacity: oldOpacity});
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Appear = function (element) {
element = $(element);
var options = Object.extend({
from: (element.getStyle('display' ) == 'none' ? 0.0 : element.getOpacity() || 0.0),
to: 1.0,
// force Safari to render floated elements properly
afterFinishInternal: function (effect) {
effect.element.forceRerendering();
},
beforeSetup: function (effect) {
effect.element.setOpacity(effect.options.from).show();
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}
Effect.Puff = function (element) {
element = $(element);
var oldStyle = {
opacity: element.getInlineOpacity(),
position: element.getStyle('position' ),
top: element.style.top,
left: element.style.left,
width: element.style.width,
height: element.style.height
};
return new Effect.Parallel(
[ new Effect.Scale(element, 200,
{ sync: true , scaleFromCenter: true , scaleContent: true , restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true , to: 0.0 } ) ],
Object.extend({ duration: 1.0,
beforeSetupInternal: function (effect) {
Position.absolutize(effect.effects[0].element)
},
afterFinishInternal: function (effect) {
effect.effects[0].element.hide().setStyle(oldStyle); }
}, arguments[1] || {})
);
}
Effect.BlindUp = function (element) {
element = $(element);
element.makeClipping();
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false ,
scaleX: false ,
restoreAfterFinish: true ,
afterFinishInternal: function (effect) {
effect.element.hide().undoClipping();
}
}, arguments[1] || {})
);
}
Effect.BlindDown = function (element) {
element = $(element);
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false ,
scaleX: false ,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true ,
afterSetup: function (effect) {
effect.element.makeClipping().setStyle({height: '0px' }).show();
},
afterFinishInternal: function (effect) {
effect.element.undoClipping();
}
}, arguments[1] || {}));
}
Effect.SwitchOff = function (element) {
element = $(element);
var oldOpacity = element.getInlineOpacity();
return new Effect.Appear(element, Object.extend({
duration: 0.4,
from: 0,
transition: Effect.Transitions.flicker,
afterFinishInternal: function (effect) {
new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true ,
scaleX: false , scaleContent: false , restoreAfterFinish: true ,
beforeSetup: function (effect) {
effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function (effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
})
}
}, arguments[1] || {}));
}
Effect.DropOut = function (element) {
element = $(element);
var oldStyle = {
top: element.getStyle('top' ),
left: element.getStyle('left' ),
opacity: element.getInlineOpacity() };
return new Effect.Parallel(
[ new Effect.Move(element, {x: 0, y: 100, sync: true }),
new Effect.Opacity(element, { sync: true , to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
beforeSetup: function (effect) {
effect.effects[0].element.makePositioned();
},
afterFinishInternal: function (effect) {
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
}
}, arguments[1] || {}));
}
Effect.Shake = function (element) {
element = $(element);
var oldStyle = {
top: element.getStyle('top' ),
left: element.getStyle('left' ) };
return new Effect.Move(element,
{ x: 20, y: 0, duration: 0.05, afterFinishInternal: function (effect) {
new Effect.Move(effect.element,
{ x: -40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
new Effect.Move(effect.element,
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
new Effect.Move(effect.element,
{ x: -40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
new Effect.Move(effect.element,
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
new Effect.Move(effect.element,
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function (effect) {
effect.element.undoPositioned().setStyle(oldStyle);
}}) }}) }}) }}) }}) }});
}
Effect.SlideDown = function (element) {
element = $(element).cleanWhitespace();
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
var oldInnerBottom = element.down().getStyle('bottom' );
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false ,
scaleX: false ,
scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true ,
afterSetup: function (effect) {
effect.element.makePositioned();
effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: '' });
effect.element.makeClipping().setStyle({height: '0px' }).show();
},
afterUpdateInternal: function (effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function (effect) {
effect.element.undoClipping().undoPositioned();
effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
}, arguments[1] || {})
);
}
Effect.SlideUp = function (element) {
element = $(element).cleanWhitespace();
var oldInnerBottom = element.down().getStyle('bottom' );
return new Effect.Scale(element, window.opera ? 0 : 1,
Object.extend({ scaleContent: false ,
scaleX: false ,
scaleMode: 'box' ,
scaleFrom: 100,
restoreAfterFinish: true ,
beforeStartInternal: function (effect) {
effect.element.makePositioned();
effect.element.down().makePositioned();
if (window.opera) effect.element.setStyle({top: '' });
effect.element.makeClipping().show();
},
afterUpdateInternal: function (effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function (effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
effect.element.down().undoPositioned();
}
}, arguments[1] || {})
);
}
// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function (element) {
return new Effect.Scale(element, window.opera ? 1 : 0, {
restoreAfterFinish: true ,
beforeSetup: function (effect) {
effect.element.makeClipping();
},
afterFinishInternal: function (effect) {
effect.element.hide().undoClipping();
}
});
}
Effect.Grow = function (element) {
element = $(element);
var options = Object.extend({
direction: 'center' ,
moveTransition: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.full
}, arguments[1] || {});
var oldStyle = {
top: element.style.top,
left: element.style.left,
height: element.style.height,
width: element.style.width,
opacity: element.getInlineOpacity() };
var dims = element.getDimensions();
var initialMoveX, initialMoveY;
var moveX, moveY;
switch (options.direction) {
case 'top-left' :
initialMoveX = initialMoveY = moveX = moveY = 0;
break ;
case 'top-right' :
initialMoveX = dims.width;
initialMoveY = moveY = 0;
moveX = -dims.width;
break ;
case 'bottom-left' :
initialMoveX = moveX = 0;
initialMoveY = dims.height;
moveY = -dims.height;
break ;
case 'bottom-right' :
initialMoveX = dims.width;
initialMoveY = dims.height;
moveX = -dims.width;
moveY = -dims.height;
break ;
case 'center' :
initialMoveX = dims.width / 2;
initialMoveY = dims.height / 2;
moveX = -dims.width / 2;
moveY = -dims.height / 2;
break ;
}
return new Effect.Move(element, {
x: initialMoveX,
y: initialMoveY,
duration: 0.01,
beforeSetup: function (effect) {
effect.element.hide().makeClipping().makePositioned();
},
afterFinishInternal: function (effect) {
new Effect.Parallel(
[ new Effect.Opacity(effect.element, { sync: true , to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true , transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true , scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true })
], Object.extend({
beforeSetup: function (effect) {
effect.effects[0].element.setStyle({height: '0px' }).show();
},
afterFinishInternal: function (effect) {
effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
)
}
});
}
Effect.Shrink = function (element) {
element = $(element);
var options = Object.extend({
direction: 'center' ,
moveTransition: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.none
}, arguments[1] || {});
var oldStyle = {
top: element.style.top,
left: element.style.left,
height: element.style.height,
width: element.style.width,
opacity: element.getInlineOpacity() };
var dims = element.getDimensions();
var moveX, moveY;
switch (options.direction) {
case 'top-left' :
moveX = moveY = 0;
break ;
case 'top-right' :
moveX = dims.width;
moveY = 0;
break ;
case 'bottom-left' :
moveX = 0;
moveY = dims.height;
break ;
case 'bottom-right' :
moveX = dims.width;
moveY = dims.height;
break ;
case 'center' :
moveX = dims.width / 2;
moveY = dims.height / 2;
break ;
}
return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true , to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true , transition: options.scaleTransition, restoreAfterFinish: true }),
new Effect.Move(element, { x: moveX, y: moveY, sync: true , transition: options.moveTransition })
], Object.extend({
beforeStartInternal: function (effect) {
effect.effects[0].element.makePositioned().makeClipping();
},
afterFinishInternal: function (effect) {
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
}, options)
);
}
Effect.Pulsate = function (element) {
element = $(element);
var options = arguments[1] || {};
var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
var reverser = function (pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({ duration: 2.0, from: 0,
afterFinishInternal: function (effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
}
Effect.Fold = function (element) {
element = $(element);
var oldStyle = {
top: element.style.top,
left: element.style.left,
width: element.style.width,
height: element.style.height };
element.makeClipping();
return new Effect.Scale(element, 5, Object.extend({
scaleContent: false ,
scaleX: false ,
afterFinishInternal: function (effect) {
new Effect.Scale(element, 1, {
scaleContent: false ,
scaleY: false ,
afterFinishInternal: function (effect) {
effect.element.hide().undoClipping().setStyle(oldStyle);
} });
}}, arguments[1] || {}));
};
Effect.Morph = Class .create();
Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
initialize: function (element) {
this .element = $(element);
if (!this .element) throw (Effect._elementDoesNotExistError);
var options = Object.extend({
style: {}
}, arguments[1] || {});
if (typeof options.style == 'string' ) {
if (options.style.indexOf(':' ) == -1) {
var cssText = '' , selector = '.' + options.style;
$A(document.styleSheets).reverse().each(function (styleSheet) {
if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
else if (styleSheet.rules) cssRules = styleSheet.rules;
$A(cssRules).reverse().each(function (rule) {
if (selector == rule.selectorText) {
cssText = rule.style.cssText;
throw $break ;
}
});
if (cssText) throw $break ;
});
this .style = cssText.parseStyle();
options.afterFinishInternal = function (effect){
effect.element.addClassName(effect.options.style);
effect.transforms.each(function (transform) {
if (transform.style != 'opacity' )
effect.element.style[transform.style] = '' ;
});
}
} else this .style = options.style.parseStyle();
} else this .style = $H(options.style)
this .start(options);
},
setup: function (){
function parseColor(color){
if (!color || ['rgba(0, 0, 0, 0)' ,'transparent' ].include(color)) color = '#ffffff' ;
color = color.parseColor();
return $R(0,2).map(function (i){
return parseInt( color.slice(i*2+1,i*2+3), 16 )
});
}
this .transforms = this .style.map(function (pair){
var property = pair[0], value = pair[1], unit = null ;
if (value.parseColor('#zzzzzz' ) != '#zzzzzz' ) {
value = value.parseColor();
unit = 'color' ;
} else if (property == 'opacity' ) {
value = parseFloat(value);
if (Prototype.Browser.IE && (!this .element.currentStyle.hasLayout))
this .element.setStyle({zoom: 1});
} else if (Element.CSS_LENGTH.test(value)) {
var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
value = parseFloat(components[1]);
unit = (components.length == 3) ? components[2] : null ;
}
var originalValue = this .element.getStyle(property);
return {
style: property.camelize(),
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
};
}.bind(this )).reject(function (transform){
return (
(transform.originalValue == transform.targetValue) ||
(
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
)
});
},
update: function (position) {
var style = {}, transform, i = this .transforms.length;
while (i--)
style[(transform = this .transforms[i]).style] =
transform.unit=='color' ? '#' +
(Math.round(transform.originalValue[0]+
(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
(Math.round(transform.originalValue[1]+
(transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
(Math.round(transform.originalValue[2]+
(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
transform.originalValue + Math.round(
((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
this .element.setStyle(style, true );
}
});
Effect.Transform = Class .create();
Object.extend(Effect.Transform.prototype, {
initialize: function (tracks){
this .tracks = [];
this .options = arguments[1] || {};
this .addTracks(tracks);
},
addTracks: function (tracks){
tracks.each(function (track){
var data = $H(track).values().first();
this .tracks.push($H({
ids: $H(track).keys().first(),
effect: Effect.Morph,
options: { style: data }
}));
}.bind(this ));
return this ;
},
play: function (){
return new Effect.Parallel(
this .tracks.map(function (track){
var elements = [$(track.ids) || $$(track.ids)].flatten();
return elements.map(function (e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
}).flatten(),
this .options
);
}
});
Element.CSS_PROPERTIES = $w(
'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
'fontSize fontWeight height left letterSpacing lineHeight ' +
'marginBottom marginLeft marginRight marginTop maxHeight ' +
'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
'right textIndent top width wordSpacing zIndex' );
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.prototype.parseStyle = function (){
var element = document.createElement('div' );
element.innerHTML = '
' ;
var style = element.childNodes[0].style, styleRules = $H();
Element.CSS_PROPERTIES.each(function (property){
if (style[property]) styleRules[property] = style[property];
});
if (Prototype.Browser.IE && this .indexOf('opacity' ) > -1) {
styleRules.opacity = this .match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
}
return styleRules;
};
Element.morph = function (element, style) {
new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
return element;
};
['getInlineOpacity' ,'forceRerendering' ,'setContentZoom' ,
'collectTextNodes' ,'collectTextNodesIgnoreClass' ,'morph' ].each(
function (f) { Element.Methods[f] = Element[f]; }
);
Element.Methods.visualEffect = function (element, effect, options) {
s = effect.dasherize().camelize();
effect_class = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[effect_class](element, options);
return $(element);
};
Element.addMethods();
Messung V0.5 C=97 H=95 G=95
¤ Dauer der Verarbeitung: 0.14 Sekunden
¤
*© Formatika GbR, Deutschland