@
.
]
#
{
<
!
}

NOUS LES DEVS

Animation @keyframes/js

Ajouter de l'animation sur un background

Niveau : débutant(e)
</> </> </>

Le projet

A l’agence j’ai eu l’occasion de travailler sur l’application Likwid qui permet d’écouter de la musique « made in JOIN ». Quand j’ai reçu la maquette dans les mains, j’ai remarqué qu’il y avait vraiment moyen de se faire plaisir. Une landing page super épurée comme je les aime, où tu peux presque tout animer et en particulier une section, qui est le descriptif du produit avec en fond, une liste de différentes jaquettes/artistes disponibles sur l’application.

Le background

J’ai eu l’idée d’ajouter un défilement infini du background avec les jaquettes, super simple étant donné que le fond était répétable dans l’axe horizontale.

background_likwid

CSS

J’ai réalisé l’animation avec mon préprocesseur favori j’ai nommé « SASS ».

Au niveau de la structure HTML, il y a juste un div qui prend 100% de la largeur de la page avec une hauteur fixe pour laquelle j’ai ajouté une image background avec un repeat-x. Mais là ce qui est intéressant, c’est de voir comment l’animation est codée. En fait, j’ai utilisé les @keyframes pour déplacer le background de 200% sur la gauche avec une durée assez longue pour avoir un déplacement lent et fluide.

@mixin keyframes($name) {
	@-webkit-keyframes #{$name} {
		@content; 
	}
	@-moz-keyframes #{$name} {
		@content;
	}
	@-ms-keyframes #{$name} {
		@content;
	}
	@keyframes #{$name} {
		@content;
	} 
}

.background{
	@include keyframes("animation_background_likwid"){
		0%   { background-position: 0% 0px; }
		100% { background-position: -200% 0px; }
	}
	
	$time_animation_vignette:45s;
	
	-webkit-animation: animation_background_likwid $time_animation_vignette infinite linear;
	-moz-animation:    animation_background_likwid $time_animation_vignette infinite linear;
	-o-animation:      animation_background_likwid $time_animation_vignette infinite linear;
	animation:         animation_background_likwid $time_animation_vignette infinite linear;
}

Et là forcement les « experts » vont me crier dessus car il y a plusieurs problèmes avec ce code !

Déjà c’est du CSS3, donc ce n’est pas compatible partout, mais après aucune spécification n’est définie donc passons ce point.

Secondo, vu qu’on ne connait pas la largeur et que l’animation ne va que dans un sens, arrivé à 100% de celle-ci, l’image va revenir instantanément à sa position d’origine et il y aura comme un « saut d’image » et ce n’est pas vraiment cool… Mais là encore, disons que vu le temps assez long de l’animation, c’est négligeable (ben ouais si l’utilisateur reste déjà 45 secondes sur la page c’est super).

Et le troisième point et non des moindres, c’est la charge processeur. Je me suis permis de faire un bench à l’arrache avec une version de Firefox 48 et là je suis effaré… 80% d’utilisation du CPU. Bon après ce chiffre est à prendre avec des pincettes et je suis nullement expert en ce domaine et la page tourne très bien.

JS VS CSS

Bon et le JavaScript dans toute cette histoire ? Il y a plusieurs milliers d’années, je claquais la plupart de mes animations en JS, j’étais tellement habitué et jQuery rendait la chose tellement facile. Ensuite le CSS3 a fait son apparition, assez rapidement d’ailleurs (ou pas) et il a bien fallu s’y mettre, comme toutes les nouvelles technos qui sortent !

Et voilà, l’animation en CSS3 présente des inconvénients.
J’aimerais bien savoir si cette animation codée en JS ne serait pas mieux ? Ben.. On va voir ça tout de suite !

1er test, un setInterval à l’ancienne, du coup on règle plusieurs problèmes, c’est compatible partout (celui qui me dit que ce n’est pas compatible avec le JS désactivé sort tout de suite !), il n’y a pas de saut d’image, l’animation sera « vraiment infinie », et au niveau du processeur ça affiche 60% soit 20% de moins ! Bon ben du coup JavaScript est déjà meilleur…

var likwid_bg = $(".background");
var background_decallage = 0;

setInterval(function(){
	likwid_bg.css("background-position",background_decallage+"px 0px");
	background_decallage = background_decallage-1;
}, 50);

2ieme test, j’utilise la fonction animate de jQuery pour voir si elle fait mieux, même si techniquement, c’est la même chose. Bon j’ai mis grossièrement un décalage de -200% et 90 secondes de délai juste pour tester la charge processeur, on est d’accords, c’est pas propre du tout ! Malheureusement, j’ai une charge de 90%, vraiment bizarre…

$('.module .background-animation').animate({ backgroundPosition: '-200%'}, 90000, 'linear');

3ieme test, je retente un animate jQuery avec une fonction récursive juste par curiosité, et je tombe à 80% de charge processeur.

function animation_bg(){
	$('.module .background-animation').animate({ backgroundPosition: '-=1%'},200, 'linear', function(){
		animation_bg();
	});
}
animation_bg();

Et le test le plus probant que j’ai eu c’est en conservant le setInterval avec une décrémentation du background position.

setInterval(function(){
	likwid_bg.css("background-position","-=1");
}, 60);

Résultat

J’ai réussi à faire l’animation que je voulais en testant différentes techniques avec des avantages et des inconvénients. Je le répète, les chiffres que j’ai donnés sont à prendre avec des pincettes, c’est une recherche que j’ai voulu faire en écrivant cet article, mon objectif étant de réaliser simplement une animation. Je pense que l’animation peut encore être améliorée soit en utilisant du code JavaScript natif, soit en changeant l’algo, ou encore avec l’utilisation d’une librairie telle que GSAP.

Démo

11/09/2016

Yann Vangampelaere - nouslesdevs -

NOUS LES DEVS

Vous aimez ce que je fais ? Vous voulez que j'en fasse plus ? dans le développement du blog.