Report abuse


			
/*
  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)
      )
    }
  });
}