Les animations SVG me ramènent dans les dessins animés de Hanna-Barbera que j’ai regardés comme un enfant. Émissions comme Races farfelues, Les périls de Penelope Pitstopet bien sûr, Yogi ours. Ils m’ont inspiré à recréer avec amour un classique Titres toon Utilisation des animations CSS, SVG et SMIL.
Mais faire charger rapidement les animations et fonctionner en douceur nécessite plus que la nostalgie. Il faut une conception propre, un code maigre et un processus qui rend les SVG complexes plus faciles à animer. Voici comment je fais.
Que ce soit pour des projets personnels ou des travaux commerciaux, la préparation des SVG garantit bien qu’ils sont accessibles. Les optimiser garantit qu’ils se chargent rapidement, en particulier sur le mobile, et réfléchir soigneusement à la façon dont ils sont structurés facilitent leur maintien. J’ai développé un processus qui équilibre les visuels avec accessibilité et performances et rend les SVG complexes plus faciles à travailler.
Donc, pour expliquer mon processus, j’ai choisi un épisode de Le salon Yogi Bear Appelé «Bewitched Bear», diffusé pour la première fois en janvier 1960. Dans cette histoire, Yogi vole un balai de sorcière pour l’aider à saisir des paniers «pic-a-nic».
« Hé, hé, hé! »
Commencez à nettoyer et à la conception avec l’optimisation à l’esprit
Garder les choses simples est la clé pour rendre les SVG optimisés et prêts à animer. Des outils comme Adobe Illustrator convertissent les images bitmap en vecteurs, mais la sortie contient souvent trop de groupes, de couches et de masques étrangers. Au lieu de cela, je commence à nettoyer dans Sketch, je travaille à partir d’une image de référence et j’utilise l’outil stylo pour créer des chemins.
Conseil: Concepteur d’affinité (Royaume-Uni) et Esquisser (Pays-Bas) sont des alternatives à Adobe Illustrator et Figma. Les deux sont indépendants et basés en Europe. Sketch a été mon application de conception par défaut depuis qu’Adobe a tué des feux d’artifice.
Commençant par les contours
Pour ces illustrations de titres Toon, j’utilise d’abord l’outil stylo pour dessiner des contours noirs avec le moins de points d’ancrage possible. Plus une forme a une forme, plus un fichier est gros, donc simplifier les chemins et réduire le nombre de points rend un SVG beaucoup plus petit, souvent sans différence visuelle discernable.
Gardant à l’esprit que certaines parties de cette illustration de yogi seront finalement animées, je garde des contours pour le corps, la tête, le col et le lien de cet ours qui ont puins pour que je puisse les déplacer indépendamment. La tête pourrait hocher la tête, la cravate pourrait se battre et, comme dans ces caricatures classiques, le col de Yogi cachera les joints entre eux.
Dessin des formes d’arrière-plan simples
Avec les contours en place, j’utilise à nouveau l’outil stylo pour dessiner de nouvelles formes, qui remplissent les zones de couleur. Ces couleurs se trouvent derrière les contours, ils n’ont donc pas besoin de les faire correspondre exactement. Plus les points d’ancrage moins, plus la taille du fichier est inférieur.
Malheureusement, ni Affinity Designer ni Sketch n’ont d’outils qui peuvent simplifier les chemins, mais si vous l’avez, l’utilisation d’Adobe Illustrator peut raser quelques kilobytes supplémentaires de ces formes d’arrière-plan.
Optimisation du code
Ce ne sont pas seulement les métadonnées qui rendent SVG plus bulk. La façon dont vous exportez de votre application de conception affecte également la taille du fichier.
L’exportation uniquement de ces formes d’arrière-plan simples d’Adobe Illustrator comprend des groupes inutiles, des masques et des données de chemin gonflées par défaut. Le code de Sketch est à peine meilleur, et il y a beaucoup de place à l’amélioration, même dans son code de compresseur SVGO. Je compte sur Jake Archibald Svgomgqui utilise SVGO V3 et fournit systématiquement les SVG les mieux optimisés.
Superposer des éléments SVG
Mon processus de préparation des SVG pour l’animation va bien au-delà de dessiner des vecteurs et d’optimiser les chemins – il comprend également la façon dont je Structurez le code lui-même. Lorsque chaque élément visuel est entassé en un seul fichier SVG, même le code optimisé peut être un cauchemar à naviguer. La localisation d’un chemin ou d’un groupe spécifique ressemble souvent à la recherche d’une aiguille dans une botte de foin.
C’est pourquoi je développe mes SVG en couches, exportant et optimisant un ensemble d’éléments à la fois – toujours dans l’ordre, ils apparaîtront dans le fichier final. Cela me permet de construire progressivement le maître SVG en le collant dans chaque section nettoyée. Par exemple, je commence par des arrière-plans comme ce graphique de dégradé et de titre.
Au lieu de faire face à un mur de code SVG, je peux maintenant identifier facilement le chemin du gradient de fond et son associé linearGradient
et voir le groupe contenant le graphique de titre. Je profite de cette occasion pour ajouter un commentaire au code, ce qui facilitera l’édition et l’ajouter des animations à l’avenir:
<svg ...>
<defs>
<!-- ... -->
</defs>
<path fill="url(#grad)" d="…"/>
<!-- TITLE GRAPHIC -->
<g>
<path … />
<!-- ... -->
</g>
</svg>
Ensuite, j’ajoute le sentier flou du balai aéroporté de Yogi. Cela comprend la définition d’un filtre de flou gaussien et en plaçant son chemin entre l’arrière-plan et les couches de titre:
<svg ...>
<defs>
<linearGradient id="grad" …>…</linearGradient>
<filter id="trail" …>…</filter>
</defs>
<!-- GRADIENT -->
<!-- TRAIL -->
<path filter="url(#trail)" …/>
<!-- TITLE GRAPHIC -->
</svg>
Viens ensuite les étoiles magiques, ajoutées de la même manière séquentielle:
<svg ...>
<!-- GRADIENT -->
<!-- TRAIL -->
<!-- STARS -->
<!-- TITLE GRAPHIC -->
</svg>
Pour garder tout organisé et prêt pour l’animation, je crée un groupe vide qui tiendra toutes les parties de Yogi:
<g id="yogi">...</g>
Ensuite, je construis des yogi à partir de zéro – en commençant par des accessoires de fond, comme son balai:
<g id="broom">...</g>
Suivi d’éléments groupés pour son corps, sa tête, son col et sa cravate:
<g id="yogi">
<g id="broom">…</g>
<g id="body">…</g>
<g id="head">…</g>
<g id="collar">…</g>
<g id="tie">…</g>
</g>
Étant donné que j’exporte chaque couche à partir de l’art de la même taille, je n’ai pas à m’inquiéter des problèmes d’alignement ou de positionnement plus tard – ils seront tous en place automatiquement en place. Je garde mon code faire le ménage, lisibleet ordonné logiquement en superposant des éléments de cette façon. Il rend également l’animation plus fluide, car chaque composant est plus facile à identifier.
Réutiliser des éléments avec <use>
Lorsque les formes en double sont réutilisées à plusieurs reprises, les fichiers SVG peuvent devenir volumineux rapidement. Ma recréation de la carte de titre «Bewitched Bear» contient 80 étoiles en trois tailles. La combinaison de toutes ces formes en un seul chemin optimisé entraînerait la taille du fichier à 3 Ko. Mais je veux animer des stars individuelles, ce qui doublerait presque à 5KB:
<g id="stars">
<path class="star-small" fill="#eae3da" d="..."/>
<path class="star-medium" fill="#eae3da" d="..."/>
<path class="star-large" fill="#eae3da" d="..."/>
<!-- ... -->
</g>
Déplacer les étoiles ‘ fill
Les valeurs d’attribut à leur groupe parent réduisent un peu le poids global:
<g id="stars" fill="#eae3da">
<path class="star-small" d="…"/>
<path class="star-medium" d="…"/>
<path class="star-large" d="…"/>
<!-- ... -->
</g>
Mais une option plus efficace et gérable est de définir chaque taille d’étoile comme un modèle réutilisable:
<defs>
<path id="star-large" fill="#eae3da" fill-rule="evenodd" d="…"/>
<path id="star-medium" fill="#eae3da" fill-rule="evenodd" d="…"/>
<path id="star-small" fill="#eae3da" fill-rule="evenodd" d="…"/>
</defs>
Avec cette configuration, la modification de la conception d’une étoile signifie uniquement la mise à jour de son modèle une fois, et chaque instance se met à jour automatiquement. Ensuite, je fais référence à chacun en utilisant <use>
Et positionnez-les avec x
et y
Attributs:
<g id="stars">
<!-- Large stars -->
<use href="#star-large" x="1575" y="495"/>
<!-- ... -->
<!-- Medium stars -->
<use href="#star-medium" x="1453" y="696"/>
<!-- ... -->
<!-- Small stars -->
<use href="#star-small" x="1287" y="741"/>
<!-- ... -->
</g>
Cette approche rend le SVG plus facile à gérer, plus léger à charger et plus rapide à itérer, en particulier lorsque vous travaillez avec des dizaines d’éléments répétitifs. Mieux encore, il maintient le balisage propre sans compromettre la flexibilité ou les performances.
Ajout d’animations
Les étoiles traînant derrière le balai volé de Yogi apportent tellement de personnalité à l’animation. Je voulais qu’ils scintillent dans un motif apparemment aléatoire sur le fond bleu foncé, alors j’ai commencé par définir une animation de l’image clé qui fait le vélo différent opacity
Niveaux:
@keyframes sparkle {
0%, 100% { opacity: .1; }
50% { opacity: 1; }
}
Ensuite, j’ai appliqué cette animation en boucle à chaque use
Élément à l’intérieur de mon groupe d’étoiles:
#stars use {
animation: sparkle 10s ease-in-out infinite;
}
Le secret pour créer un scintillement convaincant réside dans variation. J’ai des retards et des durées d’animation décalées à travers les étoiles en utilisant nth-child
Sélecteurs, en commençant par les effets d’éclat les plus rapides et les plus fréquents:
/* Fast, frequent */
#stars use:nth-child(n + 1):nth-child(-n + 10) {
animation-delay: .1s;
animation-duration: 2s;
}
De là, j’ai superposé des horaires supplémentaires pour mélanger les choses. Certaines étoiles scintillent lentement et de façon spectaculaire, d’autres plus au hasard, avec une variété de rythmes et de pauses:
/* Medium */
#stars use:nth-child(n + 11):nth-child(-n + 20) { ... }
/* Slow, dramatic */
#stars use:nth-child(n + 21):nth-child(-n + 30) { ... }
/* Random */
#stars use:nth-child(3n + 2) { ... }
/* Alternating */
#stars use:nth-child(4n + 1) { ... }
/* Scattered */
#stars use:nth-child(n + 31) { ... }
En structurant soigneusement le SVG et en réutilisant des éléments, je peux construire des animations d’apparence complexe sans code gonflé, ce qui fait même un effet simple comme le changement opacity
éclat.
Ensuite, pour plus de réalisme, je fais vaciller la tête de Yogi:
@keyframes headWobble {
0% { transform: rotate(-0.8deg) translateY(-0.5px); }
100% { transform: rotate(0.9deg) translateY(0.3px); }
}
#head {
animation: headWobble 0.8s cubic-bezier(0.5, 0.15, 0.5, 0.85) infinite alternate;
}
Sa cravate vagues:
@keyframes tieWave {
0%, 100% { transform: rotateZ(-4deg) rotateY(15deg) scaleX(0.96); }
33% { transform: rotateZ(5deg) rotateY(-10deg) scaleX(1.05); }
66% { transform: rotateZ(-2deg) rotateY(5deg) scaleX(0.98); }
}
#tie {
transform-style: preserve-3d;
animation: tieWave 10s cubic-bezier(0.68, -0.55, 0.27, 1.55) infinite;
}
Ses balançoires à balai:
@keyframes broomSwing {
0%, 20% { transform: rotate(-5deg); }
30% { transform: rotate(-4deg); }
50%, 70% { transform: rotate(5deg); }
80% { transform: rotate(4deg); }
100% { transform: rotate(-5deg); }
}
#broom {
animation: broomSwing 4s cubic-bezier(0.5, 0.05, 0.5, 0.95) infinite;
}
Et, enfin, Yogi lui-même tourne doucement alors qu’il vole sur son balai magique:
@keyframes yogiWobble {
0% { transform: rotate(-2.8deg) translateY(-0.8px) scale(0.998); }
30% { transform: rotate(1.5deg) translateY(0.3px); }
100% { transform: rotate(3.2deg) translateY(1.2px) scale(1.002); }
}
#yogi {
animation: yogiWobble 3.5s cubic-bezier(.37, .14, .3, .86) infinite alternate;
}
Tous ces mouvements subtils donnent vie au yogi. En développant des SVG structurés, je peux créer des animations qui se sentent pleines de caractère sans écrire une seule ligne de javascript.
Essayez ceci vous-même:
Voir le stylo [Bewitched Bear CSS/SVG animation [forked]](https://codepen.io/smashingmag/pen/bndwjbn) par Andy Clarke.
Conclusion
Que vous recréiez une carte de titre classique ou que vous animé des icônes pour une interface, les principes sont les mêmes:
- Commencer à nettoyer,
- Optimiser tôt, et
- Structurez tout avec l’animation à l’esprit.
Les SVG offrent une liberté créative incroyable, mais seulement si elle est conservée maigre et maniable. Lorsque vous planifiez votre processus comme une cellule de production – couche par couche, élément par élément – vous passerez moins de temps à démêler le code et plus de temps pour donner vie à votre travail.
(GG, YK)
Source link