Este tutorial é bem interessante ao mesmo tempo em que é relativamente simples. Vamos montar essa animação de cores CSS3 usando cálculos em javascript, com algumas funções do objeto Math (round, random e floor). No final do tutorial você vai ver um link para o código demonstrativo no CodePen. Vamos lá!
Tutorial passo a passo:
Passo 1: Vamos iniciar criando o nosso HTML simples. Vai existir somente uma div com id gradient, pois não temos como usar esses efeitos de animação diretamente no body.
Passo 2: O CSS aqui é igualmente simples, removemos as margens e espaços do body (não obrigatório) e definimos que a nossa div #gradient possuirá tamanho total da tela.
* Lembre-se de definir altura de 100% no html e body para que possamos usar essa mesma unidade na nossa div:
html,
body {
width: 100%;
height: 100%;
body {
padding: 0;
margin: 0;
}
#gradient {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
Passo 3: Agora vamos iniciar a montagem do javascript. Criaremos um vetor contendo o RGB das cores que queremos no nosso efeito, um outro vetor contendo quatro índices (que vai gerar a aleatoriedade de cores – comentários no código abaixo) e depois vamos declarar o fator de mudança das cores na animação e a velocidade com que a animação deve rodar (em milissegundos):
var cores = new Array(
[62,35,255],
[60,255,60],
[255,35,98],
[45,175,230],
[255,0,255],
[255,128,0]
);
/**
* Explicação dos índices:
* 0 = cor atual da esquerda;
* 1 = proxima cor da esquerda;
* 2 = cor atual da direita;
* 3 = proxima cor da direita
*/
var indices = [0,1,2,3];
var i = 0;
var fator_anima = 0.002;
var veloc_anima = 10; //em milissegundos
Passo 4: Vamos agora criar a função atualiza, que vai realizar toda a funcionalidade de alterar as cores:
function atualiza()
Passo 5: Dentro da função, declararemos novas variáveis para receber as cores iniciais, evitando que a animação comece sem cor nenhuma:
// Estas variáveis receberão nossas cores 0 e 1
var c0_0 = cores[indices[0]];
var c0_1 = cores[indices[1]];
var c1_0 = cores[indices[2]];
var c1_1 = cores[indices[3]];
// E decrementamos a variável i para que o loop de cores seja constante
// (fará o rgb das cores ser diminuído para gerar o efeito)
var passo = 1 - i;
Passo 6: Com a função Math.round, que arredonda os valores, geramos o RGB degradê das nossas duas cores iniciais:
var r1 = Math.round(passo * c0_0[0] + i * c0_1[0]);
var g1 = Math.round(passo * c0_0[1] + i * c0_1[1]);
var b1 = Math.round(passo * c0_0[2] + i * c0_1[2]);
var r2 = Math.round(passo * c1_0[0] + i * c1_1[0]);
var g2 = Math.round(passo * c1_0[1] + i * c1_1[1]);
var b2 = Math.round(passo * c1_0[2] + i * c1_1[2]);
// color1 e color2 são variáveis que serão chamadas como CSS
var color1 = "rgb("+r1+","+g1+","+b1+")";
var color2 = "rgb("+r2+","+g2+","+b2+")";
Passo 7: Hora de gerar o CSS que anima as cores! Usaremos a propriedade gradient, do CSS3. Será um degradê linear, a partir do topo esquerdo, em direção ao topo direito.
* Criamos duas sequências de código pois usamos vendor prefixes, para garantir que o código funcione em vários navegadores.
//Para navegadores Webkit - Chrome, Opera, Safari
$('#gradient').css({background: "-webkit-gradient(linear, left top, right top, from("+color1+"), to("+color2+"))"});
//Para navegador Firefox
$('#gradient').css({background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});
Passo 8: Agora incrementaremos nossa variável i com o fator_anima, que definimos no início, e verificar seu valor. Caso seja maior ou igual a 1, faremos com que seu valor seja o módulo da divisão por 1, e atualizaremos os índices usando as funções Math.floor (que retorna o menor valor inteiro antes do número que passarmos) e Math.random (que gera um valor aleatório):
i += fator_anima;
if(i >= 1){
i %= 1; // É o mesmo que i = i % 1
indices[0] = indices[1];
indices[2] = indices[3];
// Depois de pegar os valores dos índices 1 e 3, faremos o novo cálculo deles, dividindo o comprimento do vetor cores (length) pelo menor inteiro da soma do valor aleatório (Math.random) com o valor de cada índice
indices[1] = (indices[1] + Math.floor( 1 + Math.random() * (cores.length - 1))) % cores.length;
indices[3] = (indices[3] + Math.floor( 1 + Math.random() * (cores.length - 1))) % cores.length;
}
Passo 9: Por fim, fechamos a função e basta iniciarmos a nossa função atualiza utilizando setInterval, que fará a chamada no tempo que declaramos no início do código, na variável veloc_anima:
setInterval(atualiza,veloc_anima);
Código finalizado:
* Note que reduzimos um pouco o código, mas a funcionalidade é a mesma.
var cores = new Array( [62,35,255], [60,255,60], [255,35,98], [45,175,230], [255,0,255], [255,128,0] ), indices = [0,1,2,3], i = 0, fator_anima = 0.002, veloc_anima = 10; function atualiza(){ var c0_0 = cores[indices[0]], c0_1 = cores[indices[1]], c1_0 = cores[indices[2]], c1_1 = cores[indices[3]]; var passo = 1 - i, r1 = Math.round(passo * c0_0[0] + i * c0_1[0]), g1 = Math.round(passo * c0_0[1] + i * c0_1[1]), b1 = Math.round(passo * c0_0[2] + i * c0_1[2]), r2 = Math.round(passo * c1_0[0] + i * c1_1[0]), g2 = Math.round(passo * c1_0[1] + i * c1_1[1]), b2 = Math.round(passo * c1_0[2] + i * c1_1[2]), color1 = "rgb("+r1+","+g1+","+b1+")", color2 = "rgb("+r2+","+g2+","+b2+")"; $('#gradient').css({ background: "-webkit-gradient(linear, left top, right top, from("+color1+"), to("+color2+"))"}).css({ background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"}); i += fator_anima; if(i >= 1){ i %= 1; indices[0] = indices[1]; indices[2] = indices[3]; indices[1] = (indices[1] + Math.floor( 1 + Math.random() * (cores.length - 1))) % cores.length; indices[3] = (indices[3] + Math.floor( 1 + Math.random() * (cores.length - 1))) % cores.length; } } setInterval(atualiza,veloc_anima);
Confira a demonstração do código no link abaixo: