includes/clientside/static/flyin.js
author Dan
Sun, 07 Feb 2010 17:07:42 -0500
changeset 1219 2b13cd6b4f95
parent 1125 367768040a61
child 1227 bdac73ed481e
permissions -rw-r--r--
URL sanitizer: disabled uppercase letters in URL hex character codes (it was causing conflicts with the Windows/Apache 2.2 alt namespace separator). Thanks Techokami for finding and reporting this bug.

// Make an HTML element fly in from the top or bottom.
// Includes inertia!

// vB, don't even try. It's GPL like the rest of Enano. I know you're jealous. >:)

var fly_in_cache = new Object();
var FI_TOP = 1;
var FI_BOTTOM = 2;
var FI_IN = 1;
var FI_OUT = 2;
var FI_UP = 1;
var FI_DOWN = 2;
// increase to slow down transitions (for debug)
var FI_MULTIPLIER = 1;

/**
 * You can thank Robert Penner for the math used here. Ported from an ActionScript class.
 * License: Modified BSD license <http://www.robertpenner.com/easing_terms_of_use.html>
 */

// Effects code - don't bother changing these formulas
var Back = {
  easeOut: function(t, b, c, d, s)
  {
    if (s == undefined) s = 1.70158;
    return c * ( ( t=t/d-1 ) * t * ( ( s + 1 ) * t + s) + 1) + b;
  },
  easeIn: function (t, b, c, d, s)
  {
    if (s == undefined) s = 1.70158;
    return c * ( t/=d ) * t * ( ( s + 1 ) * t - s) + b;
  },
  easeInOut: function (t, b, c, d, s)
  {
    if (s == undefined) s = 1.70158; 
    if ((t /= d/2) < 1) 
    {
      return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    }
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  }
}

// This should be set to the class name of the effect you want.
var GlideEffect = Back;

// Placeholder functions, to make organization a little easier :-)

function fly_in_top(element, nofade, height_taken_care_of)
{
  return fly_core(element, nofade, FI_TOP, FI_IN, height_taken_care_of);
}

function fly_in_bottom(element, nofade, height_taken_care_of)
{
  return fly_core(element, nofade, FI_BOTTOM, FI_IN, height_taken_care_of);
}

function fly_out_top(element, nofade, height_taken_care_of)
{
  return fly_core(element, nofade, FI_TOP, FI_OUT, height_taken_care_of);
}

function fly_out_bottom(element, nofade, height_taken_care_of)
{
  return fly_core(element, nofade, FI_BOTTOM, FI_OUT, height_taken_care_of);
}

function fly_core(element, nofade, origin, direction, height_taken_care_of)
{
  if ( !element || typeof(element) != 'object' )
    return false;
  
  // force to array
  if ( !element.length )
    element = [ element ];
  
  // target dimensions
  var top, left;
  // initial dimensions
  var topi, lefti;
  // current dimensions
  var topc, leftc;
  // screen dimensions
  var w = getWidth();
  var h = getHeight();
  var y = parseInt ( getScrollOffset() );
  // temp vars
  var dim, off, diff, dist, ratio, opac_factor;
  // setup element
  for ( var i = 0; i < element.length; i++ )
    element[i].style.position = 'absolute';
  
  dim = [ $dynano(element[0]).Height(), $dynano(element[0]).Width() ];
  off = [ $dynano(element[0]).Top(), $dynano(element[0]).Left() ];
  
  if ( height_taken_care_of )
  {
    top = off[0];
    left = off[1];
  }
  else
  {
    top  = Math.round(( h / 2 ) - ( dim[0] / 2 )) + y; // - ( h / 4 ));
    left = Math.round(( w / 2 ) - ( dim[1] / 2 ));
  }
  
  // you can change this around to get it to fly in from corners or be on the left/right side
  lefti = left;
  
  // calculate first frame Y position
  if ( origin == FI_TOP && direction == FI_IN )
  {
    topi = 0 - dim[0] + y;
  }
  else if ( origin == FI_TOP && direction == FI_OUT )
  {
    topi = top;
    top = 0 - dim[0] + y;
  }
  else if ( origin == FI_BOTTOM && direction == FI_IN )
  {
    topi = h + y;
  }
  else if ( origin == FI_BOTTOM && direction == FI_OUT )
  {
    topi = top;
    top = h + y;
  }
  
  var abs_dir = ( ( origin == FI_TOP && direction == FI_IN ) || ( origin == FI_BOTTOM && direction == FI_OUT ) ) ? FI_DOWN : FI_UP;
  
  var diff_top = top - topi;
  var diff_left = left - lefti;
  
  var frames = 100;
  var timeout = 0;
  var timerstep = 8 * FI_MULTIPLIER;
  
  // cache element so it can be changed from within setTimeout()
  var rand_seed = Math.floor(Math.random() * 1000000);
  fly_in_cache[rand_seed] = element;
  
  for ( var i = 0; i < frames; i++ )
  {
    topc = GlideEffect.easeInOut(i, topi, diff_top, frames);
    leftc = GlideEffect.easeInOut(i, lefti, diff_left, frames);
    
    var code = 'var element = fly_in_cache[' + rand_seed + '];' + "\n";
    code +=    'for ( var i = 0; i < element.length; i++ )' + "\n";
    code +=    '{' + "\n";
    code +=    '  element[i].style.top = "' + topc + 'px";' + "\n";
    if ( !height_taken_care_of )
      code +=  '  element[i].style.left = "' + leftc + 'px";' + "\n";
    code +=    '}';
    
    setTimeout(code, timeout);
    
    timeout += timerstep;
    
    var ratio = i / frames;
    
    if ( !nofade )
    {
      // handle fade
      var opac_factor = ratio * 100;
      if ( direction == FI_OUT )
        opac_factor = 100 - opac_factor;
      
      var code = 'var element = fly_in_cache[' + rand_seed + '];' + "\n";
      code +=    'for ( var i = 0; i < element.length; i++ )' + "\n";
      code +=    '{' + "\n";
      code +=    '  domObjChangeOpac(' + opac_factor + ', element[i]);' + "\n";
      code +=    '}';
      
      setTimeout(code, timeout);
    }
    
  }
  
  // old framestepper code removed from here in Loch Ness
  
  timeout += timerstep;
  return timeout;
}

function abs(i)
{
  if ( isNaN(i) )
    return i;
  return ( i < 0 ) ? ( 0 - i ) : i;
}