Nuages
Des exercices originaux intégrant différentes techniques pour valider ma compréhension des filtres, des masques, du morphing par animation et des notions de trait et de remplissage.
Des exercices originaux intégrant différentes techniques pour valider ma compréhension des filtres, des masques, du morphing par animation et des notions de trait et de remplissage.
Une variation avec la technique d’animation utilisant la propriété CSS stroke-dashoffset pour animer les traits. Ici, les traits apparaissent lorsque l’utilisateur fait défiler la page.
En gros, par JavaScript, on va chercher la longueur du trait avec la fonction getTotalLength() puis on mesure l’emplacement de la fenêtre active sur la page en comparant les éléments clientHeight et scrollHeight pour trouver le haut et le bas du viewport et ainsi faire apparaitre ou disparaitre les traits. Je vérifie aussi le type d’appareil ; si c’est un téléphone, la dimension des dessins est réduite de 50%. Chaque SVG est autonome et comprend donc sont propre script personnalisé.
Pour mon exploration du grain (bruit) en SVG, je me suis inspiré du tutoriel Grainy Gradients découvert sur css-tricks. Si j’aime l’effet, je ne l’ai pas suivi car ce n’est pas fait pour être dans un seul SVG autonome, mon objectif premier pour le moment. Le grain est bien créé avec un filtre SVG mais il devient ensuite un fichier externe qui sera appliqué comme background-image à un div HTML. Ainsi, j’ai plutôt expérimenté par moi-même, ce qui demande plus de temps mais m’a aussi permis de mieux comprendre et revoir des notions nouvelles et apprises récemment.
x et en y avec <tspan>.<feTurbulence> de type bruit fractal.<animate> : animation de la fréquence de base du filtre feTurbulence de type bruit fractal.window.innerWidth et appliquer des valeurs différentes à baseFrequency.feGaussianBlur sur le cercle. Avec son dégradé et sa transparence, l'effet créait des bandes. Je découvre que pour éviter cela on doit indiquer l'interpolation colorimétrique sRGB.feTurbulence contient aussi l'élément feColorMatrix, avec les paramètres type="saturate" values="0", afin d'enlever toutes les couleurs du grain.animation-timing-function du CSS. animation-timing-function est beaucoup plus simple! Surtout avec un outil tel que cubic-bezier.keyTimes) de chacune des valeurs (values) des points bézier.calcMode permet de recalculer les keySplines lors de l'exécution.animation-timing-function<circle id="cercle-1-25022024" cx="125" cy="112" r="100"
fill="url(#degrade-4-250224)" filter="url(#cercle-flou-2-25022024)"> <animate attributeName="cx" from="125" to="375" begin="0s" dur="10s" values="125;150;175;200;250;300;375"
keySplines="
0.1 0.8 0.2 1;
0.1 0.8 0.2 1;
0.1 0.8 0.2 1;
0.1 0.8 0.2 1;
0.1 0.8 0.2 1;
0.1 0.8 0.2 1"
keyTimes="0;0.22;0.33;0.55;0.88;0.92;1"
calcMode="spline" repeatCount="indefinite"/>
</circle>
feTurbulence, feDisplacementMap et feDiffuseLightingfeDiffuseLighting. Je trouve qu'il rend tout terne en plus d'ajouter un contour noir.<feTurbulence> de type bruit fractal sur un <mask> au lieu de le mettre directement sur une forme (rect, circle etc.)feDiffuseLighting.feComponentTransfer pour travailler le contraste et la luminositéfeFuncR, feFuncG et feFuncB.slope et intercept afin d'avoir une effet similiare à jouer sur le contraste et le luminosité.contrast et brightness..stop-color-1-22022024 sur les différents palliers de couleurs des dégradés linéaires.stop-opacity à 0).<mask> <defs>
<mask id="masque-1-25022024" maskunits="userSpaceOnUse" maskcontentunits="userSpaceOnUse">
<image xlink:href="https://phospixel.com/wp-content/uploads/2024/02/3b04.gif" width="500" height="280"></image>
</mask>
<linearGradient id="gr-1-25022024" x1="0" y1="0" x2="100%" y2="100%">
<stop offset="15%" class="stop-color-1-22022024 stop-color--1" />
<stop offset="45%" class="stop-color-1-22022024 stop-color--2" />
<stop offset="55%" class="stop-color-1-22022024 stop-color--2" />
<stop offset="85%" class="stop-color-1-22022024 stop-color--3" />
</linearGradient>
<linearGradient id="gr-2-25022024" x1="0" y1="100%" x2="100%" y2="0%">
<stop offset="15%" class="stop-color-1-22022024 stop-color--4" />
<stop offset="45%" class="stop-color-1-22022024 stop-color--5" stop-opacity="0" />
<stop class="stop-color-1-22022024 stop-color--5" stop-opacity="0" />
<stop offset="85%" class="stop-color-1-22022024 stop-color--6" />
</linearGradient>
</defs>
<g mask="url(#masque-1-25022024)" class="mouvement-1-22022024">
<rect fill="url(#gr-1-25022024)" width="100%" height="100%"></rect>
<rect fill="url(#gr-2-25022024)" width="100%" height="100%"></rect>
</g>
Exercice de base faisant parti du tutoriel Learn SVG Animation – With HTML, CSS & Javascript sur Udemy.
<mask>Extrait de code pour visualiser qu’il faut déboubler les <path>s dans l’élément <mask>, et ensuite les afficher. Ici, on applique le masque au tube (#devoile) alors que le cercle reçoit une animation CSS (#demasque-1-2102024).
<defs>
<mask id="devoile">
<path class="tube" fill="#020202" d="M136.07 ..." />
<circle id="demasque-1-2102024" fill="#fff" cx="66.836" cy="50.356" r="34" />
</mask>
</defs>
<path mask="url(#devoile)" fill="#020202"class="tube" fill="gray"d="M136.07 ..." />
<circle id="demasque-1-2102024" fill="none" cx="66.836" cy="50.356" r="34" />
</svg>
Pour l’exercice de masque, le mot EXPERIMENT en SVG était fourni. J’ai voulu faire mon propre mot et comme les tutos ne montrent pas comment préparer les fichiers SVG, j’ai eu à chercher comment faire pour créer un seul et unique path dans Adobe Illustrator car mon exercice ne fonctionnait pas 🙁 C’est en ouvrant le fichier fournit que j’ai remarqué dans les calques qu’il s’agissait d’un compound path et non pas d’un path!
Enfin, ceci pourrait régler, en partie, les problèmes de dessin rencontré jusqu’à présent, notament avec les signatures, pour avoir un seul path et donc une seule animation continue. Pour ce, il faut faire un Compound path (Object > Coumpound Path > Make).
J’ai voulu rendre l’effet de dévoiler quelque chose de flou avec un verre ou une loupe, en plus d’ajouter un trait autour du cercle.
Je n’ai pas aimé que le flou reste lorsque l’animation de dévoilement passe. J’ai donc retravaillé pour rendre l’effet souhaité.
Un cercle qui dévoile le texte et un cercle qui masque le texte flou, et chacun d’eux ont un deuxième cercle avec le contour noir (stroke) qui les suivent.
Je l’avais déjà fait lorsque je testais du grain pour une première fois. Cette fois-ci l’image est externe, dans les <defs>, et ensuite appliqué comme un masque. Le résultat est pas mal mieux que celui obtenu avec un filtre de grain dans Adobe Illustrator.
<defs>
<mask id="masque-1-20022024">
<image height="400" width="600" x="0" y="0"
xlink:href="https://phospixel.com/
wp-content/uploads/2024/02/photos....png"
</mask>
</defs>
<text x="22" y="100" class="texte-01-20022024"
mask="url(#masque-1-20022024)">Texture type Alpha
</text>
image height="400" weight="600" : un problème à régler pour l’adaptabilité ? Mask vs clipPath et clip-path Même si je n’ai pas encore tester les clipPath (SVG) ou clip-path (CSS), je sais qu’ils permettent d’afficher ou non une partie d’une image. Je me demandais par contre le contexte d’utilisation par rapport aux masques et cet article très imagé aborde très bien la question.
En gros, les masques sont beaucoup plus puissant car on peut faire des dégradés. Les clipPath c’est noir ou blanc, ça passe ou pas, c’est visible ou non, il n’y a pas d’entre-deux.
J’ai voulu refaire ma signature car je n’étais pas satisfaite du résultat de ma première version. Au lieu d’utiliser ma tablette, son crayon et Clip Studio Pro, j’ai suivi à la lettre la technique présentée dans le tutoriel de Code with Sam sur udemy : avec Adobe Illustrator, écrire avec le crayon et un trait de 1pt. Voici le résultat :
Après optimisation avec SVG OMG, je reporte le code obtenu dans VS Code et anime le stroke-dashoffset. Le résultat est loin d’être celui recherché! On dirait que ce n’est pas le même code SVG que le premier ci-haut mais oui, c’est bien pareil. La technique d’animation du trait ne fonctionne donc pas encore car le trait est double.
Une capture d’écran montrant le trait dans Illustrator. Ceci n’est donc pas un trait pour le SVG même si ce l’est pour Adobe : il n’y a aucun remplissage, ce n’est qu’un trait de 1pt.

Pour m’approcher de l’objectif souhaité, j’ai éliminé du code des <path>s directement dans VS Code. L’animation ne jouerait pas en boucle normalement mais elle est en continu pour observation. Remarquez que lorsqu’il y a des rondeurs, le trait remonte ensuite sur le chemin d’où il venait.
Je n’ai pas encore découvert comment régler le problème pour une signature manuscrite, en utilisant Adobe Illustrator. Par contre, en lisant un autre tutoriel, sur un autre sujet mais qui utilise aussi la technique d’animation avec le stroke-dashoffset, l’auteur, Louis Hoebregts, donne ces informations :

Ainsi, il semble bien possible de pouvoir le faire de manière manuscrite. Ses indication sur le trait unique éclaire. Peut-être serait-ce plus simple avec Inkscape. J’ai toujours voulu l’essayer (et m’affranchir d’Adobe 😉 ).
L’élément <defs> sert à définir des propriétés supplémentaires de type XML. Dans le contexte d’un SVG, on l’utilise souvent pour y circoncir des propriétés souvent stylistiques non CSS. Par exemple, un dégradé <linearGradient> devrait être définit à l’intérieur d’une balise <defs>, de même qu’un <mask> et un <filter> .
<defs>
<linearGradient id="insta-1-20022024">
<stop offset="0%" stop-color="#f8ED34"/>
<stop offset="50%" stop-color="#FF3966"/>
<stop offset="100%" stop-color="#33207f"/>
</linearGradient>
</defs>
<text fill="url(#insta-1-20022024)" style="font-family:"Roboto","Arial",sans-serif;font-weight:700;font-size:2.6rem;pointer-events:none" transform="translate(91.545 64.47)">PhōsPixel
</text>
Le fill est déinit ici inline mais il pourrait être appliqué dans le style. Il semble toutefois que ce soit plus optimal inline, pour la publication. SVG OMG, l’optimiseur de code, replace la majorité des styles inline, à l’exception des @keyframe, ou si un même style s’adresse à plusieurs éléments.
<defs> pour les styles propres aux SVG <linearGradient>, <mask>, etc.transform et transformIl y a des situations où on doit absolument utiliser le inline. Par exemple, il est impossible d’envoyer le tranform dans le <style> car le CSS ne comprend pas comment appliquer la translation. Par rapport à quoi? On n’est pas en HTML et le SVG lui-même n’est pas positionné dans la page. Or, ce que je comprends ici, c’est que le transform inline est une propriété SVG qui applique la translation par rapport à l’élément lui-même, ce n’est pas un transform de mise-en-page (CSS) lié au conteneur, à un parent ou au viewport.
stroke-dashoffset), pas le fill.path), pour animer le remplissage (fill), ce n’est pas par CSS mais bien avec des propriétés de <animate>, propre au SVG.fill, on utilise le linearGradient et on peut animer le remplissage, ici de gauche à droite. <defs>
<linearGradient id="gauche-a-droite-1-170224">
<stop offset="0" stop-color="#00a98c">
<animate attributeName="offset" from="0" to="1" dur="3s" repeatCount="indefinite" />
</stop>
<stop offset=" 0" stop-color="#b4eae1">
<animate attributeName="offset" from="0" to="1" dur="3s"/>
</stop>
</linearGradient>
</defs>
<path fill="url(#gauche-a-droite-1-170224)"
path de la signature avec <animateMotion> <circle r="5" fill="red">
<animateMotion dur="30s" repeatCount="indefinite"
path="M115.9 241.4c3.9-15.8 7.7-31.6 11.8-47.3 [...]
path d="url(#ID)", et celà n’a pas fonctionné. path au niveau du code. <path>, avec donc en plus une animation par path. J’ai opté pour une signature toute en lettres attachées, afin de vérifier ma conclusion. Cela fonctionne en effet.
fill).stroke), sans remplissage, comme c’est le cas dans le dernier exemple.<g>), fonctionne, la même animation pour toutes les loupes de cette page en fait. stroke, stroke-width, stroke-dashoffset, stroke-dasharray et fill, il est possible d’arriver à un tel résultat rapidement lorsque la conception est bien faite et qu’on choisit une seule itération et un animation-fill-mode sur forwards.Tous les exemples sur cette page sont sans animation, sans JS au niveau de la transformation de la forme, ils ne contiennent donc qu’une transition CSS entre deux propriétés d: path("").
J’ai été ravie de voir ce truc sur css-tricks dans l’articles sur les propriétés et j’ai voulu l’essayer et voir comment il pourrait fonctionner dans diverses situations.
:hover pour sourisPour que le morphing fonctionne, les deux formes doivent avoir le même nombres de points. Dans cet autre article sur css-tricks, on explique une autre technique, avec animation et JS, mais la partie pour les formes est bien expliquée.
Si les deux formes n’ont pas le même nombre de points, JavaScript devrait pouvoir le faire car j’ai vu que c’est aussi faisable avec la librairie d’animations GSAP.
Le onClick serait très intéressant pour des icônes réutisables, comprenant leur 2 états à même un seul SVG. C’est une chose que je compte exploré. Mais attention à la règle du nombre de points, ou trouver une solution JS!
<text> et des <circle> avec onClickJe me suis mise à penser aux cartes de fêtes virtuelles et au annonces et bannières. Oui c'est bien faisable à même un seul SVG!
<foreignObject>Contenu HTML dans un SVG
Un <foreignObject> est un élément SVG qui permet d'intégrer du contenu HTML dans un document SVG. Cela permet d'inclure des éléments HTML tels que du texte, des formulaires, des images, etc.. L'utilisation de <foreignObject> permet de combiner les fonctionnalités de SVG et HTML dans un même document. En savoir plus : MDN
J'ai voulu essayer une case à cocher pour vérifier l'ampleur des possibilités avec <foreignObject>. Cela fonctionne mais pour récupérer ensuite le label, et atteindre le path à l'extérieur du <foreignObject>, je n'y suis pas arrivée. À ce moment là, il faudrait mettre le SVG à atteindre à l'intérieur même du HTML, donc : <svg>, <foreignObject>, HTML, <svg></svg>, </foreignObject>, </svg>.
Étant donné que je ne voulais pas m'attarder sur cette curiosité, je n'ai pas poussé plus loin mais j'ai su ce que je voulais savoir : les SVG, c'est presque infini côté possiblilités!
<!--Les chemins SVG qui se transforment l'un en l'autre doivent avoir les mêmes
commandes et le même nombre de points, sinon la transformation ne fonctionnera pas.-->
<style type="text/css">
.morphing-path path {
d: path("M150, 10 L40, 200 L260, 200 L260, 200Z");
fill: url(#SVGID_1_);
transition: all 0.35s ease;
cursor: pointer;
}
.morphing-path path:hover {
d: path("M220, 10 L40, 10 L40, 220 L220, 220Z");
fill: url(#SVGID_2_);
}
</style>
<!-- On attribue la classe à un groupe et on ne fait
que déclarer la balise <path /> -->
<g class="morphing-path">
<path />
</g>
</svg>