Created
July 27, 2011 17:52
-
-
Save tulios/1109970 to your computer and use it in GitHub Desktop.
Efeitos de fadeIn, fadeOut e fadeToogle em javascript puro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
WM.Effect.FADE_TICK = 10; | |
WM.Effect.Exception = function(message) { | |
this.message = message; | |
}; | |
/** | |
* Options: | |
* duration: int, | |
* maxFade: float (0 to 1) Default: 1 | |
* maxFadeOut: float (0 to 1) Default: 0 | |
* elements: [e1, e2, e3] | |
* | |
* or | |
* | |
* element: e1 | |
* | |
*/ | |
WM.Effect.Fade = function(options) { | |
this.elements = []; | |
this.instances = {}; | |
if (options.element) { | |
this.elements.push(options.element); | |
} else if (options.elements){ | |
this.elements = this.elements.concat(options.elements); | |
} else { | |
throw new WM.Effect.Exception("An Element/Elements should be informed!"); | |
} | |
this._init(options); | |
}; | |
WM.Effect.Fade.prototype = { | |
toogle: function(maxFade, maxFadeOut) { | |
this._eachInstance(function(){ | |
this.fadeState = this.isVisible() ? 'invisible' : 'visible'; | |
this.maxFade = maxFade || this.maxFade; | |
this.maxFadeOut = maxFadeOut || this.maxFadeOut; | |
this._start(); | |
}); | |
}, | |
fadeIn: function(maxFade) { | |
this._eachInstance(function(){ | |
if (!this.isVisible()) { | |
this.fadeState = 'visible'; | |
this.maxFade = maxFade || this.maxFade; | |
this._start(); | |
} | |
}); | |
}, | |
fadeOut: function(maxFadeOut) { | |
this._eachInstance(function(){ | |
if (this.isVisible()) { | |
this.fadeState = 'invisible'; | |
this.maxFadeOut = maxFadeOut || this.maxFadeOut; | |
this._start(); | |
} | |
}); | |
}, | |
_init: function(options) { | |
if (options.duration == null) throw new WM.Effect.Exception("Duration should not be null or undefined!"); | |
this.duration = options.duration; | |
for (var index in this.elements) { | |
if (this.elements.hasOwnProperty(index)) { | |
this.instances[index] = this._newInstance(this.elements[index], options.maxFade, options.maxFadeOut); | |
} | |
} | |
}, | |
_newInstance: function(element, maxFade, maxFadeOut) { | |
var instance = {}; | |
instance.element = element; | |
instance.duration = this.duration; | |
if (!maxFade) { | |
var opacity = element.style.opacity; | |
instance.maxFade = (!this._isWithoutOpacity(element) && opacity !== '0') ? parseFloat(opacity) : 1; | |
} else { | |
instance.maxFade = maxFade; | |
} | |
instance.maxFadeOut = maxFadeOut || 0; | |
if (this._isDisplayed(element) && | |
(this._isWithoutOpacity(element) || this._isOpaque(element, instance.maxFade)) && | |
parseFloat(element.style.opacity) !== maxFadeOut) { | |
instance.fadeState = 'visible'; | |
} else { | |
instance.fadeState = 'invisible'; | |
} | |
var self = this; | |
instance._start = function () { self._start.call(instance); }; | |
instance.isVisible = function() { return self._isVisible.call(instance); } | |
return instance; | |
}, | |
_isVisible: function() { | |
return this.fadeState === 'visible'; | |
}, | |
_eachInstance: function(block) { | |
for (var index in this.instances) { | |
if (this.elements.hasOwnProperty(index)) { | |
block.call(this.instances[index]); | |
} | |
} | |
}, | |
_isDisplayed: function(element) { | |
return WM.Util.getStyle(element, "display") !== "none"; | |
}, | |
_isWithoutOpacity: function(element) { | |
var opacity = element.style.opacity; | |
return opacity === null || opacity === undefined || opacity === ''; | |
}, | |
_isOpaque: function(element, maxFade) { | |
return element.style.opacity === '' + maxFade; | |
}, | |
_start: function() { | |
this.fadeTimeLeft = this.duration; | |
var currentTick = new Date().getTime(); | |
var self = this; | |
setTimeout(function() { WM.Effect._animateFade(currentTick, self) }, WM.Effect.FADE_TICK); | |
} | |
}; | |
WM.Effect._animateFade = function(lastTick, fadeElement) { | |
var duration = fadeElement.duration; | |
var maxFade = fadeElement.maxFade; | |
var maxFadeOut = fadeElement.maxFadeOut; | |
var element = fadeElement.element; | |
var currentTick = new Date().getTime(); | |
var elapsedTicks = currentTick - lastTick; | |
if (fadeElement.fadeTimeLeft <= elapsedTicks) { | |
element.style.opacity = fadeElement.isVisible() ? '' + maxFade : '' + maxFadeOut; | |
element.style.filter = 'alpha(opacity = ' + (fadeElement.isVisible() ? '' + (maxFade * 100) : '' + (maxFadeOut * 100)) + ')'; | |
// When the maxFadeOut is greater that zero it means that the 'invisible' state | |
// of the element it is not zero, so we can not set to display none | |
if (fadeElement.isVisible() || maxFadeOut > 0) { | |
element.style.display = WM.Util.getDefaultDisplay(element); | |
} else { | |
element.style.display = 'none'; | |
} | |
return; | |
} | |
fadeElement.fadeTimeLeft -= elapsedTicks; | |
var newOpacityValue = (fadeElement.fadeTimeLeft / duration) * maxFade; | |
if (fadeElement.isVisible()) { | |
newOpacityValue = maxFade - newOpacityValue; | |
// If the maxFadeOut is greater than zero we avoid the values under the defined value or | |
// if it does not matter (equal to zero) we get all the values | |
if (maxFadeOut === 0 || (newOpacityValue > maxFadeOut && maxFadeOut > 0)) { | |
element.style.opacity = newOpacityValue; | |
element.style.filter = 'alpha(opacity = ' + (newOpacityValue * 100) + ')'; | |
} | |
// Same rule here, if defined we get just the values in the range | |
} else if (maxFadeOut === 0 || newOpacityValue > maxFadeOut) { | |
element.style.opacity = newOpacityValue; | |
element.style.filter = 'alpha(opacity = ' + (newOpacityValue * 100) + ')'; | |
} | |
if (WM.Util.getStyle(element, "display") == "none") { | |
element.style.display = WM.Util.getDefaultDisplay(element); | |
} | |
setTimeout(function() { WM.Effect._animateFade(currentTick, fadeElement) }, WM.Effect.FADE_TICK); | |
}; | |
WM.Util.getStyle = function(element, property) { | |
// IE style | |
if (element.currentStyle) { | |
return element.currentStyle[property]; | |
// W3C | |
} else if (window.getComputedStyle) { | |
return document.defaultView.getComputedStyle(element, null).getPropertyValue(property); | |
} | |
return null; | |
}; | |
WM.Util.getDefaultDisplay = function(element) { | |
var newElement = WM.Util.createElement(element.nodeName, ""); | |
var body = document.getElementsByTagName('body')[0]; | |
body.appendChild(newElement); | |
var defaultDisplay = WM.Util.getStyle(newElement, "display"); | |
body.removeChild(newElement); | |
return defaultDisplay; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment