Fermer

mars 22, 2019

Décomposition de cercle SVG en chemins


À propos de l'auteur

Bryan Rasmussen est un développeur de longue date de Frontend Solutions qui possède également une vaste expérience en normalisation XML. Il vit actuellement dans une banlieue tranquille…
Pour en savoir plus sur Bryan

Cet article explique comment transformer les cercles SVG en chemins utilisables dans les chemins d'animation et de texte, ainsi que les transformer en cercles. Une fois que vous avez compris comment tout cela fonctionne, vous pourrez obtenir des effets assez pratiques. Voyons ce qu’il faut faire.

Cet article commence par une confession: j’aime coder à la main SVG. Ce n’est pas toujours le cas mais souvent cela peut sembler particulier aux personnes qui ne partagent pas ma prédilection. Pouvoir écrire à la main en SVG présente de nombreux avantages, tels que l'optimisation des SVG de la même manière qu'un outil (transformation d'un chemin en chemin ou forme simplifié), ou simplement en comprenant le fonctionnement de bibliothèques comme D3 ou Greensock.

Cela dit, j'aimerais examiner de plus près les formes circulaires en SVG et les solutions que nous pouvons utiliser avec celles-ci lorsque nous dépassons un cercle élémentaire. Pourquoi des cercles? J'aime les cercles. C'est ma forme préférée.

Tout d'abord (si vous avez déjà vu un cercle de base en SVG), voici un stylo qui en montre un:

Voir le stylo circle de Bryan Rasmussen .

On peut faire beaucoup de choses avec un cercle: il peut être animé et différentes couleurs peuvent être appliquées. Cependant, SVG 1.1 ne permet pas de faire un cercle: vous ne pouvez pas déplacer un autre élément graphique le long du tracé du cercle (à l'aide de l'élément animateMotion ) et vous ne pouvez pas mettre en forme un texte le chemin d'un cercle (cela ne sera autorisé qu'après la sortie de SVG 2.0).

Transformer notre cercle en chemin

Il existe un petit outil en ligne qui peut vous aider à créer des chemins à partir de cercles (vous pouvez l'essayer here ), mais nous allons tout créer à partir de rien afin de savoir ce qui se passe réellement dans les coulisses.

Pour créer un tracé circulaire, nous allons en créer deux les arcs, c'est-à-dire les demi-cercles qui complètent le cercle d'un chemin. Comme vous l'avez probablement remarqué dans le SVG ci-dessus, les attributs CX CY et R définissent respectivement où le cercle est tracé le long des axes X et Y. , tandis que R définit le rayon du cercle. Les CX et CY créent le centre du cercle, de sorte que le cercle est tracé autour de ce point.

La reproduction de ce cercle pourrait ressembler à ceci:


Notez que ] CX est identique à l'attribut cx du cercle; il en va de même pour CY et l'attribut du cercle cy ainsi que des attributs du cercle R et du r . Le petit un caractère est utilisé pour définir un segment d'arc elliptique. Vous pouvez utiliser un paramètre facultatif Z (ou z ) pour fermer le chemin.

La lettre minuscule a indique le début d'un arc elliptique dessiné relativement à la position actuelle – ou dans notre cas spécifique:


Vous pouvez voir la magie se dérouler dans ce stylo:

Voir le cercle du cercle du chemin de par Bryan Rasmussen . [19659005] Caché sous le chemin se trouve un cercle avec un remplissage rouge. En jouant avec les valeurs du chemin, vous verrez ce cercle tant que le chemin recouvre totalement le cercle (le chemin lui-même est un cercle de la même taille), et nous saurons que nous agissons correctement. .

Vous devez également savoir que tant que vous tracez des arcs relatifs, vous n'avez pas besoin de répéter la commande a pour chaque arc que vous tracez. Lorsque vos 7 premières entrées sont terminées pour votre arc, les 7 autres entrées seront prises pour le prochain arc.

Vous pouvez essayer ceci avec le stylo ci-dessus en supprimant la deuxième a dans le chemin:

 a 25,25 0 1,1 50,0

25,25 0 1,1 -50,0

Cela peut sembler identique, mais je préfère le laisser jusqu'à ce que je sois prêt à terminer un dessin, ce qui m'aide également à garder une trace de l'endroit où je suis.

Comment ce chemin fonctionne-t-il

Premièrement, nous passons à une coordonnée X, Y parfaitement positionnée dans l'image. Il ne dessine rien là-bas – il ne fait que s'y déplacer. Rappelez-vous que pour un élément de cercle CX CY désigne le centre du cercle; mais comme dans l'arc elliptique, les véritables CX et CY de l'arc seront calculés à partir des autres propriétés de cet arc.

En d'autres termes, si nous voulons notre CX soit à 50 et notre rayon est 25 alors nous devons passer à 50 - 25 (si nous dessinons de gauche à droite, bien sûr). Cela signifie que notre premier arc est tiré de 25 X, 50 Y et que notre premier arc est 25,25 0 1,0 50,0 .

Décomposons. que signifie réellement la valeur de notre arc 25,25 0 1,0 50,0 :

  • 25 : Le rayon X relatif de l'arc;
  • 25 : Le rayon relatif Y de l'arc;
  • 0 1,0 : Je ne parlerai pas des trois valeurs du milieu (rotation, propriétés du drapeau grand arc et du drapeau à balayage) car elles ne sont pas très important dans le contexte de l'exemple actuel dans la mesure où ils sont identiques pour les deux arcs;
  • 50 : La coordonnée de fin X de l'arc;
  • 0 : La fin Y coordonnée (relative) de l'arc

Le deuxième arc est un 25,25 0 1,0 -50,0 . Gardez à l'esprit que cet arc commencera à dessiner là où le dernier arc s'est arrêté de dessiner. Bien sûr, les rayons X et Y sont les mêmes ( 25 ), mais la coordonnée de fin X est -50 à l'endroit où se trouve le rayon actuel.

Évidemment, ce cercle pourrait avoir été dessiné de nombreuses façons différentes. Ce processus consistant à transformer un cercle en chemin est appelé décomposition. Dans la SVG 2, la décomposition d'un cercle dans un cercle sera effectuée avec 4 arcs. Cependant, la méthode recommandée n'est pas encore utilisable, car elle dépend actuellement d'une fonction appelée complétant la fermeture du segment. chemin qui n'a pas encore été spécifié.

Afin de vous montrer que nous pouvons tracer le cercle de nombreuses façons, j'ai préparé un petit stylo avec plusieurs exemples:

Voir le stylo Tous les cercles de Bryan Rasmussen .

Si vous regardez de plus près, vous verrez notre cercle d'origine ainsi que cinq exemples différents pour tracer des chemins au-dessus de ce cercle. Chaque chemin a un élément desc décrivant l'utilisation des valeurs CX CY et R pour construire le cercle. Le premier exemple est celui dont nous avons discuté ici, tandis que trois autres utilisent des variantes qui devraient être compréhensibles à la lecture du code; le dernier exemple utilise quatre arcs semi-circulaires au lieu de deux, reproduisant quelque peu le processus décrit dans la spécification SVG 2 liée ci-dessus.

Les cercles sont superposés à l'aide de la z-indexation naturelle des éléments de placement par SVG. balises au-dessus de celles qui viennent plus tôt.

Si vous cliquez sur les tracés circulaires dans le stylo, le premier clic indiquera la structure du tracé dans la console et ajoutera une classe à l'élément afin que vous puissiez le voir. la couleur de trait du dessin du cercle (vous pouvez voir que le premier cercle est tracé avec un coin de départ du trait). Le deuxième clic supprimera le cercle afin que vous puissiez interagir avec le cercle ci-dessous.

Chaque cercle a une couleur de remplissage différente; L'élément cercle réel est jaune et indiquera «Vous avez cliqué sur le cercle» à la console chaque fois que vous cliquez dessus. Vous pouvez aussi, bien sûr, simplement lire le code car les éléments desc sont assez simples.

Aller d'un chemin à un cercle

Je suppose que vous avez remarqué qu'il existe de nombreuses manières de dessiner le cercle, les chemins utilisés sont encore assez similaires. Souvent, en particulier dans les SVG générés par un programme de dessin, les cercles sont représentés par des chemins. Ceci est probablement dû à l'optimisation du code du programme graphique; Une fois que vous avez le code pour dessiner un chemin, vous pouvez tout dessiner, alors utilisez-le. Cela peut conduire à des SVG quelque peu gonflés qu'il est difficile de raisonner.

Lectures recommandées : « Conseils pour créer et exporter de meilleurs SVG pour le Web » de Sara Soueidan

Prenons par exemple le SVG de Wikipedia . Quand vous regardez le code de ce fichier, vous verrez qu'il a beaucoup de travail de l'éditeur une fois que vous l'avez lu dans le SVGOMG! de Jake Archibald (que vous pouvez en lire plus sur ici ici ). Vous obtiendrez quelque chose comme le fichier suivant qui a été plutôt optimisé, mais les cercles du document sont toujours restitués sous forme de chemins:

Voir le stylo Wikipedia embrayage à tête de vis type A de Bryan Rasmussen .

Voyons si nous pouvons déterminer ce que devraient être ces cercles s’il s’agissait d’éléments de cercle réels, compte tenu de ce que nous savons sur le fonctionnement des chemins. Le premier chemin dans le document n'est évidemment pas un cercle, alors que les deux suivants le sont (ne montrant que l'attribut d ):

 M39 20a19 19 0 1 1-38 0 19 19 0 1 1 38 0z
 M25 20a5 5 0 1 1-10 0 5 5 0 1 1 10 0z

Rappelez-vous que le deuxième un peut être laissé de côté, réécrivons-les pour donner un peu plus de sens. (Le premier chemin est le grand cercle.)

 M39 20
a19 19 0 1 1-38 0
a19 19 0 1 1 38 0z

Ces arcs sont alors évidemment les suivants:

 aR R 0 1 1 - (R * 2) 0
aR R 0 1 1 (R * 2) 0

Cela signifie que notre rayon de cercle est 19 mais quelles sont nos valeurs CX et CY ? Je pense que notre M39 est en réalité CX + R ce qui signifie que CX est 20 et CY est 20 aussi

Supposons que vous ajoutiez un cercle après tous les chemins comme celui-ci:

 

Vous verrez que c'est correct et que le cercle en traits rouges couvre exactement le grand cercle. Le deuxième chemin de cercle reformulé ressemble à ceci:

 M25 20
a5 5 0 1 1-10 0
5 5 0 1 1 10 0z

Évidemment, le rayon est 5 et je parie que nos CX et CY sont les mêmes qu'auparavant: - 20 .

Note : Si CX = 20 alors CX + R = 25 . Le cercle est assis à l'intérieur du plus grand au centre, si bien qu'il devrait évidemment avoir les mêmes valeurs CX et CY .

Ajoutez le cercle suivant à la fin du texte. les chemins:

 

Vous pouvez maintenant voir que cela est correct en jetant un coup d'œil au stylo suivant:

Voir le stylo Le type d'embrayage à vis de type Wikipedia A_ avec exemples de cercles de Bryan Rasmussen .

Maintenant que nous savons ce que devraient être les cercles, nous pouvons supprimer ces chemins inutiles et en créer des véritables – comme vous pouvez le voir ici:

Voir le stylo Wikipedia embrayage à tête à vis de type A optimisé par Bryan Rasmussen .

Utiliser notre chemin circulaire pour envelopper du texte

Maintenant que nos cercles se trouvent dans des chemins, nous pouvons envelopper du texte sur ces chemins. Vous trouverez ci-dessous un stylo avec les mêmes chemins que notre précédent stylo «Tous les cercles», mais avec un texte entouré sur le chemin. Chaque fois que vous cliquez sur un chemin, ce chemin sera supprimé et le texte sera enveloppé dans le prochain chemin disponible, comme suit:

Voir le stylo tous les cercles sont enveloppés Texte de Bryan Rasmussen .

En regardant les différents chemins, vous verrez des différences minimes entre chacun (plus sur cela dans un peu), mais d'abord, il y a une petite incompatibilité entre les navigateurs à voir – particulièrement visible dans le premier chemin :

Développeur Firefox
Chrome
Microsoft Edge

La raison pour laquelle le «S» de départ de «Smashing» se situe à cet angle amusant dans la solution Firefox est que nous avons commencé à dessiner notre chemin at (en raison de la commande vR que nous avons utilisée). Ceci est plus évident dans la version Chrome où vous pouvez voir clairement le premier coin en forme de camembert de notre cercle que nous avons dessiné:

Chrome ne suit pas tous les coins, ainsi le résultat est obtenu lorsque vous modifiez le texte en “ Smashing Magazine ”.

La raison en est que Chrome avait un bogue concernant l'héritage de l'attribut textLength déclaré sur l'élément parent text . Si vous voulez que les deux aient le même aspect, mettez l'attribut textLength sur l'élément textPath ainsi que le texte. Pourquoi? Parce qu'il s'avère que Firefox Developer a le même bogue si l'attribut textLength n'est pas spécifié sur l'élément text (c'est le cas depuis quelques années maintenant. ).

Microsoft Edge a un bogue totalement différent; il ne peut pas gérer les espaces entre l'élément Text et l'enfant TextPath . Une fois que vous avez supprimé les espaces et mis les attributs textLength à la fois sur les éléments text et textPath ils se ressemblent tous relativement (avec de petites variations dues à différences dans les polices par défaut et ainsi de suite). Donc, trois bugs différents sur trois navigateurs différents – c'est pourquoi les gens préfèrent souvent travailler avec des bibliothèques!

Le stylo suivant montre comment résoudre les problèmes:

Voir le stylo tous les cercles sont entourés Texte fixe TextLength de Bryan Rasmussen .

J'ai également supprimé les différentes couleurs de remplissage, car cela facilite la visualisation du texte enveloppant. Supprimer les couleurs de remplissage signifie que ma petite fonction vous permettant de parcourir les chemins et de voir à quoi ils ressemblent ne fonctionnera pas à moins d’ajouter un attribut pointer-events = "all" . ceux-là aussi.

Note : Vous en saurez plus sur les raisons de cela dans « Gestion de l'interaction SVG avec la propriété des événements du pointeur », expliquée par Tiffany B. Brown .

Nous avons déjà discuté de l’enveloppement du chemin multiarc, regardons maintenant les autres. Comme nous avons un chemin que nous terminons, le texte ira toujours dans le même sens.

Image Chemin Explication
M CX, CY
a R, R 0 1,0 - (R * 2), 0
a R, R 0 1,0 R * 2, 0
et utilise la fonction traduction pour se déplacer + R sur le Axe X.
La position de départ de notre textPath (puisque nous ne l’avons pas spécifié) est déterminée par notre premier arc de fin - (R * 2) à partir du le rayon que l'arc lui-même a.
M (CX + R), CY
a R, R 0 1,0 - ( R * 2), 0
a R, R 0 1,0 (R * 2), 0
Même chose que le chemin précédent.

M CX CY
m -R, 0
a R, R 0 1,0 (R * 2), 0
a R, R 0 R, 0 - (R * 2), 0
Puisque nous terminons à (R * 2) dans notre premier arc, nous allons évidemment commencer à la position opposée. En d'autres termes, celui-ci commence là où nos deux chemins précédents se sont terminés.
M (CX - R), CY
a R, R 0 1, 1 (R * 2), 0
a R, R 0 1, 1 - (R * 2), 0
Cela commence. dans la même position que le dernier en raison de (R * 2) mais il tourne dans le sens des aiguilles d'une montre car nous avons défini la propriété du drapeau à balai (marquée en jaune) sur 1 .

Nous avons vu comment insérer du texte sur un seul chemin dans un cercle. Voyons maintenant comment nous pouvons diviser ce chemin en deux chemins et les avantages que vous pouvez en tirer.

Briser nos chemins en plusieurs parties

Vous pouvez faire beaucoup de choses avec le texte de votre path, c’est-à-dire obtenir des effets stylistiques avec les éléments tspan régler le décalage du texte ou animer le texte. Fondamentalement, tout ce que vous ferez sera contraint par le chemin lui-même. Mais en divisant nos chemins multi-arcs en chemins à arc unique, nous pouvons jouer avec la direction de notre texte, l'indexation z de différentes parties de notre texte et la réalisation d'animations plus complexes.

Tout d'abord, nous allons vouloir d'utiliser une autre image SVG pour montrer certains des effets. J'utiliserai le diamant de l'article sur les événements de pointeur dont j'ai déjà parlé. Tout d’abord, montrons ce qu’il va ressembler avec un texte circulaire à un seul chemin posé dessus.

Supposons que notre cercle est CX 295, CY 200, R 175 . Maintenant, suivant la méthode du chemin circulaire, nous voyons ce qui suit:

 M (CX - R), CY
a R, R 0 1,1 (R * 2), 0
a R, R 0 1,1 - (R * 2), 0

Voir le stylo SVG Amethyst de Bryan Rasmussen .

Je ne vais pas parler du chemin ou de la taille du texte, du fond ou de la couleur de trait. Nous devrions tous comprendre cela maintenant et pouvoir faire en sorte que ce soit ce que nous voulons. Mais en regardant le texte, nous pouvons immédiatement constater des inconvénients ou des inconvénients:

  • Le texte va dans une direction;
  • Il serait peut-être intéressant de laisser une partie du texte derrière l’améthyste, en particulier là où il est écrit: MAGAZINE. Pour que les lettres «M» et «E» soient alignées sur le cercle, le «A» doit se trouver du côté inférieur de l’améthyste, ce qui donne une impression de déséquilibre d’une autre manière. (Je pense que le «A» devrait être positionné avec précision et pointé vers le bas à cet endroit.)

Si nous voulons résoudre ces problèmes, nous devons scinder notre chemin unique en deux. Dans le stylo suivant, j’ai séparé le chemin en deux chemins (et les ai placés dans la zone du defs du SVG pour notre textPath s à référence):

Voir le Stylo SVG Améthyste deux chemins de Bryan Rasmussen .

Encore une fois, en supposant que notre CX est 295, CY 200, R 175 alors les deux chemins sont au format suivant (pour le chemin semi-circulaire supérieur):

 M (CX - R), CY
a R, R 0 1,1 (R * 2), 0

Et les suivantes pour le fond:

 M (CX + R), CY
a R, R 0 1,1 - (R * 2), 0

Cependant, nous avons toujours un texte circulaire qui va dans le même sens. Pour résoudre ce problème pour tout sauf Edge, il vous suffit d'ajouter l'attribut side = "right" à l'élément text qui contient l'élément 'MAGAZINE' textPath .

Donner une autre direction au texte

Si nous voulons supporter autant de navigateurs que possible, nous devons modifier le chemin et ne pas nous fier à l'attribut côté qui n'est pas complètement prise en charge. Ce que nous pouvons faire, c'est copier notre chemin du demi-cercle supérieur, mais changer le balayage de 1 à 0 :

Avant:

 M 120, 200
175 175 0 1,  1   350,0

Après:

 M 120, 200
175 175 0 1,  0   350,0

Mais notre texte est maintenant dessiné sur le cercle intérieur défini par le balayage et il n’aura pas une aussi belle apparence dans différents navigateurs. Cela signifie que nous allons devoir déplacer la position de notre chemin pour s’aligner sur le "S" de "Smashing", augmenter la fin X du chemin et définir un décalage par rapport au texte. Comme vous pouvez le constater, il existe également une petite différence de texte entre Firefox et les autres que nous pouvons améliorer en augmentant l'attribut textLength sur l'élément text ainsi qu'en supprimant les espaces blancs de la textPath (puisque Firefox pense évidemment que les espaces sont significatifs).

La solution:

Voir le stylo SVG Amethyst à deux chemins fixés par Bryan Rasmussen .

Modifier l'index Z d'une partie de notre texte circulaire

Enfin, nous souhaitons que notre texte aille à la fois devant et derrière l'améthyste. Eh bien, c’est facile. Rappelez-vous que l’indexation z de l’élément par SVG est basée sur leur position dans le balisage? Donc, si nous avons deux éléments, l'élément 1 sera tracé derrière l'élément 2 . Ensuite, tout ce que nous avons à faire est de déplacer un élément de texte dans notre balisage SVG afin qu'il soit tracé avant l'améthyste.

Vous pouvez voir le résultat ci-dessous dans lequel des parties du mot 'MAGAZINE' sont cachés par le point inférieur de l'améthyste.

Voir le stylo SVG Améthyste à deux voies z-index de par Bryan Rasmussen .

Si vous jetez un coup d'œil au balisage , vous pouvez voir que le demi-cercle inférieur du texte a été déplacé pour être placé avant le chemin qui dessine l'améthyste.

Animation des parties de notre cercle

Nous avons maintenant la possibilité de créer un texte circulaire en contrôlant complètement la directionnalité. des parties de notre texte en le mettant en deux demi-cercles. Ceci peut, bien sûr, également être exploité pour faire des animations du texte. La création d'animations SVG inter-navigateurs fait vraiment l'objet d'un autre article (ou de beaucoup plus articles). Ces exemples ne fonctionneront que dans Chrome et Firefox, car ils utilisent la syntaxe SMIL-animations au lieu d’images-clés CSS ou d’outils tels que Greensock. Mais cela donne un bon indicateur des effets que vous pouvez obtenir en animant le cercle décomposé.

Prenez la plume suivante:

Voir le stylo SVG Améthyste deux chemins animés par Bryan Rasmussen .

Veuillez appuyer sur le bouton "Ré-exécuter" sur le codepen pour voir l'animation en action. Les deux parties de notre texte circulaire commencent à s'animer en même temps, mais ont une durée différente et finissent donc à des moments différents. Parce que nous animons l'attribut textLength nous avons placé deux directives animate sous chaque texte – une pour l'élément de texte (donc Firefox fonctionnera) et une pour l'élément textpath (donc Chrome fonctionnera).

Conclusion

Dans cet article, nous avons vu comment transformer un cercle en chemin, afin de mieux comprendre quand besoin d'optimiser un chemin et quand pas. Nous avons vu comment transformer le cercle en tracé nous permettait de placer le texte sur un tracé circulaire, mais aussi comment scinder davantage le tracé circulaire en demi-cercles et obtenir un contrôle plus complet de la directionnalité et de l'animation des composants de notre texte circulaire.

Lectures complémentaires sur SmashingMag:

 Éditorial éclatant (dm, ra, yk, il)




Source link