PhōsPixel

Accessibilité et modèle de code de base pour mes SVG

Lectures et recherches pour créer un code de base pour des SVG dit accessible (aria-label-like)

Avec comme objectif de me créer un modèle de base pour un fichier SVG, j’ai lu les articles Accessible SVGs et Accessible SVGs: Perfect Patterns For Screen Reader Users, qui m’ont davantage embrouillé qu’éclairci ! C’est assez compliqué et j’en conclus que ça dépend beaucoup du contexte d’utilisation :

En gros, j’en retiens que je regarderai à nouveau lorsque j’utiliserai des SVG dans un autre contexte, ou que je serai plus avancée, mais je vais inclure un <title>, lorsque possible, car cela agit comme un aria-lable pour les agents.

Des formes SVG

SVG 1.1 vs SVG 2

Le SVG 2 semble presque adopté par les développeurs et plusieurs articles semblent promouvoir l’adhésion du SVG a utiliser le plus possible les éléments du CSS lorsque qu’ils les ont en commun, tel le <a>. J’avais déjà commencé à adopter cette posture, mauvaise pratique, ou du moins, attention avec certains éléments!

Le SVG 2 n’est toujours qu’en recommendation au W3C. Je retiens d’ailleurs que l’inclusion de plus d’une balise <title> est considéré comme un élément à risque, de même que la description <desc>, alors je l’ai enlevé de mon modèle, contrairement à ce que suggèrais Migliorisi dans son texte sur l’accessibilité, et ce même si c’était buggué à l’époque de son article (Chrome et Firefox).

Éléments dit à risque par le W3C

En plus de plusieurs balises <title> et de l’utilisation du <desc>, les autres éléments considérés à risque par le W3C, car non supporté correctement par les navigateurs sont :

Nested links ?! <a> olalala!

Nested links! Et dire que la base de ma recherche actuelle s’est activé autour de la découverte qu’un SVG peut utilisé le <a>, article sur CSS-TRICKS, et que j’en ai déjà mis amplement (puis retirés depuis).

<a> ou pas ?

Dans l’Appendix M: Attribute Index du SVG 1.1 (Second Edition) – publié le 16 août 2011 par W3C, le <a> n’est pas là. Mais comme il peut être dans du XML, tout cela devient très confondant, de plus que les développeurs semblent largement avoir adopté le SVG 2 même si le W3C ne le reconnait toujours pas. Le groupe du W3C s’occupant du SVG 2 a réécrit un draft en mars 2023. Plusieurs problématiques sont soulevés par rapport au DOM.

Pour le <a>, le problème principal, tel que résumé par MDN :

SVG’s <a> element is a container, which means you can create a link around text (like in HTML) but also around any shape.
[…]
Warning: Since this element shares its tag name with HTML’s <a> element, selecting a with CSS or querySelector may apply to the wrong kind of element. Try the @namespace rule to distinguish the two.

Que faire ?

@namespace est une règle CSS et elle nes semble pas fonctionner si utilisée dans un balise <style> à l’intérieur même du SVG 🙂 Je crois aussi que ça dépend du contexte d’utilisation et de comment est codé un SVG. Ainsi, en donnant un namespace xmlns, des ID et classes uniques, et en continuant d’utilisé le xlink, même si celui-ci sera déprécié en SVG 2 pour se rapprocher du HTML 5, il n’y a pas de raison pour qu’un <a> soit visé, sinon je l’aurais vécu ici sur mon site, comme j’ai constaté avec d’autres éléments et script alors que je les intégrais. Toujours est-il que je vais éviter de mettre des <a> lorsque ce n’est pas nécessaire !

Nomenclature personnalisée

Ayant expérimenté plusieurs problèmes de contamination de code, j’ai dû déterminer un système personnalisé pour nommer mes classes et id. Le problème étant que le namespace ne fait pas en sorte qu’une classe dans une balise style s’appliquera qu’au dit SVG si un autre SVG avec le même nom de classe se retrouve sur une même page HTML. Et, c’est encore pire avec un script, surtout s’il vise une balise générique tel <path> ou <circle>!

Mon système pour nommer classes et ID

nom-itération-jjmmaa

Ainsi, en terminant avec une date, il sera impossible de contaminer quoique ce soit, du moins, les chances sont bien minces.

Base de code pour un SVG XML

Après avoir observé plusieurs SVG sur CodePen et aussi parce que SVG OMG retire l’ouverture <?xml suivi de la version, j’ai décidé de ne plus en ajouter après l’optimisation du code et de me fier à SVG OMG qui semble vraiment faire office de gourou dans le domaine.

<?xml version='1.0' encoding='UTF-8'?>
<svg version="1.1" id="nom-itération-jjmmaa" xmlns='http://www.w3.org/2000/svg'
      xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
      viewBox="0 0 1000 1000" xml:space="preserve">
      
   <title>Titre</title>

      <style>
            /* STYLES DE PRESENTATION */
            /* DANS LA BALISE STYLE OU INLINE SI NON GLOBAL */
            #nom-iteration-jjmmaa {}
            .nom-iteration-jjmmaa {}
      </style>

      <!-- DEFS pour définir des propriétés SVG-->
      <defs>
            <linearGradient id="degrade-1-200224">
                  <stop offset="0%" stop-color="#f8ED34" />
                  <stop offset="50%" stop-color="#FF3966" />
                  <stop offset="100%" stop-color="#33207f" />
            </linearGradient>
      </defs>

      <!-- LES ÉLÉMENTS DU OU DES SVG-->

      <path />

      <!-- SCRIPT TEMPORAIRE POUR CONNAITRE LONGUEUR-->
      <script>
        let chemin = document.getElementById('nom-iteration--jmmaa').getTotalLength();
        console.log(chemin);
      </script>
</svg>

Exploration de l’élément fePointLight et des balises script et style pour une interactivité avec un curseur personnalisé

Tester l’impact du namespace

Malheureusement <style> et <script> ne s’appliquent pas qu’à l’intérieur d’un SVG une fois avoir déclaré xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink". À noter aussi que le xlink sera abandonné avec le SVG 2.

Ce SVG montre bien qu’en visant simplement <svg> par script, de même qu’en utilisant des classes qui se retrouveront ailleurs, tout se contamine et plus rien ne fonctionne comme prévu!

Curseur + fePointLight #1 Contrôle toutes les lumières

Contrôler les lumières avec le curseur personnalisé

Je suis ravie que cet essai ait fonctionné! Un svg qui change le curseur de l’utilisateur, c’est génial! Cela permet vraiment de penser le dessin SVG comme un petit programme autonome, portable et réutilisable, en autant qu’on ne contamine pas tout avec la façon de le programmer!

Ainsi, pour les exemple qui suivent, les classes et ID sont uniques et le script JS s’adresse à eux et non pas aux balises directement.

Curseur + fePointLight #2 Contrôle chacune des lumières Curseur + fePointLight #3 Contrôle les lumières

Pour les textes, j’ai utilisé la balise <text> propre aux SVG, ce n’est pas une inclusion HTML avec <foreignObject>, que j’ai découver plus tard. <text> est toujours valable, simple et direct.

Source d’inspiration

L’article de MDN sur le filtre SVG de lumière <feDiffuseLighting> a été le point de départ de mes essais pour contrôler <fePointLight>.

No Light fePointLight feDistantLight feSpotLight

La fonction getTotalLength() + base dans Illustrator + animation et modifs dans un éditeur de code

Histoire

Formes: mon premier SVG animé

Dans le cours Udemy Learn SVG Animation – With HTML, CSS & Javascript, Sam propose cette méthode :

J’ai donc essayé CodePen pour la première fois, ça m’a plus d’obtenir des résultats en direct dans le navigateur et de voir le code bien divisé en trois boîtes.

Création des animations dans un éditeur de code

Confusion avec la fonction getTotalLength();

À partir de ce moment, la formation, qui date de 2017 ne fonctionne plus! Il y a bien d’autre cours plus récent sur Udemy, j’ai ai un autre d’ailleurs, mais j’avais choisi de débuter avec celle de Sam de par sa courte durée et la qualité des animations proposées.

Il est possible, par essais-erreur, de finir par deviner la longueur d’un trait (path) mais avec un dessin plus complexe qu’un carré ou un octogone, c’est ardu et imprécis. getTotalLenght() sert justement à calculer cette longueur. Sam utilise querySelector pour récupérer la classe et le retour dans la console dit que getTotalLenght() is not a function 🙁

Je me suis donc mise à chercher de quelle manière nous pouvons obtenir cette donnée, aujourd’hui, en 2023! Après être tombée sur une dizaine d’articles et de discussions sur stackverflow, Github, Reddit et Medium de personnes se plaignant que cette fonction ne fonctionne plus et a été retirée (depricated) je finis par tomber sur un package datant d’il y a trois mois, à installer avec node, svg-path-properties.

Je recommence donc tout dans VS Code, délaissant ainsi CodePen. Le package fonctionne en effet! J’obtiens bien la longueur du trait dans la console et je peux continuer d’animer le logo, tout en découvrant avec joie que l’extension SVG anime mon code directement dans VS Code!

Quelque chose me chicote quand même. Je trouve que le processus de création SVG devient d’une lourdeur avec le package de Node et quelque chose me dit que ça n’a pas de bon sens. Pourtant, je ne trouve aucune autre discussion sur le sujet. Je décide donc de chercher dans CodePen et tombe sur l’animation SVG toute simple d’un carré, d’une personne démontrant la fonction… getTotalLenght()!

getTotalLenght() fonctionne toujours mais avec un id et getElementById !

Je peux enfin continuer mais je décide de rester dans VS Code et je ne retourne pas dans CodePen. Je m’amuse enfin à modifier couleur et animations à mon goût.

Code final de mon preview SVG animé dans VS code. Remarquez que j’ai déclaré contexte xmlns et un titre.

<svg xmlns="http://www.w3.org/2000/logo-sam" viewBox="0 0 300 300">
  <title>Formes: mon premier SVG animé</title>
  <style>
    @keyframes animer-st3-sam {
      0% {
        transform: rotate(360deg)
      }
      to {
        transform: rotate(0deg)
      }
    }

    @keyframes dessine-octogone-sam {
      0% {
        stroke-dashoffset: -665;
        transform: rotate(360deg)
      }
      to {
        stroke-dashoffset: 0;
        transform: rotate(0deg)
      }
    }

    @keyframes dessine-carre-sam {
      0% {
        stroke-dashoffset: -894;
        transform: rotate(0deg)
      }
      to {
        stroke-dashoffset: 0;
        transform: rotate(720deg)
      }
    }

    @keyframes animer-cercle-sam {
      0% {
        stroke-dashoffset: -665;
        transform: rotate(360deg) scale(.6)
      }
      50% {
        transform: rotate(0deg) scale(1.2)
      }
      to {
        stroke-dashoffset: 0;
        transform: rotate(0deg) scale(1)
      }
    }
  </style>
 
 <circle cx="140" cy="152" r="85"
    style="fill:#17bebb;animation:animer-cercle-sam 2s infinite cubic-bezier(.2,.97,.83,.7);transform-origin:50% 50%;transform:scale(.6)" />
  <path d="M195.63 56.17H84.88L29.5 152.09 84.88 248h110.75l55.38-95.91z"
    style="fill:none;stroke:#4b1d3f;stroke-width:2;stroke-miterlimit:10;stroke-dasharray:665;stroke-dashoffset:-665;animation:dessine-octogone-sam 2s infinite cubic-bezier(.2,.97,.8,1.18);transform-origin:50% 50%" />
  <path d="M23 45h233v214H23z"
    style="fill:none;stroke:#0e7c7b;stroke-width:2;stroke-miterlimit:10;stroke-dasharray:894;stroke-dashoffset:-894;animation:dessine-carre-sam 2s infinite cubic-bezier(.2,.97,.8,1.18);transform-origin:50% 50%" />
  <path
    d="M85.36 151.07v8.36h-3.08v8.13H73v-19.34c0-3.64 1.12-6.65 3.37-9.03 2.25-2.38 5.07-3.57 8.48-3.57 3.76 0 6.9 1.62 9.43 4.86l-7.61 5.55c-.43-1.19-1.18-1.78-2.26-1.78-1.43 0-2.15.99-2.15 2.97v3.86h3.1zm23.58-15.46c4.42 0 8.2 1.61 11.36 4.82s4.74 7.06 4.74 11.53c0 4.55-1.59 8.42-4.77 11.6-3.18 3.18-7.05 4.77-11.6 4.77-4.52 0-8.38-1.6-11.58-4.8-3.2-3.2-4.8-7.06-4.8-11.58 0-4.57 1.61-8.43 4.83-11.6 3.22-3.16 7.16-4.74 11.82-4.74zm-.28 9.18c-1.9 0-3.53.7-4.86 2.1-1.34 1.4-2.01 3.09-2.01 5.07 0 1.98.67 3.67 2.02 5.07s2.97 2.1 4.85 2.1c1.92 0 3.54-.7 4.88-2.09 1.33-1.39 2-3.09 2-5.08 0-1.99-.67-3.69-2-5.08-1.34-1.39-2.96-2.09-4.88-2.09zm29.01-.02v22.79h-9.27v-31.18h11.9c3.62 0 6.43.9 8.43 2.7 2.22 2.01 3.33 4.56 3.33 7.65 0 3.15-1.38 5.81-4.13 7.97l5.34 12.86h-9.73l-4.5-10.05v-8.02h.73c1.95 0 2.92-.84 2.92-2.51 0-1.48-1.13-2.22-3.38-2.22h-1.64zm18.07 22.79v-22.47c0-2.79.85-5.06 2.53-6.83 1.69-1.77 3.88-2.65 6.58-2.65 3.2 0 5.66 1.47 7.38 4.41 1.05-1.58 2.18-2.71 3.38-3.39 1.2-.68 2.69-1.02 4.45-1.02 2.8 0 4.95.88 6.44 2.65 1.49 1.77 2.24 4.31 2.24 7.63v21.67h-9.27v-20.28c0-1-.08-1.67-.24-2-.16-.33-.48-.49-.97-.49-.91 0-1.37.78-1.37 2.33v20.44h-9.27v-20.28c0-.99-.08-1.65-.25-1.99-.17-.33-.49-.5-.98-.5-.91 0-1.37.83-1.37 2.49v20.28h-9.28zm53.24-19.05v6.94h-6.05c-.82 0-1.4.12-1.75.37s-.51.65-.51 1.23c0 .65.17 1.08.52 1.29.35.21 1.07.31 2.15.31h6.24v8.91h-7.29c-3.43 0-6.04-.82-7.86-2.46-1.81-1.64-2.72-4-2.72-7.09V145.8c0-2.98.86-5.3 2.57-6.94 1.71-1.64 4.12-2.47 7.23-2.47h8.06v8.95h-5.91c-1.6 0-2.4.52-2.4 1.55 0 .61.19 1.03.57 1.27.38.24 1.06.35 2.03.35h5.12zm20.56-12.26v8.88c-.67-.23-1.19-.34-1.55-.34-.7 0-1.3.26-1.8.78s-.75 1.14-.75 1.87c0 .62.27 1.42.82 2.38l.71 1.23c1.28 2.22 1.92 4.37 1.92 6.44 0 3.03-1.08 5.6-3.23 7.7-2.16 2.1-4.78 3.15-7.89 3.15-1.49 0-2.97-.34-4.43-1.03v-9.02c.88.56 1.67.85 2.35.85.81 0 1.48-.23 2.02-.7s.81-1.05.81-1.75c0-.46-.43-1.45-1.3-2.99-1.39-2.44-2.08-4.87-2.08-7.31 0-2.94 1.05-5.47 3.14-7.59s4.59-3.19 7.5-3.19c1.27 0 2.52.21 3.76.64z"
    style="fill:#d4f4dd;transform-origin:50% 50%;animation:animer-st3-sam 3s infinite cubic-bezier(.2,.97,.83,.7)" />
</svg>

Outils pour coder et optimiser des SVG

J’ai débuté le cours Learn SVG Animation – With HTML, CSS & Javascript de Code With Sam sur Udemy. Il suggère d’optimer le code avec SVG OMG. Je prends donc le code du SVG avec grain (image PNG) créé pour l’article précédent dans Adobe Illustrator et je le colle dans l’application.

Optimiser avec SVG OMG

On remarque que l’app retire d’emblée le commentaire <!-- Generator: Adobe Illustrator 28.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> du code.

Recommendation d’optimisation de Code With Sam

Résultats de l’optimisation

Malgré l’image PNG, ce SVG avec grain matricielle n’est pas bien lourd à la base : 21.41k. Grâce à SVG OMG, il a perdu 0.25k. C’est quand même bien!

Deuxième test d’optimisation

J’ai voulu procéder à un 2e test avec un code moins long, sans <image>, afin de mieux visualiser les différentes options de l’app. J’ai choisi le code avec le script JS pour aussi voir comment ce sera traiter. Le code devient beaucoup plus concis que celui très visuel et détaillé créé par chatGPT.

Je remarque aussi que SVG OMG supprime la déclaration : <?xml version="1.0" encoding="UTF-8"?>. Après recherches, SVG OMG semble très utilisé, j’en conclus que la déclaration n’est pas obligatoire mais il faut le namespace xmlns="http://www.w3.org/2000/svg".

Code optimisé
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">

  <path fill="#fc0" onclick="alert('Salut à toi!')" 
   d="m100 10 30 80h80l-60 40 20 80-70-40-70 40 20-80-60-40h80z"/>
  <circle cx="80" cy="40" r="5"/>
  <circle cx="90" cy="30" r="5"/>
  <circle cx="100" cy="20" r="5"/>

  <script type="text/javascript">
    function showAlert() { alert(&apos;Salut à toi!&apos;); }
  </script>
</svg>
Code original
 <?xml version="1.0" encoding="UTF-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  
      viewBox="0 0 200 200">
 <title>Un script JS dans une balise svg</title>

      <!-- Étoile -->
      <polygon
        points="100,10 130,90 210,90 150,130 170,210 100,170 30,
                210 50,130 -10,90 70,90"
        fill="#ffcc00"
        onclick="alert('Salut à toi!')"
      />

      <!-- Notes de musique pour représenter le chant -->
      <circle cx="80" cy="40" r="5" fill="#000" />
      <circle cx="90" cy="30" r="5" fill="#000" />
      <circle cx="100" cy="20" r="5" fill="#000" />

      <!-- Script JavaScript -->
      <script type="text/javascript">
        function showAlert() { alert('Salut à toi!'); }
      </script>
    </svg>

Extension SVG pour VS Code

Un script dans un SVG

J’ai installé l’extensions SVG pour VS Code. Elle aide avec de l’auto-completion, en plus de formater et permettre de visualiser les images. Cela m’a permi de modifier les coordonnées du code produit par chatGPT pour le test avec balise script. L’étoile coupé avec la boite d’alerte n’est plus coupé dans son viewBox 🙂

Capture d’écran d’un SVG dans VS Code avec l’extension SVG indiquant le poids et montrant l’image générée

Un PNG dans un SVG ? Le grain créé dans Adobe Illustrator, dimensions et le viewBox

Un PNG dans un SVG

Les objectifs de ce premier test :

WordPress est lent et gèle si je colle tout le code en tant que texte pour le montrer! Le code est très long. Je ne met que le début pour discussion et analyse.

<?xml version="1.1" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"  width="111"
 height="129"
<!-- Generator: Adobe Illustrator 28.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 viewBox="0 0 111 129" style="enable-background:new 0 0 111 129;" xml:space="preserve">

<style type="text/css">
	.st0{fill:#F7931E;}
</style>

<g id="sun">
	<path class="st0" d="M83.42,20.14c18.99,14.22,28.43,47.56,21.09,74.48s-28.68,37.21-47.66,22.99S0.61,46.46,7.94,19.54
		S64.44,5.92,83.42,20.14z"/>
<g>
		
<image style="overflow:visible;" width="172" height="192" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANS

Notes

XMLNS

Grain

Dimension

viewBox

Extraits de MDN sur l’attribut viewBox

La valeur de l’attribut viewBox est une liste de quatre nombres min-xmin-ywidth et height, séparés par des espaces ou/et des virgules. Ces nombres spécifient un rectangle dans l’espace utilisateur, qui doit correspondre aux coins du viewport établis par l’élément SVG donné, ceci en prenant en compte l’attribut preserveAspectRatio.

Les valeurs négatives de width et height ne sont pas autorisées et une valeur à zéro désactive le rendu de l’élément. Pourtant, même si les valeur négatives ne sont pas autorisées, elles fonctionnent et permettent de repositionner le dessin dans son cadre. Étrange.

C’est donc comme un viewport pour le html, avec un système de coordonnés et ce n’est pas un width et un height puisque ça se veut scalable, donc c’est un min-width et un min-height ! Ainsi, pour des dimensions fixes, il faut soit carrément inclure width et height suite à l’ouverture <svg> ou sinon le contrôler par une feuille de style CSS externe.

Les éléments suivants peuvent utiliser l’attribut viewBox mais attention aux <images>, c’est matricielle!

L’élément <pattern> wow! À essayer!

Adobe Illustrator et sauvegarde SVG

La boite de dialogue comprend plusieurs options. Toutefois je n’ai pas saisi pourquoi la sauvegarde d’un même SVG avec des options différentes concernant CSS Properties donne toujours le même code à l’exception d’une fois. Je me demande si ça fonctionne correctement. Il faudrait tester davantage peut-être mais ayant par la suite découvert SVG OMG, un optimiseur de code, cela dépendra des besoins.

La boite de dialogue d’Adobe Illustrator

Il sera intéressant de comparer avec Figma. De plus, étant donné que l’objectif est aussi de produire des animations, je compte débuter mon apprentissage de Figma plus rapidement que prévu et mettre AI de côté, pour le moment.

SVG ? Semaine 1 : notes de lectures MDN + XML + CSS intégré + JS + WP Gutenberg

MDN Web Docs

Documentation sur les SVG

D’une certaine façon, SVG est aux graphiques ce que HTML est au texte.
Balise style dans balise svg

Les éléments SVG

Documentation des éléments sur MDN

Surprise totale que de constater que le premier éléments est <a> ! Aussi simple que cela. C’est peut-être le temps de s’informer sur les différences entre le XML et HTML.

XML ?

Discussion avec chatGPT 3.5 sur le XML et le HTML (et contexte SVG)

XML en bref :

Il est intéressant de penser le SVG comme un média portable avec toutes ses propriétés. Peut-on y inclure aussi une balise <script> enfant de <svg>? Continuez de lire!

SVG, interractivité et accessibilité

Mouse over pour voir !

chatGPT 3.5 pense que c’est un oiseau. Et et moi j’ai ajouté un pseudo élément

Les éléments SVG peuvent être interactifs en utilisant une balise <style> et des événements JavaScript tels que onclick, onmouseover, etc. De plus, en fournissant des descriptions textuelles appropriées à l’aide de la balise <title>, les graphiques SVG peuvent être rendus accessibles aux personnes utilisant des technologies d’assistance, ça fonctionnerait comme un aria-label donc.

Au sujet de l’accessibilité, voici un article très intéressant et détaillé sur css-tricks .

Mouse over pour voir un titre !

Cercle bleu représentant une donnée importante

Intégration directement dans un bloc Gutenberg et pseudo-éléments

À remarquer que la première animation avec le mouse over contient une balise <style> à l’intérieur de <svg>, mais au départ, elle ne contenait aucun id ou classe pour identifier le cercle. Cela fait en sorte que tous les circle:hover sur une même page gagnaient aussi la propriété transform, et non pas que le bloc Gutenburg qui le contient. Pour y remédier, après avoir compris le problème, j’ai ajouté un id pour différencier #ce-cercle. Je me suis aussi amusée en ajoutant une animation css directement à l’intérieur du svg, mais cela est en attandant d’en connaitre plus sur les propriétés d’animation XML propres aux svg : <animate>, <animateMotion> et <animateTransform>, entre autres. Quoique par la suite, le cours que j’ai débuté sur Udemy, utilise des @keyframe et animation, propriétés CSS bien connus et comme j’ai fait par intuition.

<svg
      width="200"
      height="200"
      xmlns="http://www.w3.org/2000/svg">
      <style>
        /* Par défaut, pas de transformation */
        #ce-cercle {
          transition: transform 0.5s ease; /* Ajoute une transition fluide */
          cursor: pointer;
          animation: example 4s infinite;
        }
        /* Lorsqu'on survole le cercle */
        #ce-cercle:hover {
          transform: translate(
            50px,
            -50px
          ); /* Applique la transformation uniquement lors du survol */
        }
        @keyframes example {
          0%   {fill: red;}
          25%  {fill: yellow;}
          50%  {fill: blue;}
          100% {fill: green;}
       }
      </style>

Les blocs Gutenberg de base semblent être bien développés pour prendre en charge les SVG. Je découvre aussi qu’après avoir inséré du code avec le bloc HTML, on peut obtenir un aperçu. L’aperçu ne permet pas de tester l’interractivité CSS tel un :hover.

On peut aussi injecter une page HTML au complet, incluant toute la déclaration DOCTYPE! (et balises header et meta, par exemple). Est-ce une redondance de codes qui sera conserver au final, et sinon, est-ce que cela alourdi l’éxécution ? Probablement. Je vais éviter de faire cela.

Pour en revenir aux éléments SVG … et JavaScript!

La balise <script> peut-être, tout comme <style>, intégrée directement à l’intérieur de la balise HTML <svg>. Certaines compatibilités sont à vérifier, on ne peut pas tout faire, sauf sur Firefox, où même async et defer sont supportés!

Clique sur l’étoile pour voir une boîte alert!

Un script JS dans une balise svg
      <!-- Étoile -->
      <polygon
        points="100,10 130,90 210,90 150,130 170,210 100,170 30,210 50,130                -10,90 70,90"        fill="#ffcc00"
        onclick="alert('Salut à toi!')"
      />

      <!-- Script JavaScript -->
      <script type="text/javascript">
        function showAlert() { alert('Salut à toi!'); }
      </script>

À investiguer

Intégrer un SVG animé directement dans un article WordPress

Les objectifs de ce premier test avec des SVG dans WordPress étaient :

Parce que je voulais tester et être en mesure de publier mes animations, avant d’apprendre à créer et animer des SVG moi-même, j’ai demandé de l’aide à chat GPT :

Bonjour ! pour faire un test rapidement, j’aurais besoin que tu me génères du code pour animer un cercle et un carré SVG.

J’ai d’abord tenté d’intégrer le code généré directement en mode éditeur de code, ce qui n’a pas du tout fonctionné. J’ai ensuite choisi un bloc Gutenberg pour intégrer du HTML, et bingo!, cela fonctionne parfaitement, du moins pour une animation simple.

Le <style> incorporé directement s’appliquera à tous les SVG d’une même page alors il faut donner id et classes originales aux éléments ou, comme je le verrai plus tard, définir un contexte interne (namespace) avec la déclaration xmnls.

J’ai constaté ce problème sur la page Terrain de jeu alors qu’un SVG ayant une position absolute et une propriété à <cercle> devenait hors flow et changeait la couleur d’un autre cercle dans la même page.

Code SVG généré par ChatGPT 3.5 et intégré directement dans un bloc Gutenberg de type HTML .

<svg width="200" height="200">
  <!-- Cercle -->
  <circle id="monCercle" cx="50" cy="50" r="40" fill="blue">
    <animate attributeName="cx" from="50" to="150" dur="3s" repeatCount="indefinite" />
  </circle>
  
  <!-- Carré -->
  <rect id="monCarre" x="50" y="100" width="50" height="50" fill="red">
    <animate attributeName="x" from="50" to="150" dur="3s" repeatCount="indefinite" />
  </rect>
</svg>

Le code du bloc Gutenberg visualisé en mode éditeur.

<!-- wp:html -->
<svg width="200" height="200">
  <!-- Cercle -->
  <circle id="monCercle" cx="50" cy="50" r="40" fill="blue">
    <animate attributeName="cx" from="50" to="150" dur="3s" repeatCount="indefinite" />
  </circle>
  
  <!-- Carré -->
  <rect id="monCarre" x="50" y="100" width="50" height="50" fill="red">
    <animate attributeName="x" from="50" to="150" dur="3s" repeatCount="indefinite" />
  </rect>
</svg>
<!-- /wp:html -->

Ainsi seul l’ajout du commentaire <!-- wp:html --> diffère, par rapport à coller directement le code dans l’éditeur.

Le même code visualisé dans l’inspecteur.

On ne voit pas le commentaire <!-- wp:html -->. Ce commentaire n’est pas non plus visible lorsqu’on visualiser le code source dans le navigateur.

Extension de support SVG

Si jamais l’intégration de SVG plus complexe s’avère difficile, j’ai trouvé une extension : SVG Support. Je n’ai pas lu la documentation mais on parle de nettoyage de code, c’est quelque chose auquel je devrai porter une attention future.

À propos de wp:html et des blocs Gutenberg

Après recherches, j’en comprends que dans l’architecture de l’éditeur de blocs de WordPress, chaque type de bloc a une structure spécifique, identifiée par un préfixe suivi du nom du bloc. Dans ce cas, wp:html est le préfixe et html est le nom du bloc qui représente du contenu HTML brut.

Lorsqu’on utilise l’éditeur de blocs pour ajouter du contenu HTML à un article WordPress, le contenu est encapsulé dans un bloc de type wp:html. Cela permet à WordPress de gérer et d’afficher correctement le contenu lors de l’édition et de l’affichage sur le site Web alors que le commentaire n’est pas visible dans le contenu HTLM final qu’il encadre.

Présentation de mes objectifs pour mon projet de recherche pour l’Épreuve Synthèse du Programme en TIM

Animer avec des SVG et la bibliothèque Three js, dans un contexte de site WordPress

Dans le but de créer un thème WordPress pour renouveler mon site web personnel présentant mes projets et recherches en arts visuels et multimédia, je souhaite me familiariser avec la création d’animations utilisant des SVG et la bibliothèque Three.js. Ces deux technologies, mêlant art et code, correspondent à mes intérêts artistiques et professionnels et permettent de dynamiser un site.

Démarche

Je prévois de commencer par suivre des tutoriels et lire les documentations respectives pour acquérir les bases nécessaires à la création d’animations avec ces outils. Parallèlement, je mènerai une recherche visuelle afin de concevoir une esthétique pour un thème répondant aux besoins de mon site, ce qui me permettra de conceptualiser les animations que je souhaite développer.

Esthétique recherchée

Étant donné que mes pratiques artistiques s’appuient principalement sur la photographie, aussi bien analogique que numérique, je souhaite créer des animations inspirées par les notions de grain et de pixels, d’ombres et de lumières, ainsi que du spectre électromagnétique. Je souhaite également explorer des effets de réfraction similaires à du verre, voire évoquant l’utilisation d’une loupe ou d’un objectif, en utilisant des shaders dans Three.js. En parallèle, je vais examiner la possibilité de reproduire ces effets avec SVG et CSS, mais aussi d’autres types d’esthétiques, en explorant les filtres pour SVG.

Performance, écologie et accessibilité

Au cours de mes recherches préliminaires, j’ai remarqué que les SVG offrent des performances rapides et légères, tandis que les animations réalisées avec Three.js sont plus exigeantes en termes de ressources matérielles (CPU, GPU) mais aussi de bande passante. Je prévois donc également de comparer les performances et la consommation énergétique de ces deux technologies afin de comprendre leur impact écologique et social, et ainsi prendre des décisions éclairées lors de la conceptualisation et de la réalisation des animations pour mon thème WordPress.

Apprendre à prototyper des sites et des animations avec Figma

Enfin, lors de la conceptualisation et de la maquette des animations et du thème, ainsi que des designs UX et UI, j’apprendrai et utiliserai Figma. Figma est l’outil de prototypage de site web le plus utilisé par les professionnels et je ne le connais pas. Il semble être particulièrement efficace pour le prototypage d’animations. Étant intéressée professionnellement par le design, l’animation et la conception de site web, cet outil me semble indispensable à maitriser. De plus, je suis particulièrement attiré par ses capacités à générer du code, notamment celui des dessins SVG, ce qui s’avère très pertinent dans le contexte de mes recherches actuelles.

Application multimédia

L’application multimédia sera un site web WordPress, destiné à présenter de manière exhaustive mes recherches et mes apprentissages dans la création d’animations SVG, Three.js et en prototypage avec Figma. Chaque semaine, je publierai des articles mettant en lumière mes découvertes, les animations réalisées ainsi que des comparaisons énergétiques et esthétiques entre SVG et Three.js De plus, si le temps le permet, je souhaite approfondir mes connaissances de WordPress en apprenant la programmation de blocs pour Gutenberg.

L’objectif ultime est bien de créer une application qui va au-delà d’un simple blog de recherche, mais plutôt un site présentant également mon portfolio. Par conséquent, un thème WordPress complet intégrant des animations originales et interactives réalisées en SVG et/ou Three.js. De plus, il permettra la migration de contenu actuellement dispersé sur trois sites différents (ndasilva.art, ndasilva.ca et Behance). À travers cette plateforme, je souhaite mettre en valeur mes compétences en animation, en design et en programmation, tout en présentant l’ensemble de mon portfolio en un seul endroit.