Главная » Файлы » Прочие скрипты » Яваскрипты

Плавные переходы цвета для текста и кнопок от AD
22.06.14, 15:23:13



Сегодня мы с вам напишем скрипт цветовой анимации. Цветовая анимация - полезная и интересная штука, которая поможет создать множество красивых эффектов на вашем сайте. Что я подразумеваю под цветовой анимацией? - плавное изменение одного цвета на другой.

Начнем с того, что создадим объект, в котором и будут хранится все функции нашего будущего скрипта:

Код
<script type="text/javascript">  
  colors = {  
}  
  </script>


Теперь нам необходимо создать функцию, которая бы получала начальный цвет элемента. Так как конструкция element.style.property не возвращает данные, хранящиеся например в css, то мы воспользуемся связкой данной конструкции с конструкцией computedStyle. Так как element.style работает в разы быстрее чем computedStyle, мы сначала будем проверять наличие инлайновых данных. Так как разработчики IE опять наплевали на стандарты пошли своим путем, то я так же добавил использование конструкции currentStyle. Всю функцию я назвал current. Она принимает сам элемент и требуемый стиль и возвращает данные по стилю. Вот что получилось:

Код
<script type="text/javascript">  
  colors = {  
current: function(el,st){  
var result;  
if(el.style[st] && el.style[st]!=''){result=el.style[st]} else  
if(/*@cc_on!@*/false){result=el.currentStyle[st]} else  
{result=document.defaultView.getComputedStyle(el,null)[st]}  
return result=='transparent' ? '#FFFFFF' : result;  
}  
}  
  </script>


Едем дальше. Разные браузеры возвращают информацию о цвете по разному. К примеру IE возвращает именно то, что записано в стиле, а FireFox - цвет, преобразованный в вид rgb(r,g,b). Для того, чтобы свести все различия к единому результату, я написал функцию обработки цвета и перевода его hex значения к развернутому rgb виду. Функцию я назвал просто - torgb. Вот как выглядит эта функция, она добавлена после функции current:

Код
<script type="text/javascript">  
  colors = {  
current: function(el,st){  
var result;  
if(el.style[st] && el.style[st]!=''){result=el.style[st]} else  
if(/*@cc_on!@*/false){result=el.currentStyle[st]} else  
{result=document.defaultView.getComputedStyle(el,null)[st]}  
return result=='transparent' ? '#FFFFFF' : result;  
},  

torgb: function(col){  
var r,g,b,result;  
function rgb(a,b){  
var q = {'A':10,'B':11,'C':12,'D':13,'E':14,'F':15};  
return parseInt(a in q?q[a]:a)*16+parseInt(b in q?q[b]:b);  
}  
result=col.toUpperCase();  
if(/RGB\(\d+,\s?\d+,\s?\d+\)/.test(result)){  
r = result.match(/\d+/g)[0];  
g = result.match(/\d+/g)[1];  
b = result.match(/\d+/g)[2];  
}else  
if(/#([0-9A-F]{2}){3}/.test(result)){  
r = rgb(result.charAt(1),result.charAt(2));  
g = rgb(result.charAt(3),result.charAt(4));  
b = rgb(result.charAt(5),result.charAt(6));  
}else  
if(/#([0-9A-F]{1}){3}/.test(result)){  
r = rgb(result.charAt(1),result.charAt(1));  
g = rgb(result.charAt(2),result.charAt(2));  
b = rgb(result.charAt(3),result.charAt(3));  
}  
return {r:r,g:g,b:b};  
}  
}  
  </script>


Кстати, кому интересно, вот самописная функция обратного перевода чисел из десятичной системы в шестнадцатеричную:

Код
<script type="text/javascript">  
  var i = 102; // сюда вставляем нужное число  
  var x='';  
  var q = [0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'];  
  do{i=i%16;x='F'+x}while(i>16);  
  x=q[i]+x  
  alert(x); // получаем результат  
  </script>


Не важно, забейте. =) Едем дальше.

Пришло время добавить собственно саму функцию-аниматор.я не буду подробно описывать её и её элементы. Скажу только что обкатывал и дописывал её приличное количество времени. "Функция" эта на самом деле состоит из двух функций и двух параметров. Первая функция animtype отвечает за тип анимации (всего я сделал 4 типа). Вторая функция animate является функцией-аниматором и создает саму анимацию, а так же определяет состояние анимируемых элементов. Масив animator хранит все анимации, воспроизводящиеся в данный момент, а параметр anielems считает число анимируемых элементов. Вот весь скрипт анимации в сборе:

Код
<script type="text/javascript">  
  colors = {  
current: function(el,st){  
var result;  
if(el.style[st] && el.style[st]!=''){result=el.style[st]} else  
if(/*@cc_on!@*/false){result=el.currentStyle[st]} else  
{result=document.defaultView.getComputedStyle(el,null)[st]}  
return result=='transparent' ? '#FFFFFF' : result;  
},  
torgb: function(col){  
var r,g,b,result;  
function rgb(a,b){  
var q = {'A':10,'B':11,'C':12,'D':13,'E':14,'F':15};  
return parseInt(a in q?q[a]:a)*16+parseInt(b in q?q[b]:b);  
}  
result=col.toUpperCase();  
if(/RGB\(\d+,\s?\d+,\s?\d+\)/.test(result)){  
r = result.match(/\d+/g)[0];  
g = result.match(/\d+/g)[1];  
b = result.match(/\d+/g)[2];  
}else  
if(/#([0-9A-F]{2}){3}/.test(result)){  
r = rgb(result.charAt(1),result.charAt(2));  
g = rgb(result.charAt(3),result.charAt(4));  
b = rgb(result.charAt(5),result.charAt(6));  
}else  
if(/#([0-9A-F]{1}){3}/.test(result)){  
r = rgb(result.charAt(1),result.charAt(1));  
g = rgb(result.charAt(2),result.charAt(2));  
b = rgb(result.charAt(3),result.charAt(3));  
}  
return {r:r,g:g,b:b};  
},  
animtype: function(p,ani){  
switch(ani){  
case 'simple':return p;break;  
case 'compress':var x=2;return Math.pow(p,2)*((x+1)*p-x);break;  
case 'smooth':function d(p){return Math.pow(p,3)};if(p<0.5){return d(2*p)/2;}else{return (2-d(2*(1-p)))/2;};break;  
case 'jump':function c(p){for(var a=0,b=1;1;a+=b,b/=2){if(p>=(7-4*a)/11)return -Math.pow((11-6*a-11*p)/4,2)+Math.pow(b,2);}};return 1-c(1-p);break;  
default:return p;break;  
}  
},  
animator:{},  
anielems:0,  
animate: function(ani,obj,v,time,callback){  
for(key in v){anima(key,v[key])}  
function anima(param,to){  
var from,aID;  
to = colors.torgb(to);
from = colors.torgb(colors.current(obj,param));  
for(key in colors.animator){  
if(colors.animator[key].o==obj && colors.animator[key].p==param){  
clearInterval(colors.animator[key].timer)  
}  
}  
aID=colors.anielems;  
colors.animator[aID]={  
o:obj,  
p:param,  
start: new Date().getTime(),  
timer: setInterval(function(){  
var now,progress,u,r,g,b;  
now=(new Date().getTime())-colors.animator[aID].start;  
progress=now/time;  
u = colors.animtype(progress,ani);  
r=parseInt((parseInt(to.r)-parseInt(from.r))*u+parseInt(from.r));  
g=parseInt((parseInt(to.g)-parseInt(from.g))*u+parseInt(from.g));  
b=parseInt((parseInt(to.b)-parseInt(from.b))*u+parseInt(from.b));
obj.style[param]='rgb('+r+','+g+','+b+')';  
if(progress>=1){  
clearInterval(colors.animator[aID].timer);  
obj.style[param]='rgb('+to.r+','+to.g+','+to.b+')';  
if(callback){callback()}  
delete colors.animator[aID];  
}  
},10)  
}  
colors.anielems++;  
}  
}  
}  
  </script>


А вот его, сжатая с помощью YUI Compressor, версия:

Код
<script type="text/javascript">  
  colors={current:function(el,st){var result;if(el.style[st]&&el.style[st]!=""){result=el.style[st]}else{if(/*@cc_on!@*/false){result=el.currentStyle[st]}else{result=document.defaultView.getComputedStyle(el,null)[st]}}return result=="transparent"?"#FFFFFF":result},torgb:function(e){var h,f,c,a;function d(i,g){var j={A:10,B:11,C:12,D:13,E:14,F:15};return parseInt(i in j?j[i]:i)*16+parseInt(g in j?j[g]:g)}a=e.toUpperCase();if(/RGB\(\d+,\s?\d+,\s?\d+\)/.test(a)){h=a.match(/\d+/g)[0];f=a.match(/\d+/g)[1];c=a.match(/\d+/g)[2]}else{if(/#([0-9A-F]{2}){3}/.test(a)){h=d(a.charAt(1),a.charAt(2));f=d(a.charAt(3),a.charAt(4));c=d(a.charAt(5),a.charAt(6))}else{if(/#([0-9A-F]{1}){3}/.test(a)){h=d(a.charAt(1),a.charAt(1));f=d(a.charAt(2),a.charAt(2));c=d(a.charAt(3),a.charAt(3))}}}return{r:h,g:f,b:c}},animtype:function(e,b){switch(b){case"simple":return e;break;case"compress":var a=2;return Math.pow(e,2)*((a+1)*e-a);break;case"smooth":function f(c){return Math.pow(c,3)}if(e<0.5){return f(2*e)/2}else{return(2-f(2*(1-e)))/2}break;case"jump":function g(h){for(var d=0,c=1;1;d+=c,c/=2){if(h>=(7-4*d)/11){return -Math.pow((11-6*d-11*h)/4,2)+Math.pow(c,2)}}}return 1-g(1-e);break;default:return e;break}},animator:{},anielems:0,animate:function(a,e,b,d,f){for(key in b){c(key,b[key])}function c(h,j){var i,g;j=colors.torgb(j);i=colors.torgb(colors.current(e,h));for(key in colors.animator){if(colors.animator[key].o==e&&colors.animator[key].p==h){clearInterval(colors.animator[key].timer)}}g=colors.anielems;colors.animator[g]={o:e,p:h,start:new Date().getTime(),timer:setInterval(function(){var n,m,l,p,o,k;n=(new Date().getTime())-colors.animator[g].start;m=n/d;l=colors.animtype(m,a);p=parseInt((parseInt(j.r)-parseInt(i.r))*l+parseInt(i.r));o=parseInt((parseInt(j.g)-parseInt(i.g))*l+parseInt(i.g));k=parseInt((parseInt(j.b)-parseInt(i.b))*l+parseInt(i.b));e.style[h]="rgb("+p+","+o+","+k+")";if(m>=1){clearInterval(colors.animator[g].timer);e.style[h]="rgb("+j.r+","+j.g+","+j.b+")";if(f){f()}delete colors.animator[g]}},10)};colors.anielems++}}};  
  </script>


Скрипт запускается следующим образом:

Код
<script type="text/javascript">  
  colors.animate(тип анимации,элемент,хэш значений,время,колбэк);  

  // пример  

  colors.animate("smooth",this,{"backgroundColor":"#FF9900"},100,function(){alert('Готово!')})  
  </script>


Где тип анимации - строка, которая может принимать значения
'simple' - простая, линейная анимация
'smooth' - сглаженная анимация, замедленная в начале и в конце.
'jump' - анимация прыжком, после достижения финиш позиции анимация пару раз повторит последние шаги.
'compress' - сжимающая имация, то же что и прыжок, но анимация переходит финиш позицию, затем в несколько колебаний устанавливает нужное значение.
Элемент - сам анимируемый элемент. Хэш значений - хэш, содержащий все названия анимируемых параметров и нужные значения. Одновременно можно указать несколько анимируемых параметров:
{'color':'#000','borderColor':'#FFF','backgroundColor':#123123} и так далее. Время - время выполнения анимации в милисекундах. Колбэк - функция, выполняемая после завершения анимации (не обязательный параметр).

Данный скрипт полностью кроссбраузерен и работает во всех версиях IE начиная с 5.5, в Opera 9 и 10, в Mozilla FireFox, в Safari и в Google Chrome. Ни в одном браузере не было обнаружено торможения анимации или каких либо багов.

Так как же можно применять данный скрипт? По разному!

Категория: Яваскрипты | Добавил: Apocalypse | Теги: переходы, цвета, AD, текста, От, Плавные, кнопок, для
Просмотров: 396 | Загрузок: 0 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email: