JeuWeb - Crée ton jeu par navigateur
[Résolu][SVG]Faire varier la couleur (stroke) - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Résolu][SVG]Faire varier la couleur (stroke) (/showthread.php?tid=126)



[Résolu][SVG]Faire varier la couleur (stroke) - Myrina - 06-06-2013

Dans un dessin SVG, j'aurai besoin de tracer (via <path> de préférence) un trait de couleur noir qui doit être de couleur blanche si il se trouve sur une surface de couleur noire.

Je sais que je peux y arriver en décomposant le trait en 3 morceaux (avant la zone noire, la zone noire puis après la zone noire) mais ceci nécessite de calculer les points des 3 segments (et donc de les recalculer à chaque changements).

Donc, y a t'il moyen de le faire avec un seul segment?


RE: [SVG]Faire varier la couleur (stroke) - Xenos - 06-06-2013

Comme ceci [lien supprimé depuis]. Les navigateurs ne supportent pas encore la valeur "BackgroundImage" pour l'attribut "in" d'un filtre SVG. Or, ce moyen t'aurai permis de faire facilement ce que tu souhaites (car ce moyen t'aurai permis de définir la couleur à afficher pour un pixel de l'objet en fonction de la couleur en arrière-plan).

L'alternative proposée (cf lien de début de message) permet de simuler le comportement.
Elle se base sur clip-path. Cette propriété permet de réduire la zone d'affichage d'un groupe d'éléments. On peut ainsi:
  • Dessiner un cercle
  • Dessiner une courbe par-dessus, d'une première couleur (partout, même dans le cercle)
  • Dessiner une seconde courbe, identique mais d'une autre couleur, que l'on "clip" sur le cercle
Ainsi, le cercle est dessiné en 1er, puis la courbe "pleine", puis le morceau de courbe coloré, par-dessus la zone du cercle.

L'exemple SVG joint ajoute un peut d'animation, juste pour rigoler ^^ Mais le code d'animation est dégueulasse, ne le prends pas en exemple! :o Ne considère, dans le code source, que la partie sur le clip-path:


<?xml version="1.0" encoding="utf-8"?>
<!--
© 2013 - MONIER Vincent
Exemple d'utilisation de clip-path pour SVG
L'animation javascript n'est pas à prendre en compte:
sont code est dégueulasse.
Clip-path permet de masquer le rendu d'un objet à une forme donnée.
Donc, on crée un "fantome" (le clip) d'un cercle.
On dessine ensuite un autre cercle, de même taille que le clip, et à la même place.
On dessine, par-dessus, une courbe, générique
Enfin, on dessine une courbe d'une autre couleur, que l'on "clip" avec le fantome précédent.
On a ainsi !!l'impression!! (c'est pas "vrai" au fond, c'est juste la vue que l'on voit)
qu'il n'existe qu'une courbe, et que celle-ci change de couleur du niveau de l'unique cercle que l'on voit.

Licence CeCILL
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<script>
var a = 0;
setInterval(function ()
{
var c1 = document.getElementById('my-circle');
var c2 = document.getElementById('my-circle-2');
var b = a/360*2*Math.PI;
var X = 150 + Math.cos(b)*50, Y = 150 + Math.sin(b)*50;
c1.setAttribute('cx', X);
c1.setAttribute('cy', Y);
c2.setAttribute('cx', X);
c2.setAttribute('cy', Y);
a++;
},
30
);
</script>

<clipPath id="my-area">
<circle r="50" cx="150" cy="150" id="my-circle"/>
</clipPath>

<circle fill="purple" r="50" cx="150" cy="150" id="my-circle-2"/>

<path d="M 100 250 q 150 -300 300 0" stroke="black" stroke-width="5" fill="none"/>

<g clip-path="url(#my-area)">
<path d="M 100 250 q 150 -300 300 0" stroke="green" stroke-width="5" fill="none"/>
</g>
</svg>


(Et oui, j'aime les couleurs bien crades qui ne vont pas ensemble!)


RE: [SVG]Faire varier la couleur (stroke) - Myrina - 06-06-2013

Je n'avais absolument pas penser au clipping.

Merci, je pense que je devrais m'en sortir.

PS: en exemple, vaut mieux des couleurs crades et tranchantes pour ne pas avoir d’ambiguïté d'interprétation

Edit: Voici le résultat:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-_W3C_DTD SVG 1.0_EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd" >
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
version="1.1" width="600px" height="400px">
<style type="text/css">
<![CDATA[
.lineb {stroke:black;stroke-width:1px;}
.linew {stroke:white;stroke-width:1px;}
.pt1 {fill:white;}
.pt2 {fill:white;}
.pt3 {fill:black;}
.pt4 {fill:black;}
.pt5 {fill:#0F80C0;}
.pt6 {fill:#0F80C0;}
.pt7 {fill:red;}
.pt8 {fill:red;}
.pt9 {fill:yellow;}
.pt10 {fill:yellow;}
]]>
</style>

<clipPath id="cercle1">
<circle cx="250" cy="175" r="80"/>
<circle cx="350" cy="175" r="80"/>
</clipPath>
<clipPath id="cercle2">
<circle cx="250" cy="175" r="60"/>
<circle cx="350" cy="175" r="60"/>
</clipPath>

<circle cx="250" cy="175" r="100" class="lineb"/>
<circle cx="350" cy="175" r="100" class="lineb"/>
<circle cx="250" cy="175" r="100" class="pt1"/>
<circle cx="350" cy="175" r="100" class="pt1"/>

<circle cx="250" cy="175" r="90" class="lineb"/>
<circle cx="350" cy="175" r="90" class="lineb"/>
<circle cx="250" cy="175" r="90" class="pt2"/>
<circle cx="350" cy="175" r="90" class="pt2"/>

<circle cx="250" cy="175" r="80" class="linew"/>
<circle cx="350" cy="175" r="80" class="linew"/>
<circle cx="250" cy="175" r="80" class="pt3"/>
<circle cx="350" cy="175" r="80" class="pt3"/>

<circle cx="250" cy="175" r="70" class="linew"/>
<circle cx="350" cy="175" r="70" class="linew"/>
<circle cx="250" cy="175" r="70" class="pt4"/>
<circle cx="350" cy="175" r="70" class="pt4"/>

<circle cx="250" cy="175" r="60" class="lineb"/>
<circle cx="350" cy="175" r="60" class="lineb"/>
<circle cx="250" cy="175" r="60" class="pt5"/>
<circle cx="350" cy="175" r="60" class="pt5"/>

<circle cx="250" cy="175" r="50" class="lineb"/>
<circle cx="350" cy="175" r="50" class="lineb"/>
<circle cx="250" cy="175" r="50" class="pt6"/>
<circle cx="350" cy="175" r="50" class="pt6"/>

<circle cx="250" cy="175" r="40" class="lineb"/>
<circle cx="350" cy="175" r="40" class="lineb"/>
<circle cx="250" cy="175" r="40" class="pt7"/>
<circle cx="350" cy="175" r="40" class="pt7"/>

<circle cx="250" cy="175" r="30" class="lineb"/>
<circle cx="350" cy="175" r="30" class="lineb"/>
<circle cx="250" cy="175" r="30" class="pt8"/>
<circle cx="350" cy="175" r="30" class="pt8"/>

<circle cx="250" cy="175" r="20" class="lineb"/>
<circle cx="350" cy="175" r="20" class="lineb"/>
<circle cx="250" cy="175" r="20" class="pt9"/>
<circle cx="350" cy="175" r="20" class="pt9"/>

<circle cx="250" cy="175" r="10" class="lineb"/>
<circle cx="350" cy="175" r="10" class="lineb"/>
<circle cx="250" cy="175" r="10" class="pt10"/>
<circle cx="350" cy="175" r="10" class="pt10"/>

<path d="M 100 250 q 150 -250 300 0" stroke="black" stroke-width="5" fill="none"/>

<g clip-path="url(#cercle1)">
<path d="M 100 250 q 150 -250 300 0" stroke="white" stroke-width="5" fill="none"/>
</g>
<g clip-path="url(#cercle2)">
<path d="M 100 250 q 150 -250 300 0" stroke="black" stroke-width="5" fill="none"/>
</g>

</svg>