/*
Ajax zoopiness effects

Tim Lucas
http://toolmantim.com

See the effect at:
http://www.viddler.com/explore/toolmantim/videos/14

Written against the prototype & scriptaculous included in Rails 0.14.3

Originally used with this RJS helper:

module ShrinkAndGrowHelper
DURATION = 0.26
SCALE = 0.85
def zoom_in(id)
visual_effect(:GrowFromScale, id, :duration => DURATION,
:scaleFrom => SCALE,
:zIndex => 1)
end
def zoom_out(id)
visual_effect(:ShrinkToScale, id, :duration => DURATION,
:scaleTo => SCALE,
:zIndex => 0)
end
end

and then used from RJS like so:

page.zoom_in 'profile-edit'
page.zoom_out 'profile-view'
*/
Effect.ShrinkToScale = function(element) {
element = $(element);
var options = Object.extend({
moveTransistion: Effect.Transitions.sinodial,
scaleTransition: Effect.Transitions.sinodial,
opacityTransition: Effect.Transitions.sinodial,
scaleTo: 0,
zIndex: 0
}, arguments[1] || {});
var oldStyle = {
top: element.style.top,
left: element.style.left,
height: element.style.height,
width: element.style.width,
'z-index': element.style['z-index'],
opacity: Element.getInlineOpacity(element) };

var dims = Element.getDimensions(element);
var moveX = dims.width * (1 - options.scaleTo) / 2;
var moveY = dims.height * (1 - options.scaleTo) / 2;

return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, options.scaleTo * 100, { sync: true, scaleMode: 'contents', transition: options.scaleTransition, restoreAfterFinish: true}),
new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition })
], Object.extend({
beforeSetup: function(effect) { with(Element) {
setStyle(effect.effects[0].element, {'z-index': options.zIndex});
}},
beforeStartInternal: function(effect) { with(Element) {
[makePositioned, makeClipping].call(effect.effects[0].element) }},
afterFinishInternal: function(effect) { with(Element) {
[hide, undoClipping, undoPositioned].call(effect.effects[0].element);
setStyle(effect.effects[0].element, oldStyle); }}
}, options)
);
}

Effect.GrowFromScale = function(element) {
element = $(element);
var options = Object.extend({
moveTransistion: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.sinodial,
scaleFrom: 0,
zIndex: 1
}, arguments[1] || {});
var oldStyle = {
top: element.style.top,
left: element.style.left,
height: element.style.height,
width: element.style.width,
'z-index': element.style['z-index'],
opacity: Element.getInlineOpacity(element) };

var dims = Element.getDimensions(element);

var initialMoveX = dims.width * (1 - options.scaleFrom) / 2;
var initialMoveY = dims.height * (1 - options.scaleFrom) / 2;
var moveX = -dims.width * (1 - options.scaleFrom) / 2;
var moveY = -dims.height * (1 - options.scaleFrom) / 2;

return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
duration: 0.01,
beforeSetup: function(effect) { with(Element) {
hide(effect.element);
makeClipping(effect.element);
makePositioned(effect.element);
}},
afterFinishInternal: function(effect) {
new Effect.Parallel(
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true, scaleFrom: options.scaleFrom * 100, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) { with(Element) {
setStyle(effect.effects[0].element, {height: '0px', 'z-index': options.zIndex});
show(effect.effects[0].element); }},
afterFinishInternal: function(effect) { with(Element) {
[undoClipping, undoPositioned].call(effect.effects[0].element);
setStyle(effect.effects[0].element, oldStyle); }}
}, options)
)
}
});
}