Click here to Skip to main content
15,881,852 members
Articles / Web Development / HTML

Fading Banner

Rate me:
Please Sign up or sign in to vote.
4.37/5 (10 votes)
27 Apr 2007CPOL4 min read 64.8K   571   22  
Article presents the Fading Banner - a lightweight yet functional alternative to both still-image ads and Flash banners.
/*
 * Fading Banner, base script, version 1.1
 *
 * Copyright (C) 2007 Dmitriy Khudorozhkov
 *
 * This software is provided "as-is", without any express or implied warranty.
 * In no event will the author be held liable for any damages arising from the
 * use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source distribution.
 *
 *  - Dmitriy Khudorozhkov, kh_dmitry2001@mail.ru
 */

function FadingBanner(parentId, type, width, height, bg, timeout)
{
  this.batches  = [];
  this.current  = 0;
  this.images   = [];
  this.parent   = document.getElementById(parentId);
  this.root     = null;
  this.timeout  = timeout || 5000;
  this.type     = (type == "vertical") ? "vertical" : "horizontal";

  while(this.parent.firstChild)
    this.parent.removeChild(this.parent.firstChild);

  return this._construct(width, height, bg);
}

FadingBanner.prototype = {

  // public methods:

  add: function(batch, imageSrc, imageWidth, imageHeight, link)
  {
    var l = this.batches.length;
    for(var i = 0; i < l; i++)
      if(this.batches[i] == batch)
        break;

    if(i == l) this.batches[l] = batch;

    if(!this.images[batch]) this.images[batch] = [];

    var l2 = this.images[batch].length;

    var imag = this.images[batch][l2] = new Object;

    imag.src    = imageSrc;
    imag.link   = link;
    imag.width  = imageWidth;
    imag.height = imageHeight;

    var top = 0, left = 0, isH = (this.type == "horizontal");

    for(i = 0; i < l2; i++)
    {
      var _img = this.images[batch][i];

      if(isH)
      {
        left += _img.width;
      }
      else
      {
        top += _img.height;
      }
    }

    var a = imag.obj = document.createElement("A");
    a.href = imag.link;
    a.target = "_blank";
    a.style.display = "none";

    var img = document.createElement("IMG");
    img.src = imag.src;
    img.id  = "fb_img_" + this.parent.id + "_" + String(batch) + "_" + String(l2);

    a.appendChild(img);
    this.root.appendChild(a);

    var is = img.style;
    is.position = "absolute";
    is.top      = top + "px";
    is.left     = left + "px";
    is.width    = imag.width;
    is.height   = imag.height;
    is.border   = "0";
    is.opacity  = 0;
    is.filter   = "alpha(opacity=0)";

    this.batches.sort(function (a, b) { return a - b; });
    this.current = this.batches[0];

    return l2 + 1;
  },

  start: function()
  {
    this.root.style.display = "block";

    this._showbatch();
  },

  // support methods follow:

  _construct: function(width, height, bg)
  {
    var banner = document.createElement("DIV");
    var bs = banner.style;

    bs.position = "relative";
    bs.top      = "0px";
    bs.left     = "0px";
    bs.width    = width + "px";
    bs.height   = height + "px";

    bs.display  = "none";
    bs.backgroundColor = bg || "#FFF";

    this.root = this.parent.appendChild(banner);

    return this;
  },

  _callLater: function(obj, func, param)
  {
    param = param || null;
    return obj ? (function() { obj[func](param); }) : (function() { func(param); });
  },

  _next: function()
  {
    var _out = function(_obj)
    {
      var _go = function(__obj)
      {
        var cur = __obj.current, l = __obj.images[cur].length;

        for(var i = 0; i < l; i++)
          __obj.images[cur][i].obj.style.display = "none";

        l = __obj.batches.length;
        for(i = 0; i < l; i++)
          if(__obj.current == __obj.batches[i])
            break;

        __obj.current = (i == l - 1) ? __obj.batches[0] : __obj.batches[i + 1];

        __obj._showbatch();
      }

      // fade-out current batch:
      var cur = _obj.current, l = _obj.images[cur].length;

      for(var i = 0; i < l; i++)
      {
        var img = _obj.images[cur][i];
        _obj._fade(img.obj.firstChild.id, 0, 50, 10, (i == (l - 1) ? function() { _go(_obj); } : null));
      }
    }

    setTimeout(this._callLater(null, _out, this), this.timeout);
  },

  _showbatch: function()
  {
    var cur = this.current, l = this.images[cur].length;

    for(var i = 0; i < l; i++)
    {
      var img = this.images[cur][i];
      img.obj.style.display = "block";

      this._fade(img.obj.firstChild.id, 100, 50, 10, (i == (l - 1) ? this._callLater(this, "_next") : null));
    }
  },

  _fade: function(id, destOp, rate, delta, callback)
  {
    var obj = document.getElementById(id);

    if(obj.timer) clearTimeout(obj.timer);

    var curOp = obj.filters ? obj.filters.alpha.opacity : (obj.style.opacity * 100.0);
    var direction = (curOp <= destOp) ? 1 : -1;

    delta  = Math.min(direction * (destOp - curOp), delta);
    curOp += direction * delta;

    if(obj.filters)
      obj.filters.alpha.opacity = curOp;
    else
      obj.style.opacity = curOp / 100.0;

    if(curOp != destOp)
      obj.timer = setTimeout(function() { FadingBanner.prototype._fade(id, destOp, rate, delta, callback); }, rate);
    else
      if(callback) callback();
  }
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Freelance software engineer
Russian Federation Russian Federation
Dmitry Khudorozhkov began programming (and gaming) with his ZX Spectrum in 1989. Having seen and used all IBM PCs from early XT to the latest x64 machines, now Dmitry is a freelance programmer, living in Moscow, Russia. He is a graduate of the Moscow State Institute of Electronics and Mathematics (Applied Mathematics).

He is proficient in:

- C/C++ - more that 9 years of experience. Pure Win32 API/MFC desktop programming, networking (BSD/Win sockets), databases (primarily SQLite), OpenGL;

- JavaScript - more that 6 years of experience. Client-side components, AJAX, jQuery installation and customization;

- Firefox extensions (immediatelly ready for addons.mozilla.org reviewing) and Greasemonkey scripts. As an example of extensions Dmitry made you can search for FoxyPrices or WhatBird Winged Toolbar;

- XML and it's applications (last 2 years): XSLT (+ XPath), XSD, SVG, VML;

- ASP.NET/C# (webservices mostly);

Also familiar with (= entry level):

- PHP;

- HTML/CSS slicing.

Trying to learn:

- Ruby/Ruby-on-Rails;

- Czech language.

If you wish to express your opinion, ask a question or report a bug, feel free to e-mail:dmitrykhudorozhkov@yahoo.com. Job offers are warmly welcome.

If you wish to donate - and, by doing so, support further development - you can send Dmitry a bonus through the Rentacoder.com service (registration is free, Paypal is supported). Russian users can donate to the Yandex.Money account 41001132298694.

-

Comments and Discussions