Animeer kleuren via jQuery

Posted at January 02, 2012

Als je veel met jQuery werkt sta je soms versteld als je erachter komt dat er dingen zijn die niet standaard mogelijk zijn met de uitgebreide javascript library. Zo liep ik gister tegen het probleem dat ik kleuren wou animeren via jQuery maar dit standaard niet mogelijk is.

Als uitbreiding op jQuery kan je jQuery UI integreren in je website, maar ik vond hem nogal groot en lomp. Helemaal als je hem puur inlaadt voor de kleuranimatie’s.

Hier is de jQuery color plugin van een aantal developers die erg betrokken zijn bij jQuery. Ook al is de enige functionaliteit van de plugin kleuren animaren, hij is alsnog best groot. Hij biedt allemaal extra functionaliteit die soms handig kan zijn, maar in mijn geval alsnog overbodig was.

Na wat zoeken vond ik op stackoverflow een oplossing die perfect leek. Je ript gewoon de kleuren functie uit jQuery UI en je hebt een perfecte oplossing. Helaas kon ik dit op deze manier niet werkend krijgen: in de functie wordt namelijk een aantal keer verwezen naar een colors array die niet mee geript was. Hier is de functie zodanig dat hij bij mij wel werkt:

/* stripped from jquery UI 1.9pre /
function getColor(a,b){var c;do{c=$.curCSS(a,b);if(c!=""&&c!=="transparent"||$.nodeName(a,"body"))break;b="backgroundColor"}while(a=a.parentNode);return getRGB(c)}function getRGB(a){var b;if(a&&a.constructor===Array&&a.length===3)return a;if(b=/rgb(s([0-9]{1,3})s,s([0-9]{1,3})s,s([0-9]{1,3})s)/.exec(a))return[parseInt(b[1],10),parseInt(b[2],10),parseInt(b[3],10)];if(b=/rgb(s([0-9]+(?:.[0-9]+)?)%s,s([0-9]+(?:.[0-9]+)?)%s,s([0-9]+(?:.[0-9]+)?)%s)/.exec(a))return[parseFloat(b[1])2.55,parseFloat(b[2])2.55,parseFloat(b[3])2.55];if(b=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)];if(b=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(a))return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)];if(b=/rgba(0, 0, 0, 0)/.exec(a))return colors["transparent"];return colors[$.trim(a).toLowerCase()]}$.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(a,b){$.fx.step[b]=function(a){if(!a.colorInit){a.start=getColor(a.elem,b);a.end=getRGB(a.end);a.colorInit=true}a.elem.style[b]="rgb("+Math.max(Math.min(parseInt(a.pos(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var colors={black:[0,0,0],blue:[0,0,255],green:[0,128,0],red:[255,0,0],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]}

Als je deze functie na jQuery inlaadt (hij past jQuery aan) en voor je eigen script kan je kleuren ook animeren.

Hieronder is een voorbeeld waar ik de achtergrond kleur animeer on hover (ik gebruik de .on functie in plaats van hover omdat er in mijn geval dynamisch content wordt ingeladen nadat dit script wordt uitgevoerd).

if(!Modernizr.csstransitions) {
    $('#blog-posts').children()
        .on('mouseenter', { color: '#eeeeee' }, fadeBg)
        .on('mouseleave', { color: '#ffffff' }, fadeBg);
}
function fadeBg(e) {
    $(this).stop().animate({ backgroundColor: e.data.color }, 400 );
}

Zoals je ziet is er een if die checkt of een bepaalde waarde juist is of niet. In mijn geval wil ik een achtergrond animeren on hover, dit kan ik ook doen met CSS3. Ik gebruik modernizr om te checken of de browser de CSS3 eigenschap transition ondersteund, als de browser het ondersteund wordt de klasse .csstransitions aan mijn html tag toegevoegd en wordt bovenstaande boolean in de if check op true gezet.

Als de browser de eigenschap ondersteund doe ik de animatie via css:

.csstransitions #blog-posts a.blog-post {
    background-color:#ffffff;
    moz-transition: background-color .4s;
    -webkit-transition:background-color .4s;
    -o-transition: background-color .4s;
    -ms-transition: background-color .4s;
    transition: background-color .4s;
}

Note

Op het moment van schrijven is er een bug in chrome die ervoor zorgt dat animeren via CSS3 niet werkt zodra je de link al bezocht heb. Zie deze twee bugs.

Posted at January 02, 2012, under jQuery.