L'une des choses qui nous a laissés perplexes lors de la construction de notre nouveau site web, ce sont les vagues morcelées que l'on peut voir à différents endroits sur les pages. Nous avions beaucoup d'idées sur la façon de les mettre en œuvre sans trop d'efforts. Cependant, la plupart des solutions étaient lentes et nous avons dû construire à partir de zéro quelque chose qui serait plus rapide que les bibliothèques existantes.
Propositions de solutions
Nous avons commencé avec un simple objet SVG qui a été animé avec différentes bibliothèques. Comme nous voulions avoir 3 objets sur une page, le résultat n'était pas très satisfaisant. Toutes les animations étaient lentes - tous les chemins d'un seul objet SVG devaient être mis à jour dans des périodes de temps très courtes, ce qui rendait la page entière aussi lente qu'un escargot. Nous avons dû rejeter la solution du SVG pur inséré dans un document. Il nous restait donc deux autres solutions.
Les vidéo
était la deuxième option. Nous avons commencé par deux problèmes :
- un arrière-plan transparent, qui ne peut être appliqué aux formats vidéo les plus courants tels que .mp4 ou .webm,
- la réactivité, ce qui constituait un réel problème car les vidéos ne sont pas extensibles en tant que telles.
Nous avons décidé de garder cette solution en réserve - "si nous ne trouvons rien d'autre, nous choisirons celle-ci".
La dernière option consistait à utiliser toile
avec WebGL
le rendu. C'était une option très inhabituelle car nous avons dû concevoir tous les mécanismes de rendu nous-mêmes. C'est parce que les ondes morphiques que nous avions étaient personnalisées - cela nous a obligés à concevoir une solution personnalisée. Et c'est l'option que nous voulions suivre et sur laquelle nous voulions vraiment nous concentrer.
Architecture de la solution
Reprenons depuis le début. Quel était le matériel que nous devions utiliser pour construire ces vagues ? L'idée était que toutes les vagues étaient un fichier SVG de taille 1×1 et des chemins spécifiques positionnés autour de cette zone. L'animation de ce SVG était construite par des formes d'états de ce fichier. Ainsi, toutes les animations étaient représentées comme un ensemble de fichiers contenant les étapes du déplacement d'une forme.
Examinez de plus près ce que sont les états - tous les chemins ne sont qu'une sorte de tableau avec des valeurs spécifiques positionnées dans un ordre spécifique. La modification de ces valeurs dans des positions spécifiques de ce tableau modifie la forme dans ses parties spécifiques. Nous pouvons simplifier cela avec l'exemple suivant :
état 1 : [1, 50, 25, 40, 100]
état 2 : [0, 75, -20, 5, 120]
état 3 : [5, 0, -100, 80, 90]
Ainsi, nous pouvons supposer que la forme que nous voulons rendre consiste en un tableau de 5 éléments qui changent avec l'assouplissement linéaire dans des périodes de temps spécifiques. Lorsque l'animation termine la dernière étape, elle recommence à la première pour nous donner l'impression d'une animation infinie.
Mais... attendez - qu'est-ce que le tableau présenté ci-dessus ? Comme je l'ai mentionné, il s'agit d'un chemin qui est responsable de l'affichage d'une forme spécifique. Toute la magie est incluse dans le tableau d
du chemin SVG. Cette propriété contient un ensemble de "commandes" pour dessiner une forme et chaque commande a un certain nombre d'arguments. Le tableau mentionné ci-dessus contient toutes les valeurs (arguments) attachées à ces commandes.
La seule différence entre ces "fichiers d'état" était les valeurs des commandes spécifiques, car l'ordre des commandes était le même. Ainsi, toute la magie consistait à obtenir toutes les valeurs et à les animer.
L'assistant appelé Physique
Dans le paragraphe ci-dessus, j'ai mentionné que la seule magie dans l'animation d'un objet est la création de transitions entre toutes les étapes d'une forme. La question est de savoir comment faire cela avec le canevas ?
La fonction que tous ceux qui ont travaillé avec toile
doit savoir est requestAnimationFrame. Si vous voyez cela pour la première fois, je pense sincèrement que vous devriez commencer par lire ceci. Ce qui nous intéresse dans cette fonction, c'est l'argument - DOMHighResTimeStamp
. Cela semble vraiment terrifiant, mais en pratique, ce n'est pas si difficile à comprendre. Nous pouvons dire qu'il s'agit d'un horodatage du temps écoulé depuis le premier rendu.
D'accord, mais que pouvons-nous faire avec cela ? Comme le requestAnimationFrame
doit être appelée de manière récursive, nous pouvons accéder à un delta temporel entre ses appels. Et c'est parti pour la science ! ⚛️ (ok, ce n'est peut-être pas de la science-fiction... pour l'instant)
La physique nous enseigne que le delta d'une distance est égal au delta du temps multiplié par la vitesse. Dans notre cas, la vitesse est constante car nous voulons atteindre le point d'arrivée dans un laps de temps déterminé. Voyons donc comment nous pouvons le représenter avec les états ci-dessus :
Disons que nous voulons passer d'un état à l'autre en mille millisecondes, les valeurs de vitesse seront donc les suivantes :
delta : [ -1, 25, -45, -35, 20]
vitesse : [-1/1000, 25/1000, -45/1000, -35/1000, 20/1000]
La vitesse ci-dessus nous dit : pour chaque milliseconde, augmentons la valeur de -1/1000. Et c'est ici que nous pouvons revenir à notre requestAnimationFrame
et le delta temporel. La valeur d'une position spécifique que nous voulons augmenter est le delta de temps multiplié par la vitesse de sa position. Une autre chose à faire sans problème est de limiter la valeur de manière à ne pas dépasser l'état dans lequel elle se trouve.
Lorsque la transition se termine, nous en appelons une autre et ainsi de suite. Et cela ne semble pas si difficile à mettre en œuvre, mais l'une des principales règles de développement de logiciels est de ne pas perdre de temps sur des choses qui sont déjà mises en œuvre. Nous avons donc choisi un petite bibliothèque qui nous permet de créer ces transitions sans effort.
C'est ainsi que nous avons créé une vague animée qui ressemble à une créature vivante.
Quelques mots sur le clonage des formes
Comme vous pouvez le constater, les vagues de la marque The Codest ne sont pas une seule figure animée. Elles se composent de plusieurs figures ayant la même forme mais une taille et une position différentes. Dans cette étape, nous allons voir rapidement comment les dupliquer de cette manière.
Ainsi, le contexte de la toile nous permet de zone de dessin à l'échelle (sous le capot, on peut dire qu'il multiplie toutes les dimensions transmises aux méthodes de dessin par "k", où "k" est un facteur d'échelle, fixé par défaut à "1"), faire traduire le canevasC'est comme changer le point d'ancrage d'une zone de dessin. Ces méthodes permettent également de passer d'un état à l'autre : sauver et restaurer.
Ces méthodes nous permettent de sauvegarder l'état "zéro modification" et de rendre ensuite un nombre spécifique de vagues dans la boucle avec un canevas correctement mis à l'échelle et translaté. Juste après cela, nous pouvons revenir à l'état sauvegardé. C'est tout pour le clonage de figures. Beaucoup plus facile que de cloner des moutons, n'est-ce pas ?
Cerise sur le gâteau
J'ai mentionné que nous avons rejeté l'une des solutions potentielles pour des raisons de performance. L'option avec le canevas est assez rapide, mais personne n'a dit qu'elle ne pouvait pas être optimisée davantage. Commençons par le fait que nous ne nous soucions pas vraiment de la transition des formes lorsqu'elles se trouvent en dehors de la fenêtre du navigateur.
Il existe une autre API de navigateur que les programmeurs ont adorée - IntersectionObserver. Il nous permet de suivre des éléments spécifiques de la page et de gérer les événements qui sont invoqués lorsque ces éléments apparaissent ou disparaissent de la fenêtre de visualisation. Pour l'instant, nous avons une situation assez facile - créons l'état de la visibilité, modifions-le grâce aux gestionnaires d'événements IntersectionObserver et activons/désactivons simplement le système de rendu pour des formes spécifiques. Et ... boom, les performances se sont considérablement améliorées ! Nous ne rendons que ce qui est visible dans la fenêtre.
Résumé
Le choix d'une méthode de mise en œuvre est souvent difficile, surtout lorsque les options disponibles semblent présenter des avantages et des inconvénients similaires. La clé pour faire un choix correct est d'analyser chacune d'entre elles et d'exclure celles que nous considérons comme moins avantageuses. Tout n'est pas clair : une solution peut nécessiter plus de temps que les autres, mais elle peut être optimisée plus facilement ou plus personnalisable.
Bien que de nouvelles bibliothèques JS apparaissent presque chaque minute, il y a des choses qu'elles ne peuvent pas résoudre. C'est pourquoi tous les ingénieurs front-end (et pas seulement eux) doivent connaître les API des navigateurs, se tenir au courant des actualités techniques et parfois simplement se demander à quoi ressemblerait mon implémentation de cette bibliothèque si je devais faire ceci ou cela. Avec plus de connaissances sur les navigateurs, nous pouvons construire des choses vraiment fantaisistes, prendre de bonnes décisions sur les outils que nous utilisons, et devenir plus confiants dans notre travail. code.
En savoir plus :
– Ruby 3.0. Ruby et les méthodes moins connues de contrôle de la vie privée
– Shut up and take your money #1 : Coûts cachés et agilité réelle dans le processus de développement de produits
– Défis CTO - mise à l'échelle et croissance des produits logiciels