9. Grafische elementen met SVG

SVG, Scalable Vector Graphics is gebaseerd op XML en dient om vectorafbeeldingen te definiëren en tonen.

9.1. Een eerste voorbeeld

Net zoals XML bestaat SVG uit gewone tekst en heb je dus niet meer dan een gewone teksteditor nodig om zulke bestanden te maken.
Als je wat comfortabeler wil werken, kan je een grafisch programma zoals Inkscape gebruiken.

Je hebt de keuze om een afzonderlijk bestand te maken met extensie *.SVG of om SVG-objecten in te bedden in een HTML-pagina.

Bekijk de broncode van deze voorbeelden:

Nog een mogelijkheid: toon een SVG-bestand in een iframe in een HTML-pagina.

In de voorbeelden hieronder gebruiken we de tweede methode, SVG-objecten ingebed in de HTML-pagina.

9.2. De voorgedefinieerde objecten

Je kan je kunstwerk beginnen met verscheidene basisvormen, die hieronder gedefinieerd worden.
Tussen haakjes: de meeste voorbeelden komen van w3schools

9.2.1. Rechthoek

De basiscode voor een gevulde rechthoek is: <rect width="300" height="100" style="fill:rgb(0,0,255)" />
Behalve breedte en hoogte kan je ook de positie van de linkerbovenhoek meegeven: <rect x="50" y="20" width="150" height="150" style="CSS-opties" />
Bovendien kan je de hoeken afronden: <rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="CSS-opties" />

Verder kan je heel wat stijlkenmerken toevoegen achter style=

  • fill:kleur waarbij kleur = kleurnaam (bv: red), hexadecimale code (bv:#FF0000) of functie, bv. rgb(255,0,0)
  • stroke:kleur met als kleur ook hier de naam, code of functie rgb()
  • stroke-width:n waarbij n = positief geheel getal
  • fill-opacity:n waarbij n = decimaal getal tussen 0 en 1. Bepaalt de doorzichtigheid van de vulling.
  • stroke-opacity:n met n = decimaal getal tussen 0 en 1. Bepaalt de doorzichtigheid van de rand.
  • opacity:n met n = decimaal getal tussen 0 en 1 bepaalt de doorzichtigheid van het hele object.

Ter illustratie kan je de broncode van dit voorbeeld bestuderen.

9.2.2. Cirkel en ovaal

De basiscode voor een cirkel is: <circle cx="50" cy="60" r="40" style="CSS-opties" /> waarbij

  • cx en cy de (x,y) coördinaten van het middelpunt van de cirkel aangeven
  • r is de straal van de cirkel
  • bij een ovaal gebruik je het woord ellipse en heb je niet één straal, maar twee, een horizontale rx en een verticale ry

De CSS-opties zijn dezelfde als die van een rechthoek:

  • fill:kleur waarbij kleur = kleurnaam (bv: red), hexadecimale code (bv:#FF0000) of functie, bv. rgb(255,0,0)
  • stroke:kleur met als kleur ook hier de naam, code of functie rgb()
  • stroke-width:n waarbij n = positief geheel getal
  • fill-opacity:n waarbij n = decimaal getal tussen 0 en 1. Bepaalt de doorzichtigheid van de vulling.
  • stroke-opacity:n met n = decimaal getal tussen 0 en 1. Bepaalt de doorzichtigheid van de rand.
  • opacity:n met n = decimaal getal tussen 0 en 1 bepaalt de doorzichtigheid van het hele object.

Als voorbeeld kan je de broncode van deze pagina bekijken.

9.2.3. Veelhoek

Een veelhoek heeft minstens 3 zijden en voor elke zijde moet je de coördinaten van het hoekpunt opgeven.
bv: <polygon points="200,10 250,190 160,210" style="CSS-opties" />

De CSS-opties zijn dezelfde als die van een rechthoek met eentje extra:

  • fill:kleur waarbij kleur = kleurnaam (bv: red), hexadecimale code (bv:#FF0000) of functie, bv. rgb(255,0,0)
  • stroke:kleur met als kleur ook hier de naam, code of functie rgb()
  • stroke-width:n waarbij n = positief geheel getal
  • fill-opacity:n waarbij n = decimaal getal tussen 0 en 1. Bepaalt de doorzichtigheid van de vulling.
  • stroke-opacity:n met n = decimaal getal tussen 0 en 1. Bepaalt de doorzichtigheid van de rand.
  • opacity:n met n = decimaal getal tussen 0 en 1 bepaalt de doorzichtigheid van het hele object.
  • fill-rule:nonzero/evenodd waarbij nonzero = vul de hele binnenkant van de veelhoek en evenodd = laat het omlijnde hart van de vorm ongevuld

Ter illustratie kan je de broncode van dit voorbeeld bestuderen.

9.2.4. Lijn

Met line maak je een lijnstuk: <line x1="5" y1="5" x2="200" y2="200" style="stroke:red;stroke-width:2" />
waarbij

  • (x1, y1) de positie van het beginpunt bepaalt;
  • (x2, y2) de positie van het eindpunt aangeeft;
  • enkel de lijn-eigenschappen (stroke) toegepast kunnen worden.

Met polyline maak je een vorm die enkel bestaat uit rechte lijnstukken, een trapvorm bijvoorbeeld:
<polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160" style="fill:yellow;stroke:red;stroke-width:4" />

9.2.5. Een pad tekenen

Om een pad te tekenen begin je met path d= en vervolgens komen allemaal coördinaten met een letter voor.
Die letter bepaalt wat er vanaf/tot die coördinaat moet gebeuren:

  • M of m: moveTo, bepaalt het beginpunt van het pad
  • L of l: lineTo teken een lijnstuk tot dit punt
  • H of h: horizontalLineTo tekent indien mogelijk een horizontale lijn naar de opgegeven coördinaat
  • V of v: verticalLineTo tekent indien mogelijk een verticale lijn naar de opgegeven coördinaat
  • C of c: curveTo tekent een curve naar de opgegeven coördinaat
  • S of s: smoothCurveTo
  • Q of q: quadratic Bézier curve
  • T of t: smooth quadratic Bézier curve
  • A of a: ellipticalArc
  • Z of z: closePath, verbindt de laatst opgegeven coördinaat met het beginpunt.

Gebruik je hoofdletters, dan ben je bezig met absolute posities en kleine letters betekenen relatieve posities.

9.2.6. Tekst

Tekst zet je tussen een begin- en eindtag text: <text x="0" y="15" fill="red">SVG is leuk!</text>

Om tekst te verdelen over meer regels bestaat tag tspan:
<text x="10" y="20" style="fill:red;">meer regels:
  <tspan x="10" y="45">Dit is een regel</tspan>
  <tspan x="10" y="70">Nog een regel</tspan>
</text>

Bovendien kan je tekst als een link gebruiken:
<svg height="30" width="200" xmlns:xlink="http://www.w3.org/1999/xlink">
  <a xlink:href="http://www.w3schools.com/svg/" target="_blank">
   <text x="0" y="15" fill="red">SVG is leuk!</text>
  </a>
</svg>

9.3. Speciale effecten

Je bent uiteraard niet beperkt tot een effen vulling en een simpele omtreklijn.

9.3.1.Lijneigenschappen

De meeste lijneigenschappen kan je zowel onafhankelijk toevoegen, bv. stroke="black" als in de stijleigenschappen, bv. style="stroke:black;".

De eigenschappen zijn:

  • stroke: lijnkleur, waarbij de kleur een kleurnaam (bv: red) kan zijn, de hexadecimale code (bv:#FF0000) of de functie, bv. rgb(255,0,0)
  • stroke-width="n", dikte van de lijn waarbij n = positief geheel getal
  • stroke-linecap: het uiteinde van een lijnstuk kan een beetje afgevlakt zijn (butt), afgerond (round) of recht (square).
    Bekijk de broncode van dit voorbeeld, waarbij drie lijnstukken gegroepeerd werden.
  • stroke-dasharray: om stippellijnen te maken; je geeft de lengte van de streepjes en de spaties ertussen op en daarmee wordt de stippellijn samengesteld.
    Een voorbeeld ter verduidelijking.

9.3.2. Filters

Met filters kan je heel mooie speciale effecten aan een afbeelding toevoegen, maar ze worden nog niet volledig ondersteund door alle browsers.
Een voorbeeld van w3.org en een overzicht, deels met behulp van andere W3 voorbeelden.

  • feBlend in1="" in2="": vermeng, 'blend' afbeelding of filter in1 met afbeelding of filter in2
  • feColorMatrix type="matrix" values="[matrix met cijfers]": filter om kleuren te transformeren volgens een opgegeven matrix.
  • feComponentTransfer: pas het rode, blauwe, groene of alfakanaal van de originele afbeelding aan
  • feComposite: leg een tweede afbeelding (overlay) over de eerste
  • feConvolveMatrix: wissel kleurpixels volgens een opgegeven matrix
  • feDiffuseLighting:
  • feDisplacementMap: verplaatst de pixels uit een afbeeldingskanaal
  • feFlood x="50%" y="150" width="40" height="20" flood-color="grey" flood-opacity=".5": zet een gekleurd rechthoekje 40x20 op de originele afbeelding
  • feGaussianBlur stdDeviation="4" : vervaag met 4 pixels
  • feImage:
  • feMerge:
  • feMorphology:
  • feOffset dx="4" dy="4": maak een drop shadow met verschuiving, offset, 4 px naar rechts en naar beneden; zie voorbeeld
  • feSpecularLighting: zet een lichtspot op de afbeelding
  • feTile: maak een patroon van de afbeelding
  • feTurbulence: left een gekleurd vervormingspatroon op de afbeelding
  • feDistantLight: zet een lichtspot op de afbeelding
  • fePointLight: zet een lichtspot op de afbeelding
  • feSpotLight: zet een lichtspot op de afbeelding

Werkwijze om filters te gebruiken:

1. Definieer de filter, bv:
<defs>
 <filter id="mijnFilter">
   <feGaussianBlur stDeviation="2" />
 </filter>
</defs>

2. Pas de filter toe via een CSS-stijl:
style = "filter:url(#mijnFilter);"

Om de randen van een afbeelding te vervagen bv. gebruik je een 'Gaussian blur'. Bestudeer het voorbeeld.

9.3.3. Lineaire en radiale verlooptinten

Een verlooptint of gradient is een geleidelijke overgang van een beginkleur naar een eindkleur.
Die overgang kan lineair gebeuren, van de ene kant naar de andere, of radiaal, vanuit het middenpunt.

Net zoals bij filters zal je eerst de verlooptint definiëren en daarna pas toepassen op een element.

Een voorbeeld van zo'n definitie is:
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
 <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
 <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>

Waarbij:

  • (x1, y1) het beginpunt van de verlooptint aangeeft en (x2,y2) het eindpunt. Met x2="100%" krijg je een horizontale verlooptint, met y2="100%" een verticale.
  • je minstens 2 stop-tags hebt: een begin- en een eindkleur. Je kan er ook meer opgeven, dan krijg je extra tussentinten.

In het element zal je toevoegen: style="fill:url(#grad1);". Bekijk het voorbeeld, waar er nog tekst op de vorm met verlooptint staat.

Op gelijkaardige wijze maak je een radiale verlooptint, alleen begin je met radialGradient en geef je andere coördinaten op:
<radialGradient id="grad2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
waarbij:

  • (cx,xy) de buitenste rand van de verlooptint aangeeft;
  • r de straal;
  • (fx,fy) de binnenste ring van de verlooptint aangeeft.

Bekijk weer de broncode van het voorbeeld.

9.3.4. Groeperen

Met g kan je verscheidene elementen groeperen. g kan als attributen hebben:

  • id="": de ID voor de groep
  • fill="kleur": de vulkleur voor de groep
  • En verder alle stijlkenmerken die de elementen in de groep kunnen hebben.

Bekijk de broncode van dit kleine voorbeeldje met paden

9.3.5. Transformeren

Met stijleigenschap transform kan je elementen draaien, scheeftrekken, van formaat veranderen, enz.

vb: gedraaide tekst: <text x="0" y="15" fill="red" transform="rotate(30 20 40)">SVG is leuk</text>

De mogelijke opties na transform= – of in een stijldefinitie na transform: – zijn:

  • translate(x y): verplaats met x pixels naar rechts en y pixels naar beneden
  • scale(x y): vergroot – of bij negatieve waarden verklein – met x keer in de breedte en y keer in de hoogte
  • rotate(a [x y ]): draai a graden rond (0,0) als x en y niet gegeven zijn, anders rond punt (x, y).
  • skewX(a): trek schuin met a graden in de breedte.
  • skewY(a): trek schuin met a graden in de hoogte.

9.4. SVG en XML

SVG is gebaseerd op XML en dus kan je ook XML-gegevens tonen in een SVG-bestand; we bekijken deze techniek aan de hand van een voorbeeld.
Download om te beginnen leningen.xml (rechtsklik en opslaan), voor deze gegevens willen we een grafiek maken.

We imbedden de svg in HTML, dan kunnen we makkelijk CSS gebruiken voor de opmaak.
Bekijk de broncode van deze beginsituatie.

Vervolgens wordt het XML-bestand geladen en een eerste tekst eruit getoond, zie voorbeeld.

En dan tekenen we de grafiek, zie volgende voorbeeld.

Of mag het wat meer fancy, zoals hier.