Source : livre svg Essentials de O'REILLY.
"The world of SVG is
an infinite canvas."
La
surface du canevas que le document SVG utilise est appelée le Viewport
du document SVG.
Elle est définie de la manière suivante :
dans la balise <svg>, avec les attributs width et height pour les
dimensions (et les attributs x et y pour la position dans le navigateur).
Exemple :
Je veux dessiner un rectangle
<svg width="200"
height="150">
<rect x="10" y="10" width="50"
height="30"
style="stroke: black; fill: none;" />
</svg>
Système
de coordonnée par défaut
Je définis une surface initiale où va être contenu le dessin que je crée.
Quelle longueur, quelle largeur.
Puis je dois lui donner un système de coordonnées.
Il existe un système de coordonnées pas défaut.
L'origine (0,0) est en haut à gauche du viewport et l'unité de longueur est un
pixel. (1,1) est à 1pixels sur l'axe des x et 1 pixel sur l'axe des y de
l'origine (0,0).
Les unités de longueur :
Le pixel est l'unité de longueur par défaut.
o
Les
longeurs sont indiqués soit par un nombre, soit par les unités absolues ou
relatives habituelles:
o
em,
ex (largeur d'un "m" et hauteur d'un "x" de la fonte
courante)
o
px
(pixels, unités définies par le device)
o
pt,
pc (points, et ??). Normalement le client indique à combien de pixels
correspond pt ou pc, pareils pour
les cm, mm et in.
o
cm,
mm, in
o
pourcentages
(par rapport au viewport)
o
La
signifcation de nombres sans unités s'établit par rapport au unités utilisés
pour définir le viewport (pixels par défaut)
o
Note:
On le choix d'ignorer les subtilités du système des longueurs, mais suivant la
tâche il faut les maîtriser et relire la spécification.
Dans
l'exemple ci-dessus: le canevas est un rectangle de largeur 200 pixels et
hauteur 150 pixels. Il apparaîtra à l'écran en dépendant du système de
l'utilisateur.(de la résolution de son écran par exemple).
Le rectangle se place en (10, 10) dans le sytème de coordonnées par défaut. Et
sa largeur est de 50 pixels et sa hauteur de 30 pixels.
On
peut avoir différents cas de figures:
<svg width="70mm"
height="70mm">
<rect x="10" y="10" width="50"
height="30"
style="stroke: black; fill: none;" />
</svg>
Le rectangle est toujours en (10 pixels, 10 pixels) dans le sytème de
coordonnées par défaut. Et sa largeur est de 50 pixels et sa hauteur de 30
pixels.
<svg width="200" height="200">
<rect x="10mm" y="10mm" width="15mm"
height="10mm"
style="stroke: black; fill: none;" />
</svg>
Le rectangle est à (10 mm, 10 mm) dans le sytème de coordonnées par défaut. Et
sa largeur est de 15mm et sa hauteur de 10mm.
Modification
du système de coordonnées par défaut.
On peut modifier le système de coordonnées par défaut avec l'attribut viewBox
de l'élément svg.
Je peux modifier les coordonnées de l'origine. (je peux translater le système
de coordonnées).
Je peux modifier le valeur de l'unité de l'axe des x et la valeur de l'unité de
l'axe des y. (je peux "scaler" le système de coordonnées).
<svg
width="200" height="150" viewBox="0 0 400
300">
<rect x="10" y="10" width="50"
height="30"
style="stroke: black; fill: none;" />
</svg>
Le
rectangle diminue de moitié… dans le sytème de coordonnée local, une unité
locale vaut 0.5 pixels.(200/400).
Cas
particuliers:
Si je transforme le système de coordonnées et que l'axe des x et l'axe des y
n'ont pas le même "rapport": une unité locale ne représente pas la
même longueur sur les deux axes.
Exemple :
<svg
width="200" height="150" viewBox="0 0 100
150">
<rect x="10" y="10" width="50"
height="50"
style="stroke: black; fill: none;" />
</svg>
Dans
le système de coordonnées initial, j'ai un carré et dans le système de
coordonnées local je n'ai plus forcément un carré : j'ai un rectangle de
largeur 100 pixels et de hauteur 50 pixels.
Alors par défaut SVG, va maintenir "la proportion" et dessiner un
carré.
Si on ne veut pas que svg maintienne la proportion il faut utiliser l'attribut
suivant:
PreserveAspectRatio et lui affecter la valeur none. Les objets
seront déformés mais resteront dans la ViewBox.
On
peut affecter d'autres valeurs à l'attribut PreserveAspectRatio :
PreserveAspectRatio="alignement [meet / slice]"
Voir p20-23 svg Essentials de O'REILLY
http://www.yoyodesign.org/doc/w3c/svg1/coords.html
- PreserveAspectRatioAttribute
http://tecfa.unige.ch/guides/tie/html/svg-intro/svg-intro-6.html
- 96346
Systèmes
de coordonnées imbriqués
"Nested Systems of Coordinates"
On peut écrire du code de la façon suivante:
<svg width="200px"
height="200px" viewBox="0 0 200 200">
<circle cx="25" cy="25" r="25"
style="stroke: black; fill: none;"/>
<rect x="100" y="5" width="30"
height="80" style="stroke: blue; fill: none;"/>
<svg x="100px" y="5px"
width="30px" height="80px" viewBox="0 0 50 50"
preserveAspectRatio="xMaxYMax meet">
<circle cx="25" cy="25" r="25"
style="stroke: black; fill: none;"/>
</svg>
</svg>
On peut imbriquer des fichiers SVG et donc insérer des canevas avec leurs
sytèmes de coordonnées propres.
Ici on a voulu reproduire le cercle à l'intérieur du rectangle :
au lieu de redimmensionner le cercle et de le déplacer dans le rectangle, on
crée un nouveau canevas qui se superpose au rectangle et on dessine le cercle
dans ce nouveau canevas.
Illustration SVG du fonctionnement
du système de coordonnées...
Formules:
xm=evt.getClientX()* et
ym=evt.getClientY()* renvoient les
coordonnées du pointeur dans la fenêtre, l'origine (0;0) étant l'angle
supérieur gauche de la zone SVG. |
Les
transformations
L'attribut
Transform...
voir
sur les différents sites l'écriture...
http://www.euroclid.fr/Cours_SVG/slide22.htm
http://tecfa.unige.ch/guides/tie/html/svg-intro/svg-intro-6.html
- 96346
http://www.w3.org/2002/Talks/0328-Amsterdam-IH/ducktrslide.svgz
Il faut bien comprendre que la transformation s'applique au sytème
de coordonnée attaché à l'objet.
Exemple
<svg width="400px" height="400px" viewBox="0 0 400
400">
<rect id="square" x="10" y="10"
width="20" height="20"style="fill: none; stroke:
black;"/>
<use xlink:href="#square" transform="scale(2)"/>
</svg>
Dans cet exemple simple, on voit que le carré a doublé (en longueur et
épaisseur des traits!) ET qu'il a été "déplacé"…c'est ce point
qu'il faut bien comprendre.
Le système de coordonnée a été modifié : une unité vaut 2 pixels.
Et le rectangle qui est en (10,10) l'est toujours dans le nouveau système de
coordonnées mais se retrouve en (20,20) dans l'ancien système de coordonnées.
D'autre part, si je ne veux pas que l'épaisseur de mon trait double également
il faut prévoir de diviser l'épaisseur du trait du facteur inverse de la
transformation. Dans cet exemple, il faut affecter la valeur 0.5 à l'attibut
stroke pour que l'épaisseur soit toujours de 1 pixel.
<svg width="400px" height="400px" viewBox="0 0 400
400">
<rect x="10" y="10" width="20"
height="20"style="fill: none; stroke: black;"/>
<rect x="10" y="10" width="20"
height="20"style="fill: none; stroke: black; stroke-width:
0.5;" transform="scale(2)"/>
</svg>
Si je veux que le rectangle ne se déplace pas: il faut utiliser la translation
pour "le faire revenir à sa place" :
<rect x="10" y="10" width="20"
height="20"style="fill: none; stroke: black; stroke-width:
0.5;" transform="translate(-10 , -10) scale(2)"/>
Même
principe avec la rotation :
Si je veux appliquer une rotation à un objet en son centre (s'il en a un!), il
faut appliquer la formule suivante : rotate (angle, centerX, center Y).
Qui équivaut à la formule suivante :
translate(centerX, centerY) rotate (angle) translate(-centerX, -centerY)
Attention!
C'est la même chose d'écrire:
<rect x="10" y="10" width="20"
height="20"style="fill: none; stroke: black; stroke-width:
0.5;" transform="scale(2)"/>
et :
<g transform="scale(2)">
<rect x="10" y="10" width="20"
height="20"style="fill: none; stroke: black; stroke-width:
0.5;"/>
</g>
Exercices
Dessiner
en svg le dessin décrit ci-dessous, dans un Viewport de 500*500 pixels.
Attention
au stroke-with!!
Si on veut qu'il soit d'une épaisseur "normale" (de 1 pixel par exemple),
il faut donner comme valeur 1/5 = 0.2. car 0.2unité*50=1!!
<?xml
version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="500" height="500" viewBox="0 0 10 10">
<rect fill="rgb(255,255,192)" stroke="rgb(0,0,0)"
stroke-width="0" x="0"
y="0" width="10" height="10"/>
<line fill="none" stroke="rgb(0,0,0)"
stroke-width="0.02" x1="5" y1="0"
x2="5"
y2="10"/>
<line fill="none" stroke="rgb(0,0,0)"
stroke-width="0.02" x1="0" y1="5"
x2="10"
y2="5"/>
<g
transform="translate(5 5)">
<rect fill="rgb(255,0,0)" stroke="rgb(0,0,0)" stroke-width="0.02" x="-4"
y="-4" width="7" height="1"/>
<circle fill="rgb(0,0,0)" stroke-width="0.02"
cx="2" cy="3" r="1"/>
</g>
</svg>