Плавное перетекание цвета из одного в другой 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>
Посмотреть пример
В последнем примере мы добавили еще один параметр - функцию обратного вызова
Конечно можно было еще высчитывать проценты и потом на основе этих процентов высчитывать число переходов, но мне это было не нужно, ведь чтобы достичь плавного эффекта не обязательно использовать много переходов, главное для плавности это таймер
Впрочем чем больше диапазон различий цветов тем больше можно устанавливать число переходов
|
неплохо, но на css3 подобное занимает намного меньше строк кода...
может легче использовать jQuery?
$('.elem').animate({color : "#FFFFFF"});
забыл время
$('.elem').animate({color : "#FFFFFF"}, 1000);
Лишние обращения к массиву выведите в переменные. Так и код читабельнее будет и браузеру понравится.
//---- 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 : ...
и т.д.