total

Contexte

Le projet est une infographie interactive représentant le parcours du pétrole à travers cinq étapes : l'extraction, le transport jusqu'à la raffinerie, le raffinage, l'acheminement au dépôt et l'amélioration et enfin l'acheminement à la station-service. Toutes les animations sont réalisées entièrement en CSS et déclenchées à l'aide du javascript, soit lorsque l'élément devient visible au scroll ou lorsqu'un autre élément a été activé par le scroll.

Il y a eu plusieurs problématiques dans ce projet:

  • Comment rendre l'animation entièrement responsive ?
  • Comment dessiner les tuyaux de pétroles qui se remplissent lors de l'animation ?
  • Comment réaliser l'animation des différentes cuves de pétrole et celle de la voiture qui quitte la station service?

Informations générales

Pour cette animation interactive, le background a été utilisé comme un masque. En effet, afin de ne pas voir les démarcations des animations pour les cuves et les tuyaux, ceux-ci sont placés en z-index 1 et le background est placé en z-index 2, tous les autres éléments ayant un z-index supérieur. L'image de background a donc été creusée par la graphistes aux endroits nécessaires au préalable afin de permettre cela.

Pour gérer les différentes étapes de l'infographie et le déclenchement du menu correspondant, le plugin ScrollIt a été utilisé. Il permet de détecter la zone présente à l'écran et d'activer le lien dans le menu qui référence cette zone. Pour le mettre en place, il suffit de donner à chaque lien du menu un attribut data-scroll-nav et d'attribuer à la div correspondante un attribut data-scroll-index avec le même numéro.

Comme dit précédemment, chaque animation CSS est déclenchée en javascript, plus précisément en appliquant la classe .is-active à l'élément que l'on souhaite animer.

Pour gérer la compatibilité entre les navigateurs et plus précisément l'ajout des préfixes aux propriétés CSS, la tâche grunt autoprefixer a été utilisée.

Rendre l'infographie entièrement responsive

Tous les éléments à animer sont placés sur le background en position absolute. Les positions top et left sont en pourcentage et non en pixels afin que le positionnement s'adapte bien à la taille du conteneur lors de la réduction de la taille de la fenêtre. Cela n'est cependant pas suffisant : en effet, les positions sont bien recalculées mais les éléments gardent leur taille originelle et se chevauchent donc parfois où ne sont plus exactement à leur place. Il a donc également fallut donner à chacun de ces éléments une largeur en pourcentage pour que celle-ci s'adapte également au conteneur et que toute l'animation reste bien en place sur tous les devices.

Les tuyaux de pétrole

Pour réaliser les tuyaux de pétrole qui se remplissent, j'ai tout de suite pensé aux paths SVG, qui convenaient parfaitement à ce cas d'utilisation. Les paths ont été exportés depuis Illustrator par la graphiste et intégrés ensuite en svg inline directement dans le code HTML afin de les contrôler à l'aide du CSS. Ces chemins ne doivent pas avoir de propriété fill mais uniquement avoir la propriété stroke de renseignée afin d'avoir un contour, en renseignant une couleur et une taille. Pour réaliser l'animation des tuyaux, j'ai eu recours à deux propriétés CSS : stroke-dasharray et stroke-dashoffset:

  • stroke-dasharray défini la longueur des pointillés du chemin. Dans notre cas nous n'en voulons qu'un qui recouvre tout le chemin et il faut donc donner comme valeur à cette propriété la longueur total du chemin. Cette valeur est facilement trouvable en javascript à l'aide la fonction path.getTotalLength().

  • stroke-dashoffset permet de faire bouger les pointillés du chemin. Dans notre cas, nous voulons que notre unique pointillé soit entièrement caché. Pour cela, il faut donner comme valeur à cette propriété la longueur totale du chemin.

Nos chemins sont maintenant invisibles et il faut les dérouler pour créer l'impression d'un tuyau qui se remplit. Pour cela, il suffit d'utiliser la propriété @keyframes afin de ramener la propriété stroke-dashoffset à 0.

@keyframes paths {
    to {
        stroke-dashoffset: 0;
    }
}

.path-wrapper{
    position:absolute;
    left:0%;
    top:-50%;
    width:100%;
    padding-bottom:89%;

    svg{
        @include position(absolute,0px 0 0 0px);
        display:block;

        .path{
            stroke-dasharray: 1535;
            stroke-dashoffset: 1535;

             &.is-active{
                animation:paths 3s linear forwards;
            }
        }
    }
}

Cette technique utilisant uniquement du CSS n'est cependant compatible avec aucune des versions d'internet explorer. Pour ces navigateurs, j'ai dû re-créer les chemins et les animer en javascript, le tout à l'aide de la librairie Snap.svg.

Enfin, il fallait rendre responsive ces chemins. Pour cela, j'ai utilisé la technique du wrapper fluide ayant un padding-bottom en pourcentage qui correspond à un ratio et une hauteur égale à 0. Cette technique est normalement utilisée pour conserver l'aspect des vidéos et éviter les bandes noires sur les côtés par exemple.

L'animation des cuves

Tout au long de l'animation, il y a différentes cuves qui se remplissent. L'animation des cuves est toujours la même, seule l'image de "remplissage" change ou le délai de l'animation. C'est pour cela que j'ai créé un placeholder Sass pour cette animation, afin d'éviter au maximum les doublons dans le code.

Du point de vue de l'animation en elle-même, c'est assez basique : utilisation de scaleY() et afin que les cuves se remplissent bien du bas vers le haut et non pas du milieu vers le haut et le bas, j'ai changé la propriété transform-origin en 0 100% 0.

%cuve-animation{
    opacity:0; //bug on ie11/ie10 otherwise
    transform : scaleY(0);
    transform-origin: 0 100% 0 ;
    transition: transform 1.5s ease-out, opacity 0s linear ;

    &.is-active{
        opacity:1;
        transform: scaleY(1);
    }
}

.cuve{
    @extend %cuve-animation;
    position:absolute;
    bottom:-0.9%;
    width:18%;

    &--1{
        left:17.8%;
        transition-delay:7.9s;
    }

    &--2{
        left:36.9%;
        transition-delay:9.2s;
    }

    &--3{
        right:25.8%;
        transition-delay:7s;
    }
}

Il y a cependant un bug sous IE10 et IE11 : les cuves apparaissent une première fois dès que la classe .is-active leur est appliquée alors qu'elles ne devraient apparaitre et "grandir" uniquement au bout du délais appliqué par la propriété transition-delay. La solution est de leur mettre par défaut une opacité à 0 et de la passer à 1 en même temps que l'on applique la transformation avec scaleY() pour le remplissage des cuves : en somme, mettre le même transition-delay à opacity et à transform.

total

L'animation de la voiture qui sort de la station-service

Cette animation a été la plus compliquée à réaliser car elle a besoin de beaucoup de clés pour fonctionner, la voiture réalisant des virages avant de rouler tout droit. Pour réaliser les virages, j'ai utilisé la propriété scaleX(1) et scaleX(-1). Il fallait cependant qu'il n'y ait pas de transitions entre les directions de la voiture mais qu'il y en ait entre les positions. Pour cela, avant chaque clé qui définit le nouveau positionnement et la nouvelle direction de la voiture, il faut rajouter une clé avec la direction antérieure juste avant pour que celle-ci ne s'interpole pas depuis la première clé définie bien avant. C'est le même fonctionnement que les clés sous After Effect ou 3DSMax.

@keyframes green-car{
    0%{
        top:30%;
        left:43.5%;
    }

    19%{
        top:33.5%;
        left:38.5%;
        transform:scaleX(1);
        z-index:3;
    }

    20%{
        transform:scaleX(-1);
        z-index:4;
    }

    44%{
        top:42.5%;
        left:63.5%;
        transform:scaleX(-1);
    }

    45%{
        transform:scaleX(1);
    }

    100%{
        top:78%;
        left:-11%;  
    }  
}

.car--green{
    @include position(absolute, 30% 0 0 43.5%);
    position:absolute;
    width:10%;
    z-index:3;

    &.is-active{
        animation: green-car 6s forwards 7s linear;
    }    
}