Javascript.RU

Плавное перетекание цвета из одного в другой javascript. Fading - плавное изменение цвета. Плавное изменение цвета фона.

Вот у меня есть 2 цвета

#f91207
#01ff0c

Я хочу чтобы цвет фона, либо цвет текста плавно перетек из одного цвета в другой, т.е. плавно поменялся.
Порывшись в интернете я конечно нашел некоторые скрипты которые от части выполняли бы мою задумку, но я не был уверен в надежности этих скриптов и в том что они одинаково будут работать во всех браузерах.

Что касается алгоритма то он очень прост, единственный минус в том что скорость смены нужно подбирать вручную, но это даже не минус а скорее удобство.

Всем известно что цвет состоит из 3-х цветов RGB
R - красный
G - зеленый
B - синий

Собственно и алгоритм работы скрипта очень прост - нужно разбить каждый цвет на 3 составляющих R, G, B после чего найти разницу составляющих одного цвета от другого и вычислить число на которое будет циклично изменяться тот или иной оттенок.

Модель RGB подразумевает по 255 оттенков на каждый канал - это значит что белый цвет будет 255, 255, 255 а черный цвет будет 0, 0, 0

Т.е. FF это число 255 в 16-ричной системе счисления.

Собственно вот код который нужно подключить к сайту:

<script type="text/javascript" src="http://scriptjava.net/source/scriptjava/scriptjava.js"></script>
<script type="text/javascript">
var fade = function () {
	return {
		num_step:0,
		ini:function (s_col,e_col,step,tim,id,style,fun) {
			this.num_step=0;
			var s_col_map=[];
			var e_col_map=[];
			var gen_col='';
			var k=0;
			var num = (s_col.charAt(0)=='#') ? 1:0;
			for(var i=num;i<s_col.length;i=i+2) {
				s_col_map[k++]=parseInt(s_col.charAt(i)+s_col.charAt(i+1),16);
			}
			var k=0;
			var num = (e_col.charAt(0)=='#') ? 1:0;
			for(var i=num;i<e_col.length;i=i+2) {
				e_col_map[k++]=parseInt(e_col.charAt(i)+e_col.charAt(i+1),16);
			}
			
			var d_rcol = (s_col_map[0]>e_col_map[0]) ? Math.floor(s_col_map[0]-e_col_map[0]) : Math.floor(e_col_map[0]-s_col_map[0]);
			d_rcol = (d_rcol!=0) ? Math.floor(d_rcol/step) : 0;
			
			var d_gcol = (s_col_map[1]>e_col_map[1]) ? Math.floor(s_col_map[1]-e_col_map[1]) : Math.floor(e_col_map[1]-s_col_map[1]);
			d_gcol = (d_gcol!=0) ? Math.floor(d_gcol/step) : 0;
			
			var d_bcol = (s_col_map[2]>e_col_map[2]) ? Math.floor(s_col_map[2]-e_col_map[2]) : Math.floor(e_col_map[2]-s_col_map[2]);
			d_bcol = (d_bcol!=0) ? Math.floor(d_bcol/step) : 0;
			
			this.exe(s_col_map,e_col_map,d_rcol,d_gcol,d_bcol,step,tim,id,style,fun);
		},
		exe:function (s_col_map,e_col_map,d_rcol,d_gcol,d_bcol,step,tim,id,style,fun) {
			var r_c=(s_col_map[0]>e_col_map[0]) ? s_col_map[0]-d_rcol : s_col_map[0]+d_rcol;
			var g_c=(s_col_map[1]>e_col_map[1]) ? s_col_map[1]-d_gcol : s_col_map[1]+d_gcol;
			var b_c=(s_col_map[2]>e_col_map[2]) ? s_col_map[2]-d_bcol : s_col_map[2]+d_bcol;
			s_col_map[0]=r_c;
			s_col_map[1]=g_c;
			s_col_map[2]=b_c;
			this.num_step++;
			$$(id,style,'rgb('+r_c+','+g_c+','+b_c+')');
			if(this.num_step<step) {
				var th=this;
				setTimeout(function () { th.exe(s_col_map,e_col_map,d_rcol,d_gcol,d_bcol,step,tim,id,style,fun); },tim);
			}
			else {
				$$(id,style,'rgb('+e_col_map[0]+','+e_col_map[1]+','+e_col_map[2]+')');
				if(typeof fun == 'function') {
					fun();
				}
			}
		}
	}
}
</script>

Теперь главное - как пользоваться этим кодом

Допустим у нас на странице есть текст и блок с фоном

<div id="text" style="color:#0000ff;font-size:18px;">Мой текст</div>
<div id="block" style="width:210px;height:50px;background-color:#ff0000;
"></div>

Чтобы плавно сменить каждому элементу фон или цвет напишим небольшой скрипт:

<script type="text/javascript">
//для текста
var fef_text=new fade();
fef_text.ini('#0000ff','#ff0000',25,30,'text','color');
//для блока с фоном
var fef_block=new fade();
fef_block.ini('#ff0000','#00ff00',25,30,'block','backgroundColor');
</script>

Посмотреть пример

Теперь давайте разберемся что мы вообще делаем и какие параметры передаем в функцию ini()

Сразу скажу что передать параметров этой функции можно больше, но об этом позднее
И так пишу общий вид функции

ini('начальный цвет','конечный цвет',число переходов,время таймера,'id элемента','css параметр',функция по завершению работы скрипта);

'#ff0000' - начальный цвет
'#00ff00'-конечный цвет
25 - число переходов или кадров, это число не должно быть большим и по любому должно быть меньше 100
30 - время таймера
'block' - id элемента
'backgroundColor' - свойство стиля элемента которому будет присваиваться значение цвета

Теперь немного усложним пример

<div id="text" style="color:#0000ff;font-size:18px;">Мой текст</div>
<div id="block" style="width:210px;height:50px;background-color:#ff0000;
"></div>
<script type="text/javascript">
//для текста
var fef_text=new fade();
fef_text.ini('#0000ff','#ff0000',25,30,'text','color',function() { $$('text','Функция сработала после того как скрипт выполнился');});
//для блока с фоном
var call_b = function () {
     setTimeout(function() {fef_block.ini('#00ff00','#cc00ff',25,30,'block','backgroundColor');},3000);
}
var fef_block=new fade();
fef_block.ini('#ff0000','#00ff00',25,30,'block','backgroundColor',call_b);
</script>

Посмотреть пример

В последнем примере мы добавили еще один параметр - функцию обратного вызова

Конечно можно было еще высчитывать проценты и потом на основе этих процентов высчитывать число переходов, но мне это было не нужно, ведь чтобы достичь плавного эффекта не обязательно использовать много переходов, главное для плавности это таймер
Впрочем чем больше диапазон различий цветов тем больше можно устанавливать число переходов

+2

Автор: Гость (не зарегистрирован), дата: 6 июля, 2012 - 20:13
#permalink

неплохо, но на css3 подобное занимает намного меньше строк кода...


Автор: Гость (не зарегистрирован), дата: 13 июля, 2012 - 11:19
#permalink

может легче использовать jQuery?
$('.elem').animate({color : "#FFFFFF"});


Автор: Гость (не зарегистрирован), дата: 13 июля, 2012 - 11:20
#permalink

забыл время
$('.elem').animate({color : "#FFFFFF"}, 1000);


Автор: Гость (не зарегистрирован), дата: 19 февраля, 2015 - 10:55
#permalink

Лишние обращения к массиву выведите в переменные. Так и код читабельнее будет и браузеру понравится.


Автор: Гость (не зарегистрирован), дата: 24 июля, 2015 - 12:37
#permalink

//---- s_col_map, = [ 'ff', '00' , '00' ] --> [ 255, 0, 0 ]

var
i = 0, r = [],
s = "#ff0000"
.match( /\w{2}/g )
.map(function(e){return parseInt( e, 16)}),

e = ... // e_col_map
;

// Math.abs 120 - 255 = +135

for( ; i<2; i++ ){
var z = Math.abs ( s[i] - e[i] );
r.push( z != 0 ? Math.floor( z / step ) : 0 );
}

________
(s_col_map[0]>e_col_map[0]) ? Math.floor(s_col_map[0]-e_col_map[0]) : Math.floor(e_col_map[0]-s_col_map[0])

______

... fn: exe -----

--== or ==--
c = [
(s[ 0 ] > e[ 0 ] ) ? s[ 0 ] - r[ 0 ] : s[ 0 ] + r[ 0 ],
(s[ 1 ] > e[ 1 ] ) ? s[ 1 ] - r[ 1 ] : s[ 1 ] + r[ 1 ],
(s[ 2 ] > e[ 2 ] ) ? s[ 2 ] - r[ 2 ] : s[ 2 ] + r[ 2 ]
]

var r_c=(s_col_map[0]>e_col_map[0]) ? s_col_map[0]-d_rcol : ...

и т.д.


 
Поиск по сайту
Другие записи этого автора
gordon freeman
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Популярные таги
Последние темы на форуме
Forum