Définir une figure en plusieurs fois

Est-ce vraiment impossible ?

a marqué ce sujet comme résolu.

Je cherche à faire un truc en SVG, mais vu que ça fait des heures que je cherche en vain sur Internet comment y parvenir, j’en viens à me demander si c’est seulement possible avec SVG. Imaginez le code suivant.

1
2
3
4
5
6
7
<svg width="800px" height="600px" viewbox="0 0 800 600">

<polyline points="100,200 300,200 300,400, 100,400 100,200" stroke="red" stroke-width="3" fill="yellow" />
<polyline points="300,200 500,200 500,400, 300,400 300,200" stroke="red" stroke-width="3" fill="green" />
<polyline points="500,200 700,200 700,400, 500,400 500,200" stroke="red" stroke-width="3" fill="blue" />

</svg>

Ça donne trois carrés de couleurs différentes, parfaitement juxtaposés. Mais pour le faire, on est obligé de dupliquer les frontières entre les différents carrés. Là, ce n’est pas très grave, mais pour des structures un peu plus complexes, comme des frontières entre pays, ça devient très vite très lourd.

Ce que je voudrais, c’est définir des chemins, et pouvoir ensuite créer des surfaces à partir de plusieurs chemins qui enclosent un espace, et donner des propriétés à cette surface (par exemple, un fill). C’est le genre de trucs très simples à faire dans le format de cartographie d’OSM, par exemple.

Alors, existe-t-il un moyen de faire ça en SVG ? Parce que sinon, c’est quand même une sacrée limitation…

+0 -0

C'est possible, mais assez limité. Mon code n'est sûrement pas minimal, mon svg étant un peu rouillé, je me suis aidé d'Inkscape.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<svg xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" version="1.1"
width="210mm" height="297mm" id="svg2"
xmlns:xlink="http://www.w3.org/1999/xlink">

<defs>
    <polyline id="d1" points="300,200 300,400" />
    <polyline id="d2" points="300,200 100,200 100,400 300,400" />
</defs>
<g stroke="red" stroke-width="3" fill="yellow">
    <use xlink:href="#d1"/>
    <use xlink:href="#d2"/>
</g>
</svg>

En vrai, mon groupe a ajouté les deux objets et leur a attribué la couleur de groupe. Je peux récupérer les mêmes objets et leur donner une autre couleur, dans un autre groupe.

Mais tu remarquera que ce n'est pas tout à fait identique : la ligne rouge de droite est mangée. En effet, c'est bien d2 qui est jaune rempli, et donc qui mange d11. Ce n'est pas un objet virtuel constitué de d1 + d2. Donc, on est effectivement très limité. Je ne suis pas sûre qu'il soit possible de faire mieux en svg, mais si c'est possible, c'est probablement en jouant avec les defs.


  1. Si tu vois pas ce que je veux dire, déplace d1 en "500,200 500,400". Tu va garder ton carré jaune, mais la ligne rouge va se déplacer. 

+0 -0

Salut,

J'ai cherché un peu et j'ai trouvé deux choses qui peuvent éventuellement t'intéresser :

  • la possibilité de définir des formes pour les réutiliser : ça se passe par ici
  • le clipping (en gros, tu prends une forme, tu définis une frontière, et ce qui est dedans est visible, ce qui est dehors ne l'est pas).

Par contre, c'est apparemment impossible de définir des points, et les réutiliser comme dans le format d'OSM.

Édit. : le clipping semble relativement limité. Par exemple, il semble impossible de mettre une bordure à l'objet "clippé". Autrement, il y a l'air d'avoir moyen d'écrire des scripts (JS) dans les fichiers svg… À voir.

+0 -0

Dans un premier temps, le clipping paraît une bonne idée. Voyez par vous-mêmes le résultat sur cet exemple simple.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<svg
    width="800" height="800"
    xmlns="http://www.w3.org/2000/svg" version="1.1"
    xmlns:xlink="http://www.w3.org/1999/xlink">

<defs>
  <path id="chemin1" d="m 300 300 q -50 150 250 250" fill="none" />
  <path id="chemin2" d="m 550 550 q 72 -214 -250 -250" fill="none" />
  <clipPath id="découpage">
    <use xlink:href="#chemin1" />
    <use xlink:href="#chemin2" />
  </clipPath>
</defs>

<rect x="200" y="200" width="400" height="400" fill="yellow" clip-path="url(#découpage)" />
<use xlink:href="#chemin1" stroke="red" stroke-width="3" stroke-linecap="round" />
<use xlink:href="#chemin2" stroke="red" stroke-width="3" stroke-linecap="round" />

</svg>

On obtient de belles bordures, même s’il aurait en effet été préférable de pouvoir les appliquer directement au chemin de découpage.

En revanche, dès qu’on passe à une construction un chouïa plus complexe, le résultat est… conceptuel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<svg
    width="800" height="800"
    xmlns="http://www.w3.org/2000/svg" version="1.1"
    xmlns:xlink="http://www.w3.org/1999/xlink">

<defs>
  <path id="chemin1" d="m 300 300 q -50 150 250 250" fill="none" />
  <path id="chemin2" d="m 550 550 q 72 214 20 -50" fill="none" />
  <path id="chemin3" d="m 570 500 q -20 -150 -270 -200" fill="none" />
  <clipPath id="découpage">
    <use xlink:href="#chemin1" />
    <use xlink:href="#chemin2" />
    <use xlink:href="#chemin3" />
  </clipPath>
</defs>

<rect x="200" y="200" width="400" height="400" fill="yellow" clip-path="url(#découpage)" />
<use xlink:href="#chemin1" stroke="red" stroke-width="3" stroke-linecap="round" />
<use xlink:href="#chemin2" stroke="red" stroke-width="3" stroke-linecap="round" />
<use xlink:href="#chemin3" stroke="red" stroke-width="3" stroke-linecap="round" />

</svg>

J’ai essayé d’utiliser un attribut clip-rule différent, mais cela semble n’avoir aucun effet.

+0 -0

Sous Inkscape, j'utilise Chemin > Division, pour tracer les frontières. En tout cas, en cartographie je fais ça.

PS : désolé d'avoir remonté le topic, ça doit être HS, désolé :/

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte