Comment animer un sprite qui boit du café avec ScrollMagic

Créer un mouvement initié par un défilement peut être extrêmement gratifiant. Nous allons plonger dans un effet particulier vu sur le site Web Casper Mattress (créé par Jonnie Hallman) qui a captivé de nombreux développeurs. Dans ce tutoriel, nous allons détailler les étapes nécessaires pour créer une animation de sprite similaire avec ScrollMagic.

Résultat final

Jetons un coup d'oeil à ce que nous allons créer:

Le sprite

Avant de commencer à coder, nous aurons besoin d’un sprite comme base de cette démonstration. Voici celui que nous utiliserons: moi, en train de savourer une bonne tasse de café. Vous pouvez en prendre une copie pour suivre le tutoriel.

Mmmmm

L'ensemble du sprite est disposé de manière linéaire le long de l'axe des x. Chaque image de l'image-objet mesure 200 x 509 pixels, ce qui donne une taille totale de 2000 x 509 pixels (chaque image a une largeur de 200 x multipliée par dix images clés).. 

Des points supplémentaires déjà

Pour les plus curieux, j'ai spécifiquement utilisé le plugin Gulp gulp.spritesmith au lieu de reconstituer manuellement le sprite. Bien qu'il ne soit pas nécessaire de créer cette démo, voici la configuration que j'ai utilisée au cas où vous souhaiteriez l'essayer vous-même:

var gulp = require ('gulp'); var spritesmith = require ('gulp.spritesmith'); gulp.task ('sprite', function () var spriteData = gulp.src ('images / *. png'). pipe (spritesmith (imgName: 'sprite.png', cssName: 'sprite.css', algorithme : sort: false, algorithme: 'left-right',)); return spriteData.pipe (gulp.dest ('images / dist')););

Il est important de noter que la propriété algorithm peut accepter un assortiment de valeurs afin d’organiser l’image-objet de manière linéaire, verticale, diagonale, etc. Je vous recommande de prendre le temps de lire plus sur ce plugin Gulp pour tous vos futurs besoins en sprite.

Créer le balisage

Le balisage est le sol à partir duquel notre démo va grandir, nous allons donc commencer par créer le conteneur dans lequel l'animation du sprite aura lieu. Nous allons également construire des conteneurs factices dans le but d'avoir des régions pour faire défiler.

La section centrale avec le contenant div est l'endroit où notre mouvement de sprite se déclenche, mais nous devrons ajouter des classes et des identifiants à des fins de style et de hook d'événement.

La classe js-scrollpin est le point à partir duquel la fenêtre d'affichage sera «épinglée» au fur et à mesure que l'utilisateur fait défiler l'écran. Ce point de blocage durera pendant une durée définie à partir de notre code JavaScript (nous en reparlerons dans une section à venir). L'intérieur div avec la classe Cadre sera le point où la magie de défilement a lieu.

Créer les styles

Notre démo ne serait pas complète sans le style, alors commençons! Pour écrire le code avec des mises à jour et des améliorations à l'esprit, nous utiliserons Sass, ce qui nous permettra de créer la boucle et les variables pour une création succincte..

nombre de cadres: 9; $ offset-val: 100;

Ces variables définissent: 

  • le nombre d'images, égal au nombre d'images dans l'image-objet 
  • et la valeur de décalage qui positionne la position d'arrière-plan de chaque image singulière à l'intérieur de l'image-objet. 

Vous remarquerez peut-être que je n'ai défini que le nombre d'images à 9 car la première image est déjà en vue et qu'il reste 9 images dans la séquence (10 - 1 = 9)..

J'ai été encadré

Comme mentionné, chaque image de notre sprite mesure 200 pixels de large, je vais donc définir la largeur du cadre comme étant 200 pixels.. 

.frame width: 200px; background-image: url (sprite.png); répétition de fond: non répétée; position de fond: 0 50%; 

L'image est chargée en fond et positionnée en conséquence.

Maintenant pour la boucle:

@pour $ i de 1 à $ nombre-cadres .frame # $ i position d'arrière-plan: - (($ i * $ offset-val) * 2) + px 50%; 

Cette boucle de Sass est la partie la plus importante. Au fur et à mesure que nous faisons défiler, chaque classe de corrélation sera basculée via JavaScript; ces noms de classe activés sont corrélés à la position de chaque image dans l'image-objet.

.frame1 background-position: -200px 50%;  .frame2 background-position: -400px 50%;  .frame3 background-position: -600px 50%;  .frame4 background-position: -800px 50%;  .frame5 background-position: -1000px 50%;  .frame6 background-position: -1200px 50%;  .frame7 background-position: -1400px 50%;  .frame8 background-position: -1600px 50%;  .frame9 background-position: -1800px 50%; 

La sortie compilée de notre Sass aide à expliquer comment fonctionne ce calcul, mais allons plus loin pour nous assurer de bien comprendre comment l'arithmétique est calculée..

$ i * $ offset-val

A chaque itération de la boucle, le $ i cycles variables de 1 à 9 et multipliés par la valeur de décalage (100). Enfin, nous prenons le résultat entier et le multiplions par 2. Le facteur 2 aidera à déplacer la position de l’arrière-plan par rapport à l’emplacement de chaque image dans l’image-objet. Cela correspond également à la valeur de décalage définie dans le code JavaScript dont nous parlerons dans la prochaine partie de notre parcours..

Lancer le JavaScript

La clé de cet effet est le JavaScript. Pour cette démo particulière, nous utiliserons ScrollMagic; une bibliothèque JavaScript pour les interactions de défilement magiques. Avant d'écrire un code ScrollMagic, assurons-nous d'avoir la bibliothèque ScrollMagic chargée.

Avec cela fait, nous allons établir des variables.

var frame = document.querySelector ('. frame'), frame_count = 9, offset = 100;

Les variables définies doivent avoir l’air familier car elles se rapportent directement aux valeurs que nous avons spécifiées dans notre Sass, à l’exception de la sélection de la classe frame à l’aide de document.querySelector.

contrôleur var = new ScrollMagic.Controller (globalSceneOptions: triggerHook: 0);

Le contrôleur est la classe principale requise une fois par conteneur de défilement. Notre globalSceneOptions objet passé contient un déclencheur. Les valeurs de cette propriété peuvent être un nombre compris entre 0 et 1 définissant la position du crochet de déclenchement par rapport à la fenêtre d'affichage..

new ScrollMagic.Scene (triggerHook: 0, triggerElement: '.js-scrollpin', durée: (frame_count * offset) + 'px', reverse: true) .setPin ('. js-scrollpin') .addTo (contrôleur )

Nous définissons l’épingle une fois dans la scène cible et attachons notre animation à la même scène. Nous allons créer une scène pour chaque classe et les activer ou les désactiver en fonction de la valeur de décalage du défilement.. 

Décomposer

Il reste encore quelques choses à expliquer, donc décomposons les parties importantes:

triggerElement: '.js-scrollpin'

L'élément Trigger est l'identifiant de référence du panneau contenant notre sprite..

.setPin ('. js-scrollpin')

le setPin méthode dira à ScrollMagic, une fois la triggerElement est atteint, épinglez ce panneau en haut de la fenêtre.

duration: (frame_count * offset) + 'px',

La durée aidera à contrôler la durée du mouvement, en fonction du nombre d'images et du décalage. Comme vous vous en souviendrez, nous avions un nombre d'images de 9 et un décalage de 100. Ces valeurs, multipliées ensemble, sont égales à 900 pixels; la valeur totale des points de décalage de déclenchement.

pour (var i = 1, l = frame_count; i <= l; i++)  new ScrollMagic.Scene( triggerElement: '.js-scrollpin', offset: i * offset ) .setClassToggle(frame, 'frame' + i) .addTo(controller); 

Comme il y a 9 cadres, nous parcourons ce nombre d'itérations tout en définissant le même panneau pour un triggerElement. À chaque itération de la boucle, nous multiplions la valeur de cette boucle par la valeur du décalage (1 * 100, 2 * 100, 3 * 100…). Nous définissons également une classe à travers laquelle basculer; .cadre1, .frame2, .frame3 etc. Chacune des classes représente la position de l’arrière-plan de chaque image dans l’image-objet..

Et nous avons fini!

Conclusion

Vous vous demandez peut-être quelle est la taille totale du fichier de l'image-objet, alors laissez-moi vous donner quelques chiffres. Non compressé, l’image pesait 1,5 Mo, mais une fois compressée, elle permettait un format plus acceptable de 319 Ko. Cela n'inclut pas les 6Ko compressés pour charger la bibliothèque ScrollMagic. 

J'espère que cette technique vous inspirera pour votre prochain projet et n'hésitez pas, comme toujours, à poser des questions dans les commentaires ci-dessous. Bonne codage!