Fade на чистом JS (типа FadeTo в jQuery)

27.04.2014 20:54
2
Иногда хочется что-то написать на чистом JS, без jQuery и других фреймворков, как в старые добрые времена - нет ничего прекраснее чистого JS :)

Функция реализует анимацию прозрачности DOM объекта. Похожа на FadeTo у jQuery.
Можно из него сделать прототипный вариант, можно привести к аргументам, схожим с JQ FadeTo.

function fade( o, opts, dontStartNow ) {
	var opacityVal, opacityStart, opacityEnd, opacityStep, t;
 
	function th() {
		opacityVal += opacityStep;
		if ( ( opacityStep > 0 && opacityVal >= opacityEnd ) || ( opacityStep < 0 && opacityVal <= opacityEnd ) ) {
			opacityVal = opacityEnd;
			clearInterval( t );
			t = null;
		}
 
		o.style.opacity = opacityVal;
 
		if ( !t && opts.hasOwnProperty( "handler" ) ) opts.handler( true, fs, o );
	}
 
	function init() {
		opacityStep = opts.hasOwnProperty( "opacityStep" ) ? Math.abs( opts.opacityStep ) : 0.1;
 
		if ( !opts.hasOwnProperty( "delay" ) ) opts.delay = 30;
 
		if ( !opts.hasOwnProperty( "opacityStart" ) ) {
			opacityStart = parseFloat( o.style.opacity );
			if ( isNaN( opacityStart ) ) opacityStart = 1;
		}
		else {
			opacityStart = opts.opacityStart;
			o.style.opacity = opacityStart;
		}
 
		opacityVal = opacityStart;
 
		if ( !opts.hasOwnProperty( "opacityEnd" ) ) {
			opacityEnd = parseFloat( o.style.opacity );
			if ( isNaN( opacityEnd ) ) opacityEnd = 1;
		}
		else opacityEnd = opts.opacityEnd;
 
 
		if ( opacityStart > opacityEnd ) opacityStep = -opacityStep;
 
		if ( opacityStart != opacityEnd ) t = setInterval( th, opts.delay );
	}
 
	var fs = {
		get: function() {
			return {
				opts:		opts,
				opacityVal:	opacityVal,
				opacityEnd:	opacityEnd,
				opacityStep:opacityStep
			};
		},
 
		stop: function( end, dontNotify ) {
			if ( !t ) return;
 
			clearInterval( t );
			t = null;
			if ( end ) o.style.opacity = opacityEnd;
 
			if ( dontNotify !== true && opts.hasOwnProperty( "handler" ) ) opts.handler( true, fs, o );
		},
 
		start: function( restart, newOpts, dontNotify ) {
			if ( t ) return;
 
			if ( newOpts ) opts = newOpts;
 
			if ( restart ) {
				init();
				if ( dontNotify !== true && opts.hasOwnProperty( "handler" ) ) opts.handler( false, fs, o );
			}
			else t = setInterval( th, opts.delay );
		}
	};
 
	if ( dontStartNow !== true ) fs.start( true );
	return fs;
}

Вызов

var f = fade( o, opts );

oDOM объект
optsнастройки

Настройки

opacityStartначальное значение прозрачности, если не задано - берется текущее значение прозрачности DOM объекта, или 1, если получить не удалось
opacityEndконечное значение прозрачности, если не задано - берется текущее значение прозрачности DOM объекта, или 1, если получить не удалось
opacityStepшаг приращения прозрачности (по умолчанию 0.1)
delayзадержка в мс после которой происходит изменение яркости на шаг (по умолчанию 30)
handlerфункция обработки событий вида function( state, fo, o ) { ... }, где:
state true, если анимация идет / началась и false если остановлена / окончена
fo - объект fade
o - DOM объект

Методы

Функция возвращает объект со следующими методами:

get()возвращает объект со следующими членами:
opacityVal - текущая прозрачность
opacityStart - текущая начальная прозрачность
opacityEnd - текущaя конечная прозрачность
opacityStep - текущий шаг (может быть отрицательным)
opts - объект настроек, который использовался последним
stop( end, ignoreHandler )остановить анимацию:
end если true - установить прозрачность равную конечной
ignoreHandler если true - не уведомлять об остановке
start( restart, newOpts, ignoreHandler )запустить анимацию:
restart если true - заново начать анимацию
newOpts новый объект настроек, если нужно (иначе null)
ignoreHandler если true - не уведомлять о запуске

Скачать fade.html

скачать

27.04.2014, Protocoder
Дрозд Бункерный28.04.2014 11:01:34#ответить
Легче будет читать, если назовешь переменные более развернуто, чем ob, oe.
Protocoder28.04.2014 12:49:24#ответить
Так и знал, что кто-нибудь обязательно это скажет, но было очень лень :)
Однако замечание верное, поэтому переписал.
Написать комментарий