Tout sur les animations SVG

Dans cet article, je veux souligner les subtilités du travail avec les graphiques SVG, l'animation SVG (y compris le chemin), les problÚmes et les méthodes pour les résoudre, ainsi que divers piÚges, dont il existe de nombreux SVG. Je positionne cet article comme un guide détaillé.



Il n'y aura pas de plugins, bibliothĂšques, etc., nous ne parlerons que de SVG pur.
Le seul outil que j'utiliserai est Adobe Illustrator.

Préface


Tout a commencĂ© par une confĂ©rence ennuyeuse et dans l'espoir de me divertir avec au moins quelque chose, j'ai dĂ©cidĂ© d'Ă©tudier le graphisme SVG, Ă  savoir l'animation. À ma grande surprise, il y avait trĂšs peu d'informations sur Internet. Partout, il y avait des informations en double expliquant les bases, mais sur l'animation en gĂ©nĂ©ral Ă  partir de la force de 2-3 liens avec des informations absolument identiques, qui est une traduction de l'article Un guide des animations SVG (SMIL) de Sarah Suydan.

Son article parle de tout, mais superficiellement. Néanmoins, je vous recommande fortement de vous familiariser avec elle. * Lien vers la traduction *

Les semaines suivantes, j'ai passé à recueillir des informations piÚce par piÚce auprÚs de diverses sources. Le résultat de ces recherches est cet article.

Exportation SVG appropriée depuis Illustrator


Cette section se concentre sur les fonctionnalités et les problÚmes d'Adobe Illustrator, donc si vous n'utilisez pas Illustrator, vous pouvez ignorer cette partie.

La prĂ©paration d'un document pour l'animation est une Ă©tape trĂšs importante, dont la nĂ©gligence peut entraĂźner des consĂ©quences trĂšs dĂ©sagrĂ©ables. Pour vous apprendre Ă  mieux dessiner dans Illustrator, je ne le ferai pas. La seule chose que je dirai, c'est que lorsque vous dessinez des formes, vous devez garder une trace des valeurs, il est souhaitable qu'elles n'aient qu'un seul nombre aprĂšs la virgule dĂ©cimale, et il vaut mieux ĂȘtre entier. Il n'est pas nĂ©cessaire de suivre cette rĂšgle, mais cela rĂ©duira la taille du fichier, simplifiera l'animation et rĂ©duira visuellement la quantitĂ© d'informations. Jetez un oeil

<path d="M 17.7 29 C 28.2 12.9 47 5.6 62.8 10.4 c 28.2 8.5 30 50.5 24.8 53.1 c -2.6 1.3 -10.4 -6.1 -29.2 -34.6"/> <path d="M 17.651 28.956 c 10.56 -16.04 29.351 -23.359 45.12 -18.589 c 28.151 8.516 29.957 50.5 24.841 53.063 c -2.631 1.318 -10.381 -6.148 -29.235 -34.643"/> 

Dans l'exemple, la mĂȘme courbe, mais dans le premier cas, un chiffre aprĂšs le point dĂ©cimal, et dans les trois autres. Cette courbe n'a que 4 points et le deuxiĂšme exemple est un tiers plus long que le premier. Imaginez combien d'espace une courbe de 20 points prendra.

Une fois le filaire dessiné, vous devez enregistrer l'image en tant que fichier SVG. Il existe deux façons de procéder: Enregistrer sous ou Exporter sous. Mais quelle voie choisir? Si vous me faites confiance, mieux vaut utiliser "enregistrer sous". Si vous voulez savoir pourquoi, déployez un spoiler.

Alors pourquoi?
À premiĂšre vue, cela ne fait aucune diffĂ©rence, car au final, nous obtenons un fichier .svg avec notre image. Cependant, les diffĂ©rences commencent au stade des paramĂštres d'exportation.


Je ne vois pas l'intĂ©rĂȘt d'expliquer tous les paramĂštres en dĂ©tail, Illustrator le fait trĂšs bien dans la section "Description".

Comme vous pouvez le voir, «enregistrer» a plus de paramÚtres que «exporter», et pour quelqu'un, ce sera déjà une bonne raison de refuser d'exporter, mais nous continuerons.

Si nous ouvrons des fichiers enregistrĂ©s dans les deux sens dans un navigateur, nous ne remarquerons pas la diffĂ©rence. Cependant, pour le moment, nous ne nous intĂ©ressons plus Ă  l'apparence, mais au remplissage, nous ferons donc de mĂȘme, mais via un Ă©diteur de texte. Ici, les diffĂ©rences deviendront plus apparentes. Je vous suggĂšre de regarder et de tirer des conclusions vous-mĂȘme, je n'ai rien changĂ© dans les fichiers, je viens de copier le tout tel quel.

Exporter

 <svg id="_1" data-name=" 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 51 51"> <defs> <style> .cls-1 { fill: none; stroke: #4ec931; stroke-miterlimit: 10; } .cls-2 { fill: #4ec931; } .cls-3 { fill: #fff; } </style> </defs> <title>my_icon_E</title> <circle class="cls-1" cx="25.5" cy="25.5" r="20"/> <circle class="cls-1" cx="25.5" cy="25.5" r="25"/> <g id="_2" data-name=" 2"> <circle class="cls-2" cx="25.5" cy="25.5" r="15"/> <polygon class="cls-3" points="25.5 34.8 34 20.3 17 20.3 25.5 34.8"/> </g> </svg> 

Enregistrer

 <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" id="_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve"> <style type="text/css"> .st0{fill:none;stroke:#4EC931;stroke-miterlimit:10;} .st1{fill:#4EC931;} .st2{fill:#FFFFFF;} </style> <circle class="st0" cx="50" cy="50" r="20"/> <circle class="st0" cx="50" cy="50" r="25"/> <g id="_2"> <circle class="st1" cx="50" cy="50" r="15"/> <polygon class="st2" points="50,59.3 58.5,44.8 41.5,44.8 "/> </g> </svg> 

Outre les différences de dénomination des classes CSS et de la conception en général, que certains peuvent juger de bon goût, il existe d'autres problÚmes. Lors de "l'exportation", l'image entiÚre a été réduite de 2 fois. Vous pouvez en juger par la taille des formes et l'attribut viewBox . Comme il s'agit d'un graphique vectoriel, cela n'a pas empiré, mais c'est toujours désagréable. "Enregistrement" a laissé les dimensions que j'ai spécifiées dans Illustrator.

Mais ce ne sont que des fleurs par rapport au type de porc que «l'exportation» peut mettre. Plus précisément, ces exemples n'ont pas ce problÚme, probablement parce que l'image est trÚs simple. Cependant, je l'ai rencontré lors de l'exportation de mon autre travail. Voici sa capture d'écran



La taille du fichier est assez grande, donc je ne donnerai que la partie problématique

 <g id="-21" data-name=""> <path class="cls-9" d="M477.94,456.75a1.83,1.83,0,0,1-.9,1.36l-4.91,3.1a7.29,7.29,0,0,1-7.5,0l-16.29-9.72a1.85,1.85,0,0,1-.92-1.56v-3.68a1.85,1.85,0,0,0,.92,1.56l.38.23,15.91,9.49a7.29,7.29,0,0,0,7.5,0l4.53-2.86.38-.23a1.87,1.87,0,0,0,.9-1.36Z" transform="translate(-5.5 -5.5)"/> <path class="cls-10" d="M477,451.19l-16.38-9.5a7.28,7.28,0,0,0-7.32,0l-5,2.9a1.88,1.88,0,0,0-.94,1.51v.17a1.85,1.85,0,0,0,.92,1.56l.38.23,15.91,9.49a7.29,7.29,0,0,0,7.5,0l4.53-2.86.38-.23a1.87,1.87,0,0,0,.9-1.36v-.51A1.88,1.88,0,0,0,477,451.19Z" transform="translate(-5.5 -5.5)"/> </g> <g id="-22" data-name=""> <path class="cls-9" d="M525.37,557.86a1.85,1.85,0,0,1-.9,1.36l-33.22,19.64a7.29,7.29,0,0,1-7.5,0l-16.29-9.72a1.85,1.85,0,0,1-.92-1.56v-3.68a1.85,1.85,0,0,0,.92,1.56l.38.23,15.91,9.49a7.29,7.29,0,0,0,7.5,0l32.84-19.41.38-.23a1.83,1.83,0,0,0,.9-1.36Z" transform="translate(-5.5 -5.5)"/> <path class="cls-10" d="M524.45,552.3l-16.38-9.51a7.31,7.31,0,0,0-7.32,0l-33.27,19.44a1.89,1.89,0,0,0-.94,1.51v.17a1.85,1.85,0,0,0,.92,1.56l.38.23,15.91,9.49a7.29,7.29,0,0,0,7.5,0l32.84-19.41.38-.23a1.83,1.83,0,0,0,.9-1.36v-.5A1.86,1.86,0,0,0,524.45,552.3Z" transform="translate(-5.5 -5.5)"/> </g> 

Avez-vous remarqué quelque chose d'inhabituel? Si vous regardez de travers l'attribut de transformation , alors vous avez raison. C'est lui qui gùte toute la framboise. Lorsque vous "exportez" une image, Illustrator l'affecte à TOUS les éléments <chemin> . Cependant, un tel problÚme n'est pas observé avec la "conservation".

Si vous ne comprenez toujours pas mon indignation, alors je vais vous expliquer: si vous voulez animer le mouvement d'un tel Ă©lĂ©ment, alors il se dĂ©placera sur le cĂŽtĂ©. Dans ce cas, 5,5 sur les deux axes. Cela est dĂ» au fait que l'animation de mouvement modifie l'attribut de transformation , rĂ©initialisant toutes les valeurs passĂ©es. Bien sĂ»r, cela peut ĂȘtre contournĂ©, mais ne vaut-il pas mieux Ă©viter le problĂšme que d'en corriger les consĂ©quences plus tard ...

Pour le moment, je n'ai remarqué que ce problÚme, mais cela ne veut pas dire que c'est le seul. Si vous évaluez la situation de maniÚre raisonnable, il s'avÚre que «enregistrer sous» l'emporte sur tout. C'est pourquoi je vous conseille de l'utiliser.

Façons d'importer un document SVG en HTML


Avant de commencer directement avec l'animation, je veux parler de la façon d'incorporer SVG sur une page. Chaque méthode a ses propres «fonctionnalités» qui ont un impact direct sur l'animation. Et si vous n'en parlez pas, l'article sera incomplet.
Supposons que vous disposez dĂ©jĂ  d'un SVG prĂȘt Ă  l'emploi avec animation interactive et qu'il reste Ă  intĂ©grer ce document sur le site. Comment faire ça?

L'option numĂ©ro un est de se rappeler que SVG est Ă©galement une image et peut ĂȘtre importĂ© Ă  l'aide d'outils HTML standard. Vous pouvez crĂ©er une balise <img> avec un lien vers un document

 <img src="Hello_SVG.svg" /> 

Ou définissez SVG comme image de fond

 #box { background-image: url("Hello_again.svg"); } 

Le principal inconvĂ©nient de cette mĂ©thode est l'isolement de l'image. SVG en tant qu'exposition au musĂ©e - vous pouvez regarder, sans toucher. L'animation Ă  l'intĂ©rieur fonctionnera, mais il ne peut ĂȘtre question d'aucune interactivitĂ©. Si, par exemple, une animation est dĂ©clenchĂ©e par un clic de l'utilisateur ou s'il est nĂ©cessaire de modifier dynamiquement le contenu d'un document SVG, cette mĂ©thode n'est pas pour vous.

L'option numéro deux consiste à créer un objet à partir de SVG à l'aide des balises <object> ou <embed> . Il est également possible d'utiliser <iframe> pour créer un cadre, mais je ne recommande pas d'utiliser cette méthode, car une béquille est requise pour tous les navigateurs afin que cette option s'affiche correctement

 <object data="My_SVG.svg" type="image/svg+xml"></object> <embed src="My_SVG.svg" type="image/svg+xml" /> <iframe src="My_SVG.svg"></iframe> 

Ici, les choses vont mieux. Les animations ont la possibilitĂ© d'ĂȘtre interactives, mais uniquement si elles sont dĂ©clarĂ©es dans un document SVG et que le contenu est disponible pour JavaScript externe. <objet> et <iframe> peuvent toujours afficher un stub si soudainement l'image ne se charge pas.

L'option numĂ©ro trois consiste Ă  coller simplement le contenu du document SVG directement dans le code HTML. Oui, c'est possible. Le support SVG est apparu dans la norme HTML5 . Étant donnĂ© que SVG fait essentiellement partie de la page elle-mĂȘme, son accĂšs est partout. Les animations et les styles d'Ă©lĂ©ments peuvent ĂȘtre dĂ©clarĂ©s Ă  la fois Ă  l'intĂ©rieur du SVG et dans des fichiers externes. L'inconvĂ©nient est que ces images ne sont tout simplement pas mises en cache sĂ©parĂ©ment de la page

 <body> ... <svg> <!--  --> </svg> </body> 

Animation SVG


Il existe deux façons principales d'animer un élément SVG:

  • Animation CSS
  • Animation SMIL intĂ©grĂ©e Ă  SVG (en fait, c'est une animation SVG qui est basĂ©e sur SMIL et Ă©tend ses fonctionnalitĂ©s)

Personnellement, je les sépare en animations «externes» et «internes». Cette division est conditionnelle, mais ils ont encore des différences fonctionnelles. Si nous parlons des différences en général: CSS - a un meilleur support pour les navigateurs; SMIL - a une grande fonctionnalité. Il est difficile de dire lequel est préférable d'utiliser car ils se ressemblent beaucoup. Le choix dépend de la tùche, donc je vais juste dire les principales raisons d'utiliser SMIL au lieu de CSS

SMIL - en cas de besoin:

  1. Ce que CSS ne pouvait pas faire (animer un attribut non pris en charge, etc.)
  2. Ayez un contrÎle plus précis sur l'animation.
  3. Faire du morphing de chemin (animation de l'attribut d au tag de chemin )
  4. Synchroniser les animations
  5. Créez des animations interactives

Si j'ai Ă©crit que SMIL devrait ĂȘtre utilisĂ© pour des animations interactives, cela ne signifie pas que la mĂȘme chose ne peut pas ĂȘtre faite avec CSS. Simply SMIL est un outil plus fonctionnel et sophistiquĂ©. Et c'est pourquoi il ne doit ĂȘtre utilisĂ© qu'en cas de besoin. Si l'animation est simple et que CSS peut ĂȘtre supprimĂ©, alors cela devrait ĂȘtre fait.

Animation CSS


Rien de nouveau ici. Nous pouvons animer n'importe quel Ă©lĂ©ment SVG de la mĂȘme maniĂšre que nous le faisons avec HTML. Toutes les animations sont créées Ă  l'aide de @keyframes . Puisque l'animation CSS est un autre sujet, je ne m'attarderai pas sur ce point en dĂ©tail, le rĂ©seau est plein de documentation et de guides sur ce sujet. Tout ce qui y est dĂ©crit s'applique au SVG, mais je vais juste donner quelques exemples.

Le document SVG a des feuilles de style internes, nous allons donc y écrire des animations

 <svg> <style> <!--   --> </style> <!--   SVG  --> </svg> 

L'animation d'un attribut SVG est aussi simple que les attributs CSS

 @keyframes reduce_radius { from { r: 10; } to { r: 3; } } @keyframes change_fill { 0% { fill: #49549E; } 75% { fill: #1bceb1; } 100% { fill: #1bce4f; } } 

Vous pouvez spécifier des valeurs en pourcentage et une construction de-à

Il ne reste plus qu'à appliquer les animations créées à l'élément souhaité

 .circle { animation: change_fill 1s, popup 2s; } 

Tout ce que j'ai dĂ©crit ci-dessus, ce sont des animations statiques, il n'y a aucune odeur d'interactivitĂ© lĂ -bas. Et si vous en avez vraiment envie? Eh bien, quelque chose peut encore ĂȘtre fait de maniĂšre interactive et en CSS. Par exemple, si vous utilisez la transition en combinaison avec la pseudo- classe de survol

 .circle { fill: #49549E; transition: .3s; } .circle:hover { fill: #1bceb1; } 
Lorsque vous survolez un élément, sa couleur passe du bleu au bleu pendant 300 ms.

Animation des attributs et un petit morceau d'interactivitĂ© - c'est lĂ  que s'arrĂȘtent les fonctionnalitĂ©s de l'animation CSS. Mais cette fonctionnalitĂ© est suffisante, car la plupart des tĂąches se rĂ©sument Ă  l'animation d'un attribut. Presque tous les attributs SVG peuvent ĂȘtre animĂ©s. Et quand j'Ă©cris "presque n'importe quoi", je veux dire que si vous choisissez un attribut alĂ©atoire et qu'il s'avĂšre non invariant, alors vous ĂȘtes TRÈS chanceux.

Animation SMIL


Il vaut la peine de dire tout de suite que l'animation SMIL est aussi vieille que le monde et qu'elle s'éteint, la prise en charge du navigateur est décente, mais toujours moins que l'animation CSS, mais il y a une raison pour laquelle SMIL est toujours attrayant - cela peut parce que CSS ne peut pas.

Je parlerai davantage de SMIL, car il existe de nombreux piÚges sur lesquels ils écrivent rarement. Et ce sujet est moins populaire que CSS. Les balises principales pour l'animation sont <animate> , <set> , <animateTransform> , <animateMotion> .

<animer>


Commençons par l'artillerie lourde. <animer> - utilisé pour animer n'importe quel attribut et est l'outil principal. Les balises restantes sont hautement spécialisées, mais tout d'abord.

Comment appliquer une animation à un élément?

Il existe deux façons de spécifier l'élément auquel l'animation sera appliquée.

  1. Mettez la balise à l'intérieur de l'élément. Cette méthode vous permet d'encapsuler l'animation à l'intérieur de l'objet, ce qui facilite la lecture du code

     <circle ...> <animate .../> </circle> 
    Dans ce cas, l'animation sera appliquée à l'élément cercle .
  2. Passez le lien vers l'article. Utile si vous souhaitez que toutes les animations soient collectées en un seul endroit

     <svg xmlns:xlink="http://www.w3.org/1999/xlink"> <circle id="blue" .../> ... <animate xlink:href="#blue" .../> </svg> 
    L' attribut xlink: href est utilisé ici, dans lequel nous spécifions l' id de l' élément auquel l'animation doit s'appliquer. Pour que cette méthode fonctionne, vous devez définir l'espace de noms xlink . Cela se fait dans la balise <svg>.

Avec SVG 2, l' attribut xlink: href est obsolÚte, la spécification recommande d'utiliser href à la place, ce qui ne nécessite pas d'espace de noms xlink .

 <circle id="blue" .../> ... <animate href="#blue" .../> 

Mais ici, tout n'est pas si fluide - href n'est pas pris en charge par Safari. Il se trouve que la situation est dans l'impasse, un attribut est obsolĂšte, l'autre n'est pas pris en charge en partie. Alors quelle mĂ©thode utiliser, chacun dĂ©cide pour lui-mĂȘme.

Pour ceux qui ont remarqué des similitudes avec les sélecteurs CSS: je suis désolé de décevoir, je ne pourrai pas accéder aux éléments par classe

 <circle class="blue_circle" .../> <animate href=".blue_circle" .../> 
Ça ne marche pas!

Comment spécifier un attribut pour l'animation?

Il y a AttributeName pour cela. La valeur est le nom de l'attribut que nous allons animer.

 <circle r="25" ...> <animate attributeName="r" ... /> </circle> 
En spécifiant r dans attributeName , nous signalons que nous allons animer le rayon du cercle

Qu'est-ce que attributeType et pourquoi n'en avez-vous pas besoin?

Parce qu'il est inutile
En théorie, un moment peut survenir lorsque les noms d'attribut en CSS et XML correspondent, ce qui peut entraßner des problÚmes. Et pour résoudre ce conflit, vous devez spécifier explicitement un espace de noms. Il existe deux types de chaises : spécifiez un préfixe ou utilisez attributeType . Commençons par le préfixe.

Partout, ils écrivent quelque chose comme ceci:
Vous pouvez spécifier un préfixe XMLNS pour un attribut pour spécifier explicitement son espace de noms
Cette mĂ©thode est mentionnĂ©e en passant et sans exemples. Je ne changerai donc pas les traditions. (Je vous conseille de vous arrĂȘter ici, d'oublier les prĂ©fixes comme un cauchemar et d'aller sur attributeType , je vous ai prĂ©venu)

"Je suis masochiste"
Le contenu de ce spoiler est plutÎt divertissant et exploratoire. Aucune information utile, à part le fait que les préfixes ne fonctionnent pas, vous ne trouverez pas ici

Vous devez d'abord trouver une définition plus précise et, comme vous le savez, les définitions les plus précises dans les spécifications et les normes.

Un petit guide sur la façon d'abandonner la vie
  1. Nous ouvrons la spécification pour l'animation SVG pour le 14 mars 2019
  2. Dans la section attributeName , nous voyons qu'il hérite du standard d'animation SMIL pour (oh horror) 2001
  3. Lire la définition de attributeName
  4. Profit!

La traduction de la définition se lit comme suit:
«DĂ©finit le nom de l'attribut cible. Le prĂ©fixe XMLNS peut ĂȘtre utilisĂ© pour spĂ©cifier l'espace de noms XML pour un attribut. Le prĂ©fixe sera interprĂ©tĂ© dans le cadre de l'Ă©lĂ©ment d'animation. »
Hmm, ça n'a pas été plus facile. Que vient à l'esprit une personne qui ne connaßt pas XML aprÚs avoir lu une telle définition? Oui. Comme moi.

Je l'ai pris au pied de la lettre et j'ai pensé que ça devrait ressembler à ça

 <animate attributeName="xmlns:* *"/> 

J'ai pensĂ© et oubliĂ© cette mĂ©thode en toute sĂ©curitĂ© avant d'Ă©crire cet article. Les problĂšmes ont commencĂ© lorsque j'ai dĂ©cidĂ© de le tester en pratique. Je pense que je ne surprendrai personne si je dis que cela ne fonctionne pas. AprĂšs plusieurs heures de recherches infructueuses, j'ai googlĂ© «prĂ©fixe xmlns» et, Ă  ma grande surprise, j'ai vu que xmlns n'est pas le prĂ©fixe lui-mĂȘme, mais (concentrez-vous, ce sera difficile maintenant) la conception de l' espace de noms avec des prĂ©fixes .

Il se présente comme suit:

 <** xmlns:**="* url *" ...> 
Ensuite, j'ai réalisé que je ne comprenais rien ... au tout début ... et maintenant, en principe aussi

AprÚs quelques heures de plus, j'ai finalement trouvé ce que je cherchais dans les espaces de noms en XML . Voici un exemple original:

 <x xmlns:n1="http://www.w3.org" xmlns="http://www.w3.org" > <good a="1" n1:a="2" /> </x> 

Mais tu sais quelle est la chose la plus drîle? Ça ne marche toujours pas. Bien que tout se fasse selon le livre

 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:n1="http://www.w3.org/2000/svg"> <circle id="www" n1:r="10" .../> <animate href="#www" attributeName="n1:r" .../> </svg> 

Il n'y a pas d'erreurs et ne devrait pas l'ĂȘtre, car tout est fait selon les rĂšgles, mais le problĂšme est que nous obtenons un cercle sans rayon. Le mĂȘme rĂ©sultat sera si vous n'Ă©crivez simplement pas l'attribut r .

Épilogue : SVG ignore les attributs prĂ©fixĂ©s. Par consĂ©quent, mĂȘme si SMIL anime vraiment l'attribut avec un prĂ©fixe, vous ne verrez pas le rĂ©sultat de cette animation.
Pour ma défense, je dirai que je ne traitais que du SVG, à savoir de son animation, donc le gourou XML mettrait les torches et la fourche de cÎté. Si vous savez comment faire fonctionner cette méthode, bienvenue les commentaires

Pour indiquer explicitement Ă  quoi appartient l'attribut animĂ©, attributeType est utilisĂ©. Il prend 3 valeurs: CSS , XML , auto . À moins que attributeType ne soit explicitement spĂ©cifiĂ©, auto sera utilisĂ©. Dans ce cas, les propriĂ©tĂ©s CSS sont vĂ©rifiĂ©es en premier, et s'il n'y a pas de correspondance, les attributs de l'Ă©lĂ©ment cible sont vĂ©rifiĂ©s. Dans l'exemple, nous indiquons que nous allons animer exactement la propriĂ©tĂ© CSS

 <animate attributeType="CSS" attributeName="opacity" .../> 

Eh bien, attributeType vous permet d'indiquer facilement et sans bĂ©quilles Ă  quoi appartient l'attribut animĂ©, rĂ©solvant ainsi le "problĂšme", qui n'existe mĂȘme pas.

De façon inattendue, non? Comme je l'ai dit au dĂ©but du chapitre, SMIL s'Ă©teint et cela est dĂ» au fait que l'animation est traduite en rails CSS. La plupart des attributs en double sont absolument identiques les uns aux autres, c'est-Ă -dire peu importe si l'attribut CSS ou SMIL appartient - le rĂ©sultat sera le mĂȘme. Et en combinaison avec la valeur automatique par dĂ©faut, la nĂ©cessitĂ© de dĂ©finir explicitement attributeType n'est plus nĂ©cessaire.

Un moment de faits intĂ©ressants: attributeType n'est pas pris en charge par SVG. D'oĂč venait-il alors? Il nous est venu de SMIL Animation, sur lequel l'animation SVG est basĂ©e. Et attributeType est Ă©galement supprimĂ© aprĂšs la deuxiĂšme Ă©dition de SVG 1.1. Toutes les preuves ici

Comment déterminer les valeurs d'animation?

Il ne suffit pas de spécifier un attribut pour l'animation, vous devez définir ses valeurs. Voici venir de , à , par , valeurs .

Commençons par un couple toujours ensemble: de et vers . La signification de leur existence est évidente, de indique le début à la fin

 <circle r="25" ...> <animate attributeName="r" from="10" to="45" .../> </circle> 
Le résultat de l'animation sera un changement en douceur du rayon du cercle de 10 à 45

MĂȘme si j'ai dit qu'ils sont toujours ensemble, to peut Ă©galement ĂȘtre utilisĂ© sans dĂ©clarer explicitement from . Dans ce cas, from prendra la valeur dĂ©finie dans l'Ă©lĂ©ment cible. Pour l'exemple ci-dessus, l'animation commencera Ă  25.

S'il est nécessaire de spécifier un ensemble de plusieurs valeurs, des valeurs sont utilisées. Les valeurs sont répertoriées avec un point-virgule.

 <circle r="25" ...> <animate attributeName="r" values="15;50;25" .../> </circle> 
La valeur du rayon diminue Ă  15, puis augmente Ă  50, puis revient Ă  sa position d'origine.

DerniĂšre ligne par . Il ne se soucie pas «oĂč» et «oĂč», tout ce qui l'intĂ©resse, c'est «combien». En d'autres termes, au lieu de valeurs absolues, cela fonctionne avec des valeurs relatives

 <circle r="25" ...> <animate attributeName="r" by="15" .../> </circle> 
À la suite de l'animation, le rayon augmentera de 15, c'est-à-dire que vous obtenez 25 + 15 = 40

Une lĂ©gende fait le tour des Ă©tendues de manuels qui " par peuvent ĂȘtre utilisĂ©s pour indiquer la quantitĂ© d'avance des animations" . Je le comprends de cette façon: si de = 20 , Ă  = 50 , et donnĂ© par = 10 , alors ce chemin doit ĂȘtre surmontĂ© en "sautant" en 10, c'est-Ă -dire 20, 30, 40, 50. Mais peu importe comment j'ai essayĂ©, avec et sans, l'animation n'a pas changĂ© du tout. De plus, je n'ai pas trouvĂ© de confirmation dans les spĂ©cifications. Il semble que ce soit juste une erreur.

Les valeurs ont la priorité la plus élevée, puis de - à , en dernier. La priorité la plus basse de explique pourquoi une «légende» ne peut pas fonctionner en principe. Cependant, en travaillant conjointement avec from , dans ce cas, from remplace simplement la position actuelle de l'élément

 <circle cy="50" ...> <animate attributeName="cy" from="70" by="30" .../> </circle> 
Ici, l'animation au lieu de 50 commence Ă  70 et se termine Ă  100

En savoir plus sur les animations relatives

Vous pouvez faire fonctionner d'autres attributs de la mĂȘme maniĂšre que par . Cela se fait en utilisant l'attribut additif , qui a deux positions - remplacer et additionner .Le premier est la valeur par dĂ©faut, nous sommes donc intĂ©ressĂ©s par le second. Avec une valeur de somme, tous les attributs seront ajoutĂ©s Ă  la valeur actuelle de l'Ă©lĂ©ment cible, c'est-Ă -dire lors de l'animation d'un rayon de 20 avec les valeurs forme = 5 et Ă  = 15 , l'animation sera de 20 + 5 Ă  20 + 15

 <circle r="20" ...> <animate attributeName="r" from="5" to="15" additive="sum" .../> </circle> 

Lors de l'exĂ©cution de l'animation, il y aura un saut brusque Ă  la position 25, ce qui n'est pas bon (sauf si, bien sĂ»r, cela est prĂ©vu). Cela peut ĂȘtre Ă©vitĂ© avec form = 0 , mais alors le sens de l'utilisation de sum est perdu , car le mĂȘme effet peut ĂȘtre obtenu sans additif en utilisant par

 <animate attributeName="r" from="0" to="15" additive="sum" .../> <animate attributeName="r" by="15" .../> 
Quant à moi, la deuxiÚme méthode est beaucoup plus compréhensible et pratique:

oĂč spĂ©cifier la durĂ©e de l'animation?

Le dernier attribut requis est laissĂ© pour faire fonctionner l'animation - et c'est dur . La valeur d'attribut dĂ©termine la durĂ©e de l'animation, qui peut ĂȘtre spĂ©cifiĂ©e Ă  la fois en secondes et en millisecondes

 <animate dur="0.5s" .../> <animate dur="500ms" .../> <animate dur="00:00:00.5" .../> 
Depuis la derniĂšre ligne, vous pouvez deviner qu'il y a autre chose ...

Vous pouvez Ă©galement indiquer les valeurs en minutes et mĂȘme en heures

 <animate dur="1.2min" .../> <animate dur="0.02h" .../> 
, , , , ...


, ?

fill ( ) . :

  • remove ( ) – ,
  • freeze –

Est-il possible de boucler l'animation?

La réponse est oui. Pour ce faire, l'attribut repeatCount spécifie une valeur indéfinie . L'attribut détermine le nombre de répétitions de l'animation et par défaut à 1, mais vous pouvez spécifier n'importe quel nombre

 <animate repeatCount="indefinite" .../> <animate repeatCount="3" .../> 
Le premier se répétera à l'infini, le second fonctionnera 3 fois.

Maintenant, les animations sans fin me font chier, puis-je les désactiver aprÚs un certain temps?

Pour ces personnes ennuyeuses, rĂ©pĂ©terDur . Cet attribut arrĂȘte l'animation aprĂšs un certain temps Ă  partir du dĂ©but de l'animation! Autrement dit, repeatDur limite la durĂ©e de l'animation. La principale diffĂ©rence avec repeatCount est que l'animation peut ĂȘtre arrĂȘtĂ©e au milieu

 <animate dur="2s" repeatCount="indefinite" repeatDur="3s" .../> 
L'animation s'arrĂȘtera au milieu de la deuxiĂšme itĂ©ration.

Et si je veux que l'animation ne démarre pas tout de suite?

Alors pour vous, mon ami, l'attribut begin est fourni. Il est responsable du début de l'animation. Cet attribut est trÚs utile car il est également utilisé pour synchroniser plusieurs animations, mais plus à ce sujet plus tard.

Si vous devez spécifier le délai habituel de lancement, nous écrivons à quelle période de temps l'animation doit commencer aprÚs l'ouverture du document

 <animate begin="1.5s" .../> 
La lecture démarre aprÚs 1,5 seconde.

Vous pouvez Ă©galement spĂ©cifier une valeur nĂ©gative. Ensuite, l'animation ne commencera pas depuis le dĂ©but, mais Ă  l'endroit oĂč elle se trouverait aprĂšs une pĂ©riode de temps spĂ©cifiĂ©e

 <animate begin="-2s" dur="4s" .../> 
,



begin , , «on». , , «onclick» click

 <circle ...> <animate begin="click" .../> </circle> 

, . , id

 <circle id="button" .../> ... <animate begin="button.click" .../> 

.

 <animate begin="click; 0s" .../> 
L'animation démarre lorsque le document est chargé et en cliquant sur

. Tous les Ă©vĂ©nements ne sont pas pris en charge, mais la plupart des Ă©vĂ©nements liĂ©s Ă  la souris fonctionnent. Je ne les Ă©numĂ©rerai pas tous, les Ă©vĂ©nements disponibles peuvent ĂȘtre trouvĂ©s quelque part ici . De plus, personne n'a annulĂ© la mĂ©thode de piquer scientifique.

L'animation redémarre sans atteindre la fin, comment puis-je la réparer?

Je vais donner un exemple simple. Ici, l'animation commence par un clic. Si l'utilisateur n'appuie toujours pas, le démarrage automatique est fourni en 3 secondes

 <animate begin="click; 3s" dur="7s" .../> 

Mais il y a un problÚme: si l'utilisateur appuie avant le chronomÚtre automatique, puis lorsque 3 secondes se sont écoulées, l'animation redémarre et n'atteint jamais la fin. L'attribut restart dans la valeur whenNotActive viendra à la rescousse . Au total, il en a trois

  • always –
  • whenNotActive – ,
  • never –

 <animate begin="click; 3s" dur="7s" restart="whenNotActive" .../> 
, ,



, , , , . , , id begin , end , repeat

 <animate id="pop" begin="click" .../> <animate begin="pop.begin" .../> <animate begin="pop.end" .../> 

Si avec les deux premiers tout est clair, alors avec rĂ©pĂ©ter tout n'est pas si Ă©vident. Le nombre de rĂ©pĂ©titions est Ă©crit entre parenthĂšses, aprĂšs quoi vous devez dĂ©marrer l'animation (ce nombre ne peut pas ĂȘtre la derniĂšre rĂ©pĂ©tition)

 <animate id="flip" repeatCount="5" .../> <animate begin="flip.repeat(2)" .../> 
L'animation démarre aprÚs deux répétitions et pas toutes les deux répétitions

. Vous pouvez également spécifier un délai par rapport à l'événement. Par exemple, si je veux lire l'animation 2 secondes aprÚs le début d' une autre

 <animate id="another" .../> <animate begin="another.begin + 2s" .../> 

Ou lancez l'animation une seconde avant la fin d' une autre

 <animate begin="another.end - 1s" .../> 

Quoi d'autre peut commencer ...
Je voulais appeler cette section, mais il est plus correct de l'appeler "Que devrait-il pouvoir, mais pas?". Selon mes spĂ©cifications prĂ©fĂ©rĂ©es , begin devrait avoir deux autres valeurs qu'il devrait prendre. Le premier est accessKey , qui dĂ©marre l'animation en appuyant sur une touche spĂ©cifiĂ©e au format Unicode. La seconde est l' horloge murale , qui dĂ©termine le dĂ©but de l'animation en temps rĂ©el. Et lĂ , vous pouvez spĂ©cifier non seulement l'horloge, mais mĂȘme le mois et l'annĂ©e, en gĂ©nĂ©ral, un ensemble complet.

Malheureusement, aucun d'entre eux ne voulait travailler. Bien que la perte ne soit pas grande, car leur besoin est encore douteux

 <animate begin="accessKey(\u0077)" .../> <animate begin="wallclock(2019-04-09T19:56:00.0Z);" .../> 
Je ne sais pas quel est le problĂšme, peut-ĂȘtre que mon navigateur ne les prend pas en charge, ou peut-ĂȘtre autre chose ...

Puis-je interrompre l'animation?

Cela peut ĂȘtre fait avec l'attribut end . Dans son utilisation, il est identique pour commencer , vous pouvez Ă©galement spĂ©cifier l'heure, les Ă©vĂ©nements, etc. Comme vous pouvez le voir, ce n'est pas le premier (et pas le dernier) moyen d'interrompre l'animation, car il y a repeatDur , oĂč vous pouvez Ă©galement fixer la durĂ©e de l'animation. Et bienque vous puissiez Ă©galement spĂ©cifier l'heure directementĂ  la fin , ses caractĂ©ristiques distinctives sont la liaison d'Ă©vĂ©nements et la possibilitĂ© de spĂ©cifier une liste de valeurs.

Supposons que nous ayons un élément qui a un état de repos et d'activité. Le second est activé lorsque vous cliquez dessus. Et nous voulons interrompre l'animation restante avec le début de l'activité. Vous pouvez implémenter une idée similaire comme celle-ci

 <animate id="idle" end="action.begin" begin="0s" repeatCount="indefinite" .../> <animate id="action" begin="click" .../> 
.

end begin

, begin , end , , , . , , 
 ? .

, – . begin - enddĂ©finit une «rĂ©pĂ©tition». Et le temps entre la fin d'une «rĂ©pĂ©tition» et le dĂ©but de la suivante dĂ©termine le retard. Je les appelle des «rĂ©pĂ©titions» pour une raison, l'animation ne s'arrĂȘte pas et continue, mais est interrompue et recommence depuis le dĂ©but. Il s'avĂšre que nous pouvons ajuster sĂ©parĂ©ment la durĂ©e de chaque rĂ©pĂ©tition et dĂ©finir diffĂ©rents dĂ©lais aprĂšs chaque rĂ©pĂ©tition

 <animate dur="3s" begin="1s; 5s; 9s" end = "2s; 8s; 11s" .../> 
Dans l'exemple, l'animation comporte 3 «répétitions». Le premier commencera une seconde aprÚs le chargement du document et ne durera qu'une seconde sur trois. Puis un délai de 3 secondes, puis une animation complÚte de 3 secondes. Encore une fois, un retard, mais en 1 seconde. La derniÚre répétition sera interrompue aprÚs deux secondes d'animation.

Pouvez-vous quand mĂȘme interrompre l'animation d'une maniĂšre ou d'une autre?
Quelques attributs inutiles Ă  la tirelire
Keeneeee, il y a deux autres attributs - min et max . Comme son nom l'indique, min définit le minimum et max définit ladurée maximale. Tout d'abord, la durée de l'animation est calculée à l'aide des valeurs dur , repeatCount , repeatDur ,fin . Et aprÚs cela, la durée obtenue est ajustée aux images spécifiées par min et max . Tout est beau sur papier, voyons comment ça marche dans la pratique.

Avec max, tout est simple, c'est un autre attribut qui définit la limite supérieure. Si la durée calculée est inférieure à max , alors elle est ignorée, et si elle est plus longue, alors la durée de l'animation devient égale à max

 <animate dur="10s" repeatDur="7s" end="5s" max="4s" .../> 
Il sera interrompu pendant 4 secondes,

mais min a été moins chanceux. Si la durée d' animation calculée est supérieure à min , elle est ignorée, ce qui est logique. Cependant, si la durée calculée est inférieure à min , alors elle ... est parfois ignorée, et parfois non.
Pourquoi pourquoi?! Ce moment est trĂšs facile Ă  confondre, alors lisez attentivement.

Nous avons deux options lorsque la durée calculée est inférieure à min :

  1. Parce que l'animation elle-mĂȘme est terminĂ©e, c'est-Ă -dire dur * repeatCount < min

     <animate dur="2s" repeatCount="2" min="5s" .../> 
    Dans cette option, l'attribut min est simplement ignorĂ©, l'animation s'arrĂȘtera Ă  la quatriĂšme seconde
  2. repeatDur end .

    • repeatDur , , min , min

       <animate dur="1s" repeatCount ="indefinite" repeatDur="3s" end="5s" min="4s" .../> 
      repeatDur , min , 3
    • repeatDur , end min , end , min

       <animate dur="1s" repeatCount ="indefinite" end="2s" min="4s" .../> 
      4 , .. min end

En raison de l'abondance d'attributs qui interrompent l'animation, il y a beaucoup de confusion. En conséquence, il n'y a pas de grand sens en max et min , car une animation bien écrite élimine leur besoin.

Comment gĂ©rer les images clĂ©s et oĂč indiquer la fonction temporelle?

Pour ce faire, vous devez connaĂźtre les attributs keyTimes , keySplines , calcMode . AprĂšs avoir spĂ©cifiĂ© la liste en valeurs , nous dĂ©clarons les images clĂ©s, mais elles sont rĂ©parties uniformĂ©ment. GrĂące Ă  l'attribut keyTimes . , , . , (0 – 0%; 0,5 – 50%; 1 – 100%).

: 0 1, - , 0, 1, . , , keyTimes values .

 <animate values="15; 10; 45; 55; 50" keyTimes="0; 0.1; 0.6; 0.9; 1" .../> 

Par défaut, toutes les conversions se produisent de façon linéaire, pour changer cela, vous devez spécifier un mode différent dans calcMode . Et il n'y a pas beaucoup d'options:

  • linĂ©aire - valeur standard, aucune explication nĂ©cessaire
  • stimulĂ© - les intervalles de temps sont calculĂ©s de sorte que la vitesse entre les images clĂ©s soit constante
  • discret - l'animation bascule entre les images clĂ©s en sauts, sans interpolation
  • spline - on peut dire que c'est un mode de contrĂŽle manuel (Ă  ce sujet plus tard)

Malheureusement, ce sont toutes des fonctions intégrées, ici vous ne trouverez pas de facilité dans \ out comme dans CSS. Ces besoins devront donc satisfaire le régime que j'ai appelé "manuel".

Le plus difficile à comprendre est rythmé , je vais donc l'expliquer plus en détail. Pour commencer, voyez comment l'animation fonctionne en mode standard. L'animation dure 2 secondes et nous avons 3 images clés - initiale, intermédiaire, finale

 <animate dur="2s" values="100; 200; 150" .../> 

, , . 100, – 50, .. . , , . calcMode="paced" , .

 <animate dur="2s" values="100; 200; 150" calcMode="paced" .../> 

. , , – .

spline keySplines . 




Si spline dĂ©finit un mode manuel, l'attribut keySplines dĂ©finit les valeurs de ce mode. Évidemment, l'un ne fonctionne pas sans l'autre. Les valeurs dans keySplines sont dĂ©finies par une liste oĂč les coordonnĂ©es de deux points pour BĂ©zier cubique sont indiquĂ©es.

Plus sur la fonction cubique de Bézier
, . 4 0 1 : cubic-bezier(x1, y1, x2, y2). , .

cubic-bezier . , .

Le nombre de valeurs dans keySplines doit ĂȘtre infĂ©rieur de 1 aux valeurs . Cela est dĂ» au fait que nous indiquons des valeurs non pas pour les images clĂ©s, mais pour les intervalles entre elles.

 <animate values="100; 200; 150" keySplines=".25 .1 .25 1; 0 0 .58 1" calcMode="spline" .../> 
Les coordonnées des points de la fonction Bézier sont séparées par des espaces ou des virgules, et les valeurs de liste sont séparées par des points-virgules.

Le premier inconvénient, et le plus désagréable, est que vous ne pouvez pas définir une fonction de temps commune pour toutes les images clés, vous devrez dupliquer la fonction pour chaque image.
DeuxiÚmement - si vous souhaitez définir la fonction de temps pour les attributs de - à ou par , vous avez besoin d'une béquille: vous devrez définir keyTimes avec les valeurs "0; 1"

 <animate from="10" to="50" keyTimes="0; 1" keySplines=".25 .1 .25 1;" calcMode="spline" .../> 
from - to values ,

?

– , . , 
 , .

, : accumulate ( none ) sum

 <animate by="100" repeatCount="3" accumulate="sum".../> 

Il ne faut pas oublier que si vous utilisez des valeurs ou de - à , toutes les répétitions, sauf la premiÚre, se comporteront comme si additive = "somme" . Et accumuler est ignoré si un seul est spécifié .

Nous comprenons le morphing du contour

Maintenant que j'ai expliqué les bases, il est temps de passer à des choses vraiment cool et complexes. Je suis sûr que quelqu'un a ouvert cet article uniquement pour le plaisir de cette section.

Le morphing de chemin est une animation de l'attribut d de la balise de chemin , qui vous permet de crĂ©er l'effet de changer en douceur la forme de la forme. Actuellement, avec les outils intĂ©grĂ©s, cela ne peut ĂȘtre fait qu'Ă  l'aide de SMIL. Dansvaleurs indique la liste des valeurs de l'attribut d par laquelle passe l'Ă©lĂ©ment. Vous pouvez Ă©galement utiliser de - Ă  . En gĂ©nĂ©ral, la forme du contour ressemble Ă  ceci

 <animate attributeName="d" values=" 1;  2; ..." .../> 

:

– d , . , ( «» ). , « », «», - , .. ( ).

, , . , – , calcMode="discrete" . , . , .

, «». , . , , . Adobe Illustrator , . , , . , .

À l'heure actuelle, la seule solution au problĂšme est la conversion du «code tordu» dans l'application Web Shape Shifter . C'est l'option que j'utilise. En plus de corriger le code cassĂ©, Shape Shifter vous permet de voir le rĂ©sultat, d'ajouter Ă©ventuellement un autre type d'animation et d'exporter le rĂ©sultat dans un format pratique.

Ensuite, un tutoriel Ă©tape par Ă©tape oĂč je vous dirai comment crĂ©er une si belle animation

Apprenez-moi!
: SVG Adobe Illustrator, , Shape Shifter . CSS, SMIL .

. Illustrator. , . 200x200 .

, , . , , «». ,

. . « »

, . , , ,

. , , . , . SVG , . 


. , . SVG . ( Illustrator )

, , Illustrator <path> , <circle> . , . , , . - ( SVGO ), . .

d , )

 <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve"> <style type="text/css"> .st0{fill:#D38911;} .st1{fill:#87872B;} .st2{fill:#CEB629;} .st3{fill:none;stroke:#DD913E;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:12,200;} </style> <g id="Pulse"> <g> <path class="st0" d="M100,87c44.1,0,80,35.9,80,80s-35.9,80-80,80s-80-35.9-80-80S55.9,87,100,87 M100,82c-46.9,0-85,38.1-85,85 s38.1,85,85,85s85-38.1,85-85S146.9,82,100,82L100,82z"/> </g> </g> <g id="_x3F__1_"> <path id="side" class="st1" d="   "/> <path id="front" class="st2" d="   "/> </g> <g id="Particles"> <line class="st3" x1="80" y1="162.9" x2="42" y2="59.1"/> <line class="st3" x1="90.1" y1="148.8" x2="59.8" y2="28.8"/> <line class="st3" x1="107.9" y1="155.6" x2="124.9" y2="15.9"/> <line class="st3" x1="94.4" y1="160.4" x2="154.3" y2="7.2"/> <line class="st3" x1="119.3" y1="157" x2="159.2" y2="75.5"/> <line class="st3" x1="98" y1="169" x2="87.7" y2="10.7"/> <line class="st3" x1="80.4" y1="147.6" x2="63.2" y2="14.1"/> </g> </svg> 

 <?xml version="1.0" encoding="utf-8"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"> <style type="text/css"> #Pulse{fill: none; stroke: #D38911; stroke-width: 5;} #side{fill:#87872B;} #front{fill:#CEB629;} .particles{fill:none;stroke:#DD913E;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:12,200;} </style> <circle id="Pulse" cx="100" cy="167" r="85"/> <g id="Sign"> <path id="side" d="   "/> <path id="front" d="   "/> </g> <g id="Particles"> <line class="particles" x1="80" y1="162.9" x2="42" y2="59.1"/> <line class="particles" x1="90.1" y1="148.8" x2="59.8" y2="28.8"/> <line class="particles" x1="107.9" y1="155.6" x2="124.9" y2="15.9"/> <line class="particles" x1="94.4" y1="160.4" x2="154.3" y2="7.2"/> <line class="particles" x1="119.3" y1="157" x2="159.2" y2="75.5"/> <line class="particles" x1="98" y1="169" x2="87.7" y2="10.7"/> <line class="particles" x1="80.4" y1="147.6" x2="63.2" y2="14.1"/> </g> </svg> 
, . , ,

CSS , . . , . . CSS . :

 #Pulse{fill: none; stroke: #D38911; stroke-width: 5; transform: rotateX(80deg);} ._transformer{transform-box: fill-box; transform-origin: center;} 

, _transformer , , . «» <animateTransform> .

- : , Illustrator? 


– , . , . , <path> , .

, ! – , . , – . circle , . animate , 3

 <circle id="Pulse" class="_transformer" cx="100" cy="167" r="0"> <animate id="doPulse" attributeName="r" values="0;85;" dur=".8s" begin="Sign.click" calcMode="spline" keySplines="0,0,.58,1"/> <animate attributeName="stroke-width" values="5;12;" dur=".8s" begin="doPulse.begin"/> <animate attributeName="opacity" values="0.5;1;1;0" keyTimes="0;0.2;0.5;1" dur=".8s" begin="doPulse.begin"/> </circle> 
, CSS


, . : , , . - :


. - , . ,

 <linearGradient id="light-gradient"> <stop offset="0%" stop-color="#ffffff00"/> <stop offset="10%" stop-color="#FFF"/> <stop offset="90%" stop-color="#FFF"/> <stop offset="100%" stop-color="#ffffff00"/> </linearGradient> <mask id="light-mask"> <rect y="0" x="90" class="_transformer" width="20" height="220" fill="url(#light-gradient)" /> </mask> 

, . , , . , <use> , <path> <defs>

 <defs> <path id="question" d="     "/> </defs> ... <use id="front" href="#question"/> <use id="light" href="#question" mask="url(#light-mask)"/> 



, , . . ,

 #light-mask rect{ animation: highlight 4s infinite; } @keyframes highlight { 0% { transform: translate(-100px,0) rotate(-50deg); } 30% { transform: translate(100px,0) rotate(-50deg); } 100% { transform: translate(100px,0) rotate(-50deg); } } 

. . CSS , SMIL.

, . — , . ,

 <g id="Sign" class="_transformer"> <path id="side" d="     "/> <use id="front" href="#question"/> <use id="light" href="#question" mask="url(#light-mask)"/> <animateTransform id="idle" attributeName="transform" type="translate" values="0,0;0,-5;0,0" dur="6s" begin="0s; jump.end" end="click" repeatCount="indefinite" /> <animateTransform id="jump" attributeName="transform" type="translate" calMode="spline" values="0,0;0,10;0,-35;0,5;0,0" keyTimes="0;0.1;0.35;0.6;1" keySpline="0,0,.58,1;0,0,.58,1;.42,0,1,1;0,0,.58,1" dur="1s" begin="idle.end" /> </g> 
,

, , . , additive="sum"

 <animateTransform attributeName="transform" type="scale" additive="sum" values="1,1;1.1,0.8;0.9,1.2;1.1,0.8;1,1" keyTimes="0;0.1;0.35;0.7;1" dur="1s" begin="idle.end" /> 

, , . Résultat:

.
? - , , . stroke-dashoffset , . ,

- . ,

 <g id="Particles"> ... </g> <g id="Sign" class="_transformer"> ... </g> 

, ,

 .particles{ opacity:.7; stroke-width:0; ... } 

, . ,

 @keyframes sparks { 0% { stroke-dasharray: 20,200; stroke-width: 5px; } 100% { stroke-dasharray: 4,200; stroke-width: 0px; stroke-dashoffset: -180; } } 

, . , , «». : CSS , , . SMIL, 3 , , 7. , , 


– , - , . CSS, SMIL.

Particles_active ,

 .Particles_active .particles{ animation: sparks .7s; } 

<set> , , ( set )

 <g id="Particles"> <line class="particles" x1="80" y1="162.9" x2="42" y2="59.1"/> ... <line class="particles" x1="80.4" y1="147.6" x2="63.2" y2="14.1"/> <set attributeName="class" to="Particles_active" dur=".7s" begin="jump.begin + .5s"/> </g> 

:

  • ;
  • ;
  • , , , , , ;
  • ;


. , , . 3D , . , , .

Adobe Illustrator, . , . - , . ,

d .


, . Shape Shifter.

, , . , Shape Shifter

, SVG . Shape Shifter , «» SVG. Illustrator. , . , pathData


, , toValue. . «»

. ,

, , Shape Shifter , , , , . , toValue fromValue .

. ,

 <animate attributeName="d" calMode="spline" values="  1;  2;  1" dur="5s" keySpline=".42,0,.58,1;.42,0,.58,1" repeatCount="indefinite" /> 

1 – , 2 –


. Codepen.

, SVG – , . , ,

<set>


La balise set est une version abrégée d' animation , sauf qu'elle ne peut pas interpoler. Il est utilisé pour changer instantanément l'attribut pendant une certaine période de temps, c'est-à-dire fonctionne sur le principe d'un interrupteur. Par conséquent, il ignore les attributs associés à l'interpolation et ne prend pas en charge les animations cumulatives ou relatives. La valeur est définie exclusivement à l'aide de l' attribut to , les valeurs , from , by sont ignorées.

 <set attributeName="cx" to="200" begin="click" dur="5s" .../> 
L'élément change de position en cliquant, aprÚs 5 secondes, il revient à sa position d'origine.

Si vous ne spécifiez pas l'attribut dur , l'élément restera dans cet état jusqu'à ce que le document soit rechargé. Sinon, c'est similaire à animer .

<animateTransform>


Comme son nom l'indique, il est utilisé pour appliquer diverses transformations à un élément. Tous les types de transformations sont identiques aux transformations CSS. Avec l'utilisation simultanée des transformations CSS et SMIL, elles se remplaceront mutuellement, il est donc préférable d'utiliser une chose ou de veiller à ce qu'elles ne se chevauchent pas.

Comment transformer?

L'attribut animé est transform . Le mode de transformation est indiqué dans l'attribut type et prend 4 types de valeurs - mouvement, rotation, mise à l'échelle, décalage le long des axes.

translate - dĂ©placer un Ă©lĂ©ment par rapport Ă  sa position actuelle. Il prend un dĂ©calage au format [x, y] , oĂč y est un paramĂštre facultatif

 <animateTransform attributeName="transform" type="translate" from="0, -10" to="0, 10" .../> 
Déplace l'élément le long de l'axe Y

rotation - fait pivoter l'élément par rapport au centre de rotation. Il prend l'angle de rotation et les coordonnées du centre de rotation [deg, x, y] comme valeurs, les coordonnées du centre sont optionnelles. Par défaut, le centre de rotation se trouve dans le coin supérieur gauche du document SVG

 <animateTransform attributeName="transform" type="rotate" from="0, 150, 150" to="45, 150, 150" .../> 
Faire pivoter de 45 degrés autour d'un point avec les coordonnées 150, 150

De plus, le centre de rotation peut ĂȘtre modifiĂ© Ă  l'aide de la propriĂ©tĂ© CSS de l' origine de la transformation , oĂč en plus des coordonnĂ©es, vous pouvez spĂ©cifier des pourcentages. Par dĂ©faut, les pourcentages sont calculĂ©s par la taille de l'ensemble du document, de sorte que les pourcentages soient calculĂ©s par rapport Ă  l'Ă©lĂ©ment, vous devez dĂ©finir la propriĂ©tĂ© CSS transform-box avec la valeur fill-box .

scale - met à l'échelle l'élément. Comme valeurs, il prend des nombres à virgule flottante au format [échelle] pour les deux axes, ou séparément pour chaque axe [scaleX, scaleY] (1 correspond à la taille normale de l'élément). Si vous ne changez pas la boßte de transformationComme je l'ai mentionné ci-dessus, l'élément est mis à l'échelle par rapport à l'ensemble du document. L'espace vide autour de l'élément change également avec lui, il semble donc visuellement que l'élément est décalé sur le cÎté

 <animateTransform attributeName="transform" type="scale" from="1, 1" to="2, 1" .../> 
Étire un Ă©lĂ©ment le long de l'axe X

skewX ou skewY - dĂ©cale un Ă©lĂ©ment par rapport Ă  l'axe. La valeur prend l'angle d'inclinaison [deg] . Par dĂ©faut, le centre de dĂ©calage est le coin supĂ©rieur gauche, donc la mĂȘme blague avec transform-box et transform-origin fonctionne ici commedans d'autres transformations

 <animateTransform attributeName="transform" type="skewX" from="0" to="45" .../> <animateTransform attributeName="transform" type="skewY" from="90" to="0" .../> 
L'un décale le long de X, l'autre le long de Y

Sommation et redéfinition des transformations

Dans animateTransform , vous pouvez toujours faire des animations cumulatives et relatives, mais ici l'attribut additif se comporte différemment. Dans la valeur de replace, la transformation remplace toutes les précédentes. Dans la valeur somme , latransformation est additionnée à la précédente

 <rect transform="skewY(115)" ...> <animateTransform type="translate" from="-10" to="10" additive="replace" .../> <animateTransform type="rotate" from="0" to="90" additive="sum" .../> </rect> 
Dans cet exemple, le décalage du rectangle sera redéfini pour se déplacer et pivoter

<animateMotion>


, . animateMotion animate 3 – path , rotate , keyPoints .



– from , to , by values , path <mpath> . .

from , to, en indiquant les coordonnĂ©es des points, les mĂȘmes valeurs , mais dĂ©jĂ  sous forme de liste

 <animateMotion from="0,0" to="50,100" .../> <animateMotion values="0,0; 0,100; 100,100; 0,0" .../> 

L'effet de cette méthode est comparable à la transformation habituelle du déplacement. Un élément se déplace rectiligne d'un point à un autre. Et ici, tout comme dans animateTransform , les coordonnées sont relatives . Le point 0,0 n'indique pas le coin supérieur gauche du document, mais la position actuelle de l'élément cible. Cette caractéristique est présente dans d'autres méthodes de détermination de la trajectoire.

L'attribut path spécifie un ensemble de commandes, comme pour l'attribut d . Si dans l'attribut d les commandes sont interprétées comme le contour de la figure, alors dans l'attribut path elles sont la ligne le long de laquelle l'élément se déplacera. Les coordonnées des points sont également relatives, donc le chemin commence au point 0,0

 <animateMotion path="M 0 0 c 3.4 -6.8 27.8 -54.2 56 -37.7 C 73.3 -27.5 89.6 -5.1 81.9 5.9 c -5.8 8.3 -24.7 8.7 -45.4 -0.4" .../> 

Ce chemin décrit une telle courbe


La derniĂšre façon consiste Ă  utiliser un Ă©lĂ©ment <path> tiers comme chemin . Pour ce faire, vous devez spĂ©cifier un lien vers cet Ă©lĂ©ment dans la balise <mpath> , et la balise elle-mĂȘme doit ĂȘtre placĂ©e dans <animateMotion> . Cette option a la mĂȘme fonctionnalitĂ© avec des coordonnĂ©es relatives. À la base, cette mĂ©thode «copie» la valeur de l'attribut d de l'Ă©lĂ©ment dans l'attribut <path>

 <path id="movement" .../> ... <animateMotion ...> <mpath href="#movement"/> </animateMotion> 
L'Ă©lĂ©ment qui dĂ©finit le chemin d'accĂšs peut mĂȘme ne pas apparaĂźtre dans le document. Vous pouvez simplement le dĂ©finir dans <defs>

Faire pivoter un élément par rapport à la trajectoire.

Il est possible de faire tourner l'élément dans le sens du mouvement en utilisant l'attribut de rotation . Il accepte 3 types de valeurs: auto , auto-reverse et un nombre indiquant la rotation en degrés

 <animateMotion rotate="auto" .../> 

Par défaut, la rotation est de 0. Toute valeur numérique capture l'angle tout au long de l'animation. Les modes automatiques auto et auto-reverse modifient l'angle de rotation de l'élément, respectivement, tangent à la trajectoire. Et ils diffÚrent dans le sens de cette tangente. En auto, il est dirigé vers l'avant, tandis qu'en auto-reverse , il est dirigé vers l'arriÚre.


Comment contrĂŽler le mouvement le long du chemin?

La trajectoire est une courbe qui a un dĂ©but et une fin, ces points sont dĂ©signĂ©s par les nombres 0 et 1, respectivement. Toute position sur la courbe peut ĂȘtre dĂ©terminĂ©e par un nombre dans cette plage. En rĂ©pertoriant les points dans l'attribut keyPoints , vous pouvez dĂ©finir tout type de mouvement le long du chemin. Mais cela ne suffit pas pour contrĂŽler le mouvement, pour cela vous avez besoin de tout un systĂšme d'attributs.

Vous devez d'abord définir calcMode sur linéaire ou spline . Contrairement à d'autres balises, animateMotion par défaut est stimulé (pour une raison quelconque, l'animation ne veut pas fonctionner dans ce mode). Vous devez également spécifier un attribut.keyTimes . Ce n'est qu'en suivant ces étapes que l'animation fonctionnera comme il se doit

 <animateMotion keyPoints="0.5; 1; 0; 0.5" keyTimes="0; 0.25; 0.75; 1" calcMode="linear" .../> 
Dans l'exemple, l'animation commence au milieu du chemin, se déplace à la fin, puis au début, et termine à nouveau le mouvement au milieu

PS

En traitant avec animateMotion , je suis tombĂ© sur des informations selon lesquelles la mĂȘme chose peut, comme, ĂȘtre faite sur CSS. Mais Ă  la fin de cet article, je n'avais ni la force ni l'envie de traiter cela. Pour les passionnĂ©s, je laisse juste un lien vers la documentation.


Remerciements spéciaux


Bhudh pour l'énorme travail de correction de l'article

Source: https://habr.com/ru/post/fr450924/


All Articles