Créer un effet Chillwave en SVG

Varun Vachhar recrée en SVG un effet chillwave initialement créé en sprite : enchaînement de courbes de Bézier, chemins en miroir, animation de la vague et touche finale, un beau boulot!

Par

See the Pen This Also Chillwave by Varun Vachhar (@winkerVSbecks) on CodePen.

Il y a quelques jours je suis tombé sur le site du studio de création This Also, qui vient d’être lancé. Il donne de nombreux exemples de leur incroyable travail et il contient cette drôle de petite animation :

J’adore ça ! J’ai tout de suite fait un clic-droit pour inspecter l’élément, m’attendant à trouver un SVG avec une animation SMIL, mais à ma grande surprise j’ai trouvé une animation sprite en 24 images. Dans ce petit tutoriel, nous allons recréer cet effet Chillwave avec SVG.

Dessiner une vague

La première étape était assez évidente... dessiner une vague en utilisant l’élément path de SVG. Dans Sketch ou Illustrator, on la créerait avec l’outil crayon ou équivalent. C’est juste une courbe de Bézier avec deux points, chacun avec ses poignées (point de contrôle). La vague est simplement un ensemble de points sur ce chemin (path), alternant avec une image en miroir.

Pour créer ce chemin en SVG, nous utilisons la commande c (en minuscule) de la courbe de Bézier, qui signifie coordonnées relatives. Nous répétons ce motif plusieurs fois et plutôt que d’essayer de trouver les coordonnées de chaque point nous pouvons utiliser les coordonnées relatives pour nous faciliter la vie.

<!--  
  dx1 dy1: point de contrôle pour le départ
  dx2 dy2: point de contrôle pour l’arrivée
  dx dy: point final
-->
c dx1 dy1, dx2 dy2, dx dy  

Les blocs constitutifs

Pour cet exemple, nous supposerons que la largeur de l’élément SVG est w, sa hauteur est h et l’amplitude de la vague est 0.25 * h. Le chemin peut être construit ainsi :

  • On part du point de départ qui sera le milieu du SVG (0.5 * h) + la moitié de l’amplitude (0.125 * h) :
  [
    'M', 0, 0.625 * h
  ]
  • Puis nous commençons la courbe c et ajoutons le premier point de contrôle en utilisant les coordonnées relatives, donc la coordonnée y est simplement 0. La coordonnée x est égale à 0,512286623256592433 (m) fois l’amplitude. La valeur de m est choisie de façon à créer approximativement une courbe sinusoïdale.
  [
    'M', 0, 0.625 * h,
    'c', 0.25 * h * m, 0
  ]
  • Nous ajoutons ensuite le deuxième point de contrôle. Pour la coordonnée y nous devons remonter d’une amplitude — et remonter se traduit par une valeur négative en SVG, donc -0.25 * h. Pour calculer la coordonnée x, nous allons jusqu’à la fin 0.25 * h et revenons de 0.25 * h *m.
  [
    'M', 0, 0.625 * h,
    'c', 0.25 * h * m, 0,
    0.25 * h * (1 - m), -0.25 * h,
  ]
  • enfin, nous ajoutons le point final et créons la définition du chemin en utilisant la technique décrite dans le tutoriel de création d'icônes avec React.
  var pathData = [
    'M', 0, 0.625 * h,
    'c', 0.25 * h * m, 0,
    0.25 * h * (1 - m), -0.25 * h,
    0.25 * h, -0.25 * h
  ].join(' ');

See the Pen SVG wave section by Varun Vachhar (@winkerVSbecks) on CodePen.

La section de chemin suivante est simplement en miroir de la précédente, grâce à la commande s de SVG.

Vous pouvez enchaîner plusieurs courbes de Bézier pour créer des formes. Souvent, dans ce cas, le point de contrôle d’un côté d'un point sera un reflet du point de contrôle utilisé de l’autre côté (pour avoir une pente constante). Dans ce cas, vous pouvez utiliser une version raccourcie de la courbe de Bézier via la commande S (ou s).
(Extrait du Tutoriel MDN sur les chemins)

Nous pouvons donc utiliser la commande s et étendre notre définition de chemin. N’oubliez pas que le premier point de contrôle est automagiquement inséré pour nous, donc il nous suffit de spécifier le second point de contrôle et le point final de la deuxième section.

var pathData = [  
  'M', 0, 0.625 * h,
  'c', 0.25 * h * m, 0,
  0.25 * h * (1 - m), -0.25 * h,
  0.25 * h, -0.25 * h,
  's', 0.25 * h * (1 - m), 0.25 * h,
  0.25 * h, 0.25 * h
].join(' ');

See the Pen SVG wave – mirror section by Varun Vachhar (@winkerVSbecks) on CodePen.

...et répéter

Nous pouvons maintenant utiliser la technique de la commande s pour étendre cette vague en alternant les hauts et les bas.

// en bas
's', 0.25 * h * (1 - m), 0.25 * h,  
0.25 * h, 0.25 * h  
// et vers le haut
's', 0.25 * h * (1 - m), -0.25 * h,  
0.25 * h, -0.25 * h  

See the Pen SVG wave – repeat by Varun Vachhar (@winkerVSbecks) on CodePen.

Animer la vague

Pour animer la vague, nous déplaçons le chemin de gauche à droite en utilisant les transformations CSS. La distance est égale à la largeur de l’élément SVG : transform: translate3d(-90px, 0, 0) et nous devons nous assurer que la vague est suffisamment longue, faute de quoi l’animation ne fonctionnera pas vraiment.

See the Pen Chillwave – animate 1 by Varun Vachhar (@winkerVSbecks) on CodePen.

La touche finale

Nous pourrions nous arrêter là, mais vous remarquerez que dans le GIF de départ la vague est arrondie au bout. Il est facile d’ajouter cet effet à une vague statique, il suffit d’utiliser stroke-linecap="round" et c’est fait. Mais lorsqu’on anime une vague, son chemin s’étend en dehors du canevas SVG visible. Les bouts arrondis sont donc quelque part en dehors de l’écran.

Pour parvenir à l’effet recherché, nous devons nous appuyer sur stroke-dasharray. Celui-ci accepte des valeurs correspondant à la longueur des tirets (dash) et des écarts (gap) entre les tirets.

#wave { stroke-dasharray: 0 16 101 16; }
  • Nous commençons avec 0 puisque nous voulons un gap pour commencer, mais par défaut dasharray applique la première valeur à un trait.
  • 16 est la longueur du premier gap
  • 101 est la longueur du tiret
  • et finalement, 16 est la longueur du dernier gap.

La longueur totale du chemin est d’environ 120px. En utilisant cette longueur comme point de départ, j’ai choisi les nombres en procédant à tâtons.

See the Pen SVG wave – add the rounded ends by Varun Vachhar (@winkerVSbecks) on CodePen.

À partir d’ici, si nous réintroduisons l’animation, vous remarquerez qu’on perd l’illusion optique d'une vague qui oscille tout en restant en place. Le chemin se déplace maintenant de gauche à droite. Pour contrer ce mouvement, nous devons animer le tiret (celui du dasharray ci-dessus) de droite à gauche à la même vitesse.

On a : gap + tiret + gap = 16 + 101 + 16 = 133. Et nous pouvons déplacer le tiret avec stroke-dashoffset exactement du même nombre — c'est la technique maintenant célèbre de l'animation d'une ligne SVG. Notez bien la différence. Celle de gauche n’a pas le dashoffset, contrairement à celle de droite :

See the Pen Chillwave – animate 1 by Varun Vachhar (@winkerVSbecks) on CodePen.

Mise à jour

J’ai dû faire un petit ajout pour Safari. Pour une raison inconnue, le viewport SVG est plus large que dans les autres navigateurs.

<svg xmlns="http://www.w3.org/2000/svg"  
     width="80px" height="60px"
     viewBox="5 0 80 60">

Intéressé par SVG ? Retrouvez une liste des meilleurs articles et ressources du web.

Tous les articles sur SVG parus dans la Cascade.

Tous les articles sur les animations parus dans la Cascade.

Tous les articles sur les transformations parus dans la Cascade.


original paru le dans le blog de Varun Vachhar.

Sur l’auteur : est un créatif passionné de technologie, basé à Toronto. Il travaille actuellement pour rangle.io. Il aime tout particulièrement JavaScript, CSS, WebGL, Canvas et les triangles. On peut le suivre sur Twitter, Github, CodePen et Dribbble.

Traduit avec l'aimable autorisation de l'auteur.
Copyright Varun Vachhar © 2015.