moparscape.org-smf/Themes/default/scripts/fader.js

218 lines
6.8 KiB
JavaScript

function smf_NewsFader(oOptions)
{
this.opt = oOptions;
this.oFaderHandle = document.getElementById(this.opt.sFaderControlId);
// Fade from... what text color? Default to black.
this.oFadeFrom = 'oFadeFrom' in this.opt ? this.opt.oFadeFrom : {
r: 0,
g: 0,
b: 0
};
// To which background color? Default to white.
this.oFadeTo = 'oFadeTo' in this.opt ? this.opt.oFadeTo : {
r: 255,
g: 255,
b: 255
};
// Surround each item with... anything special?
this.sItemTemplate = 'sItemTemplate' in this.opt ? this.opt.sItemTemplate : '%1$s';
// Fade delay (in milliseconds).
this.iFadeDelay = 'iFadeDelay' in this.opt ? this.opt.iFadeDelay : 5000;
// The array that contains all the lines of the news for display.
this.aFaderItems = 'aFaderItems' in this.opt ? this.opt.aFaderItems : [];
// Should we look for fader data, still?
this.bReceivedItemsOnConstruction = 'aFaderItems' in this.opt;
// The current item in smfFadeContent.
this.iFadeIndex = -1;
// Percent of fade (-64 to 510).
this.iFadePercent = 510
// Direction (in or out).
this.bFadeSwitch = false;
// Just make sure the page is loaded before calling the init.
setTimeout(this.opt.sSelf + '.init();', 1);
}
smf_NewsFader.prototype.init = function init()
{
var oForeEl, oForeColor, oBackEl, oBackColor;
// Try to find the fore- and background colors.
var modern_browser = 'MozOpacity' in this.oFaderHandle.style || 'Opacity' in this.oFaderHandle.style || 'filter' in this.oFaderHandle.style;
if ('currentStyle' in this.oFaderHandle && !modern_browser)
{
oForeColor = this.oFaderHandle.currentStyle.color.match(/#([\da-f][\da-f])([\da-f][\da-f])([\da-f][\da-f])/);
this.oFadeFrom = {
r: parseInt(oForeColor[1]),
g: parseInt(oForeColor[2]),
b: parseInt(oForeColor[3])
};
oBackEl = this.oFaderHandle;
while (oBackEl.currentStyle.backgroundColor == 'transparent' && 'parentNode' in oBackEl)
oBackEl = oBackEl.parentNode;
oBackColor = oBackEl.currentStyle.backgroundColor.match(/#([\da-f][\da-f])([\da-f][\da-f])([\da-f][\da-f])/);
this.oFadeTo = {
r: eval('0x' + oBackColor[1]),
g: eval('0x' + oBackColor[2]),
b: eval('0x' + oBackColor[3])
};
}
else if (!('opera' in window) && 'defaultView' in document && !modern_browser)
{
oForeEl = this.oFaderHandle;
while (document.defaultView.getComputedStyle(oForeEl, null).getPropertyCSSValue('color') == null && 'parentNode' in oForeEl && 'tagName' in oForeEl.parentNode)
oForeEl = oForeEl.parentNode;
oForeColor = document.defaultView.getComputedStyle(oForeEl, null).getPropertyValue('color').match(/rgb\((\d+), (\d+), (\d+)\)/);
this.oFadeFrom = {
r: parseInt(oForeColor[1]),
g: parseInt(oForeColor[2]),
b: parseInt(oForeColor[3])
};
oBackEl = this.oFaderHandle;
while (document.defaultView.getComputedStyle(oBackEl, null).getPropertyCSSValue('background-color') == null && 'parentNode' in oBackEl && 'tagName' in oBackEl.parentNode)
oBackEl = oBackEl.parentNode;
oBackColor = document.defaultView.getComputedStyle(oBackEl, null).getPropertyValue('background-color');
this.oFadeTo = {
r: parseInt(oBackColor[1]),
g: parseInt(oBackColor[2]),
b: parseInt(oBackColor[3])
};
}
// Did we get our fader items on construction, or should we be gathering them instead?
if (!this.bReceivedItemsOnConstruction)
{
// Get the news from the list in boardindex
var oNewsItems = this.oFaderHandle.getElementsByTagName('li');
// Fill the array that has previously been created
for (var i = 0, n = oNewsItems.length; i < n; i ++)
this.aFaderItems[i] = oNewsItems[i].innerHTML;
}
// The ranges to fade from for R, G, and B. (how far apart they are.)
this.oFadeRange = {
'r': this.oFadeFrom.r - this.oFadeTo.r,
'g': this.oFadeFrom.g - this.oFadeTo.g,
'b': this.oFadeFrom.b - this.oFadeTo.b
};
// Divide by 20 because we are doing it 20 times per one ms.
this.iFadeDelay /= 20;
// Start the fader!
window.setTimeout(this.opt.sSelf + '.fade();', 20);
}
// Main fading function... called 50 times every second.
smf_NewsFader.prototype.fade = function fade()
{
if (this.aFaderItems.length <= 1)
return;
// A fix for Internet Explorer 4: wait until the document is loaded so we can use setInnerHTML().
if ('readyState' in document && document.readyState != 'complete')
{
window.setTimeout(this.opt.sSelf + '.fade();', 20);
return;
}
// Starting out? Set up the first item.
if (this.iFadeIndex == -1)
{
setInnerHTML(this.oFaderHandle, this.sItemTemplate.replace('%1$s', this.aFaderItems[0]));
this.iFadeIndex = 1;
// In Mozilla, text jumps around from this when 1 or 0.5, etc...
if ('MozOpacity' in this.oFaderHandle.style)
this.oFaderHandle.style.MozOpacity = '0.90';
else if ('opacity' in this.oFaderHandle.style)
this.oFaderHandle.style.opacity = '0.90';
// In Internet Explorer, we have to define this to use it.
else if ('filter' in this.oFaderHandle.style)
this.oFaderHandle.style.filter = 'alpha(opacity=100)';
}
// Are we already done fading in? If so, fade out.
if (this.iFadePercent >= 510)
this.bFadeSwitch = !this.bFadeSwitch;
// All the way faded out?
else if (this.iFadePercent <= -64)
{
this.bFadeSwitch = !this.bFadeSwitch;
// Go to the next item, or first if we're out of items.
setInnerHTML(this.oFaderHandle, this.sItemTemplate.replace('%1$s', this.aFaderItems[this.iFadeIndex ++]));
if (this.iFadeIndex >= this.aFaderItems.length)
this.iFadeIndex = 0;
}
// Increment or decrement the fade percentage.
if (this.bFadeSwitch)
this.iFadePercent -= 255 / this.iFadeDelay * 2;
else
this.iFadePercent += 255 / this.iFadeDelay * 2;
// If it's not outside 0 and 256... (otherwise it's just delay time.)
if (this.iFadePercent < 256 && this.iFadePercent > 0)
{
// Easier... also faster...
var tempPercent = this.iFadePercent / 255, rounded;
if ('MozOpacity' in this.oFaderHandle.style)
{
rounded = Math.round(tempPercent * 100) / 100;
this.oFaderHandle.style.MozOpacity = rounded == 1 ? '0.99' : rounded;
}
else if ('opacity' in this.oFaderHandle.style)
{
rounded = Math.round(tempPercent * 100) / 100;
this.oFaderHandle.style.opacity = rounded == 1 ? '0.99' : rounded;
}
else
{
var done = false;
if ('alpha' in this.oFaderHandle.filters)
{
try
{
this.oFaderHandle.filters.alpha.opacity = Math.round(tempPercent * 100);
done = true;
}
catch (err)
{
}
}
if (!done)
{
// Get the new R, G, and B. (it should be bottom + (range of color * percent)...)
var r = Math.ceil(this.oFadeTo.r + this.oFadeRange.r * tempPercent);
var g = Math.ceil(this.oFadeTo.g + this.oFadeRange.g * tempPercent);
var b = Math.ceil(this.oFadeTo.b + this.oFadeRange.b * tempPercent);
// Set the color in the style, thereby fading it.
this.oFaderHandle.style.color = 'rgb(' + r + ', ' + g + ', ' + b + ')';
}
}
}
// Keep going.
window.setTimeout(this.opt.sSelf + '.fade();', 20);
}