Skip to content

Instantly share code, notes, and snippets.

@tulios
Created July 27, 2011 17:52
Show Gist options
  • Save tulios/1109970 to your computer and use it in GitHub Desktop.
Save tulios/1109970 to your computer and use it in GitHub Desktop.
Efeitos de fadeIn, fadeOut e fadeToogle em javascript puro
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