Главная » Файлы » Прочие скрипты » Яваскрипты |
Плавные переходы цвета для текста и кнопок от 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. Ни в одном браузере не было обнаружено торможения анимации или каких либо багов. Так как же можно применять данный скрипт? По разному! | |
Просмотров: 491 | Загрузок: 0 | |
Всего комментариев: 0 | |
| |