SVG
Moduler > XML > Noen XML-språk >SVG

SVG

Hva
Noen demonstrasjoner av SVG, Scalar Vector Graphics

Statusen til SVG er i skrivende stund, august 2006, noe uklar. Fra betydelig optimisme for noen år siden ser det ut til at ulike og manglende installasjoner i nettleserne har lagt en viss demper på entusiasmen. Mozilla og Opera har installert SVG i selve nettleseren, mens MSIE fordrer en plugin. Noen av eksemplene på disse sidene kan feile i noen nettlesere.

Tradisjonelt har illustrasjoner på vevsider vært rastergrafikk i form av gif, jpg eller png bilder. Dersom en er ute etter illustrasjoner som er bygget opp av tegningselementer i form av geometriske figurer, rotert tekst eller lignende er trolig Flash fra Macromedia det mest nærliggende alternativet for de fleste. Det samme gjelder animasjon av geometriske elementer. Plugin for flash har vært og er en kurant løsning med enkel installasjon.

SVG er en åpen standard støttet av W3C som er et alternativ i mange situasjoner. I dag er det slik at også SVG fordrer en plugin. Du må installere denne eller du kan forsøke nettleseren Amaya, som er den nettleseren W3C benytter for å teste blandt annet SVG. Du trenger en plugin for å arbeide med eksemplene nedenfor.

  • Scalable Vector Graphics: [1]
  • Plugin for SVG. Generelt: [2] eller direkte til Adobe: [3]
  • Noen gode råd når du skal generere SVG-filer fra et CGI-script: [4]
  • Du kan tegne og få SVG-output i flere verktøy. Høgsskolen har lisens for: Abode Illustrator: [5]

Vi ønsker selvsagt å inludere SVG i vevsider som også består av andre språkelementer. Typisk vil vi ha en side med XHTML og SVG, eller XHTML, SVG og MathML, eller XHTML, SVG og RDF. Mer om dette senere. Vi starter med noen rene SVG-dokumenter for å illustrere noen grunnleggende prinsipper.

Et rektangel

Et enkelt SVGdokument, svgdok1.svg, kan se slik ut:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="5cm" height="5cm"  viewBox="0 0 50 50"
  xmlns="http://www.w3.org/2000/svg">
  <desc>Et enkelt eksempel</desc>
  <rect x="10" y="10" width="20" height="20" 
    fill="yellow" stroke="blue" stroke-width="2"/>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgdok1.svg

Vi har etablert en fil med riktig dtd, og vi har et rotelement: svg. Dette elementet er kvalifisert via et namspace og vår SVG-tegning beslaglegger et område på 5x5 cm. Det adresseområdet vi har definer er 50 X 50. Det vil si at når vi beskriver figurer i dette adresseområdet, så mappes dette til det 5x5 cm store området på siden (skjermen). Det eneste vi tegner ut er et rektangle som er fylt med gult og med blå kant(, så svenskene får sitt). Du kan eksperimentere med koordinatene til rektangelet og til svg-elementet for å se hvordan mappingen via viewBox fungerer.

Default er origo oppe til venstre i det koordinatsystemet som etableres.

Flagget

Det norske flagget kan lages slik:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300px" height="300px"  viewBox="0 0 300 300"
  xmlns="http://www.w3.org/2000/svg">
  <desc>
  Flaggets proposjoner:
  Horisontalt: 6R 1H 2B 1h 12R=22
  Vertikalt:   6R 1H 2B 1H 6R=16
  </desc>
    <g transform="translate(20,50)">
      <rect x="0" y="0" width="220" height="160" 
      fill="red" stroke="none" stroke-width="0"/>
      
      <rect x="0" y="60" width="220" height="40" 
      fill="white" stroke="none"/>
      <rect x="60" y="0" width="40" height="160" 
      fill="white" stroke="none"/>
      
      <rect x="0" y="70" width="220" height="20" 
      fill="blue" stroke="none"/>
      <rect x="70" y="0" width="20" height="160" 
      fill="blue" stroke="none"/>
      
      <g transform="translate(0,225)">
        <text id="TextElement" x="0" y="0"
          font-family="Verdana" font-size="25" 
          fill="black" stroke="none"> 
          17.mai
        </text>
      </g>
   </g>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgnoflag.svg

Vi har tatt i bruk elementet g og vi bruker det til å flyttet origo mens vi "tegner", translate. Teksten som kommer under flagget er lagt inn i et eget g-element. Siden dette er omsluttet av det andre vil hele tegningen, flagget og teksten, kunne forskyves ved å endre parametrene til translate i det først, ytterste, g-elementet.

Smiley

En blid smiley har litt mer komplisert form enn de rektanglene vi har brukt ovenfor. Vi vil se at den runde hodeformen og øynene lar seg realisere med elementer som heter circle. Uten munn kan en smiley lages slik, svgsmiley1.svg:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="200px" height="200px"  viewBox="0 0 400 400"
  xmlns="http://www.w3.org/2000/svg">
  <desc>En smiley</desc>
  <g transform="translate(200,200)">
  <circle cx="0" cy="0" r="100" fill="yellow"/>
  <circle cx="40" cy="-40" r="20" fill="black"/>
  <circle cx="-40" cy="-40" r="20" fill="black"/>
  </g>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgsmiley1.svg

Hva så med munnen. Dette er litt mer utfordrende. Vi må på en eller annen måte kunne forme en kurve. Den enklsete måten å beskrive en kurve på er å angi punktene på kurven. I SVG kan vilkårlige polygoner (mangekanter) beskrives ved den vi kan kalle en blyant-metafor. Vi har en kommando for å løfte blyanten og flytte den og en kommando for å trekke en strek. Elementet

<path d="M 0,0 L 10,0 5,10 z"
      fill="none" stroke="black" stroke-width="1"/>

vil tegne en trekant. Attributten d(ata) sier at vi skal M(ove) blyanten til 0,0, så skal vi lage L(ine) fra punkt til punkt i lista som følger. z til slutt sier at kurven skal lukkes. På grunnlag av dette kan vi foreslå følgende smiley, svgsmiley2.svg

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="200px" height="200px"  viewBox="0 0 400 400"
  xmlns="http://www.w3.org/2000/svg">
  <desc>En smiley</desc>
  <g transform="translate(200,200)">
  <circle cx="0" cy="0" r="100" fill="yellow"/>
  <circle cx="40" cy="-40" r="20" fill="black"/>
  <circle cx="-40" cy="-40" r="20" fill="black"/>
  <path d="M-40,10 L -20,30 -10,35 0,40  10,35 20,30 40,10"
        fill="black" stroke="none"/>
  </g>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgsmiley2.svg

Dette er ikke helt vellykket. Vi har mange muligheter for forbedring. Vi kan lage flere og tettere punkter, eller vi kan bruke en matematisk måte å beskrive en glattere kurve. For de som er kjent med grafisk databehandling så er det f.eks. mulig å lage Bezierkurver. Vi forfølger ikke dette her.

Tekst

Vi brukte tekst ovenfor i flaggeksempelet uten å kommentere det noe videre. Det er relativt kurant å sett ut tekst i SVG-områder. F.eks. slik, svgtext1.svg:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400px" height="400px"  viewBox="0 0 400 400"
  xmlns="http://www.w3.org/2000/svg">
  <desc>litt ymse tekst</desc>
<g transform="translate(200,200)">
   <text id="TextElement" x="0" y="0"
      transform="rotate(-30)"
      font-family="Verdana" font-size="20" 
      fill="blue" stroke="none"> 
      Hallo dette ble skjevt
   </text>
   <text id="TextElement" x="-70" y="50"
      transform="rotate(30)"
      font-family="Verdana" font-size="20" 
      fill="red" stroke="black" stroke-width="0.2"> 
      Ja du store
   </text>
</g>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgtext1.svg

Animasjon

Vi kan skape tidsstyrte animasjoner i SVG. Det er tre elementer som styrer slik animasjon. Nedenfor er de satt opp med noen typiske attributter. Du må selvsagt slå opp på SVG sidene i W3C for å få full oversikt.

<animateMotion from="0,0" to="50,50"
     begin="0s" dur="24s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" attributecode="XML"
     code="rotate" from="1" to="1440"
     begin="0s" dur="24s" repeatCount="indefinite"/>
<animateColor attributeName="fill" attributecode="CSS"
     from="blue" to="red"
     begin="0s" dur="24s" repeatCount="indefinite"/>

Vi forsøker oss på litt tekst,svgtext2.svg.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400px" height="500px"  viewBox="0 0 500 400"
  xmlns="http://www.w3.org/2000/svg">
  <desc>litt dynamisk tekst</desc>
<g transform="translate(200,200)">
   <text id="TextElement" x="-10" y="5"
      font-family="Verdana" font-size="5" 
      fill="blue" stroke="none"> 
      Hallo
      <animateMotion from="0,0" to="50,50"
         begin="0s" dur="12s"  fill="freeze" />
         <animateTransform attributeName="transform" 
         attributeType="XML"
         type="rotate" from="1" to="1440"
         begin="0s" dur="6s" fill="freeze" />
      <animateTransform attributeName="transform" 
         attributeType="XML"
         type="scale" from="1" to="15" additive="sum"
         begin="0s" dur="12s" fill="freeze" />
      <animateColor attributeName="fill" 
         attributeType="CSS"
         from="blue" to="red"
         begin="0s" dur="24s" repeatCount="indefinite"/>
   </text>
</g>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgtext2.svg
En annen fil med tekstanimasjon http://www.it.hiof.no/~borres/ml/svg/p-jungle.svg

Dersom vi skal animere, f.eks. rotere, vår smiley må vi lage en konstruksjon som roterer alle delene. Dette kan vi oppnå ved å lage et g-element som inneholder det ønskede animasjonselementet og smileybeskrivelse, svgtext3.svg:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="200px" height="200px"  viewBox="0 0 400 400"
xmlns="http://www.w3.org/2000/svg">
<desc>En smiley</desc>
<g transform="translate(200,200)">
   <g>
      <animateTransform attributeName="transform" 
      attributeType="XML"
      type="rotate" from="1" to="1440"
      begin="0s" dur="6s" fill="freeze" />
      
      <circle cx="0" cy="0" r="100" fill="yellow"/>
      <circle cx="40" cy="-40" r="20" fill="black"/>
      <circle cx="-40" cy="-40" r="20" fill="black"/>
      <path d="M-40,10 L -20,30 -10,35 0,40  10,35 20,30 40,10"
      fill="black" stroke="none"/>
   </g>
</g>
</svg>
Se denne i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/svgsmiley3.svg

Kartdata

SVG er ganske raskt.

Se kartet i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/norge.svg

Interaksjonen i kartet er realisert ved hjelp av de eventene som er definert for SVG og litt DOM-programmering. Et utdrag av kildekoden er slik: (Polygondataene er redusert):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="100%" height="100%" viewBox="0 0 11939 15026"
      xmlns="http://www.w3.org/2000/svg">
<desc>Norgeskart</desc>

<!-- ECMAScript to identify a kommune after mouseover -->
<script code="text/ecmascript"> <![CDATA[

var lastPath=null;
var markcolor="red";
var unmarkcolor="white";

function kommune_click(evt) {
  var path = evt.target;
  path.setAttribute("fill",markcolor);
  if (lastPath!=null)
    lastPath.setAttribute("fill",unmarkcolor);
  lastPath=path;
  var kommunename = path.getAttribute("id");
  var komElement=document.getElementById("KommuneElement");
  var komTextNode=document.createTextNode(kommunename);
  komElement.replaceChild(komTextNode,komElement.getFirstChild());
}
]]> </script>

<g transform="translate(250,1250)">
<text id="TextElement" x="0" y="0" font-family="Verdana" 
         font-size="500" fill="black">
  Norge
</text>
</g>

<g transform="translate(7250,7250)">
<text id="KommuneElement" x="0" y="0" font-family="Verdana" 
         font-size="500" fill="black">
  Move mouse on map
</text>
</g>
<g transform="translate(0,15026)">
  <g transform="scale(1.0,-1.0)">
    <path onmouseover="kommune_click(evt)" id="Halden" 
      d="M 3839,1188  L 3834,1257 ... z" fill="none" stroke="black"/>
    <path onmouseover="kommune_click(evt)" id="Sarpsborg" 
      d="M 3599,1314  L 3594,1324 ... z" fill="none" stroke="black"/>
    <path onmouseover="kommune_click(evt)" id="Fredrikstad" 
      d="M 3509,1154  L 3509,1171 ... z" fill="none" stroke="black"/>
    ...
  </g>
</g>
</svg>

Den komplette kildekoden finner du her: norge_svg.html.

Merk at dataene er gamle (før siste kommunesammenslåing) og det er noen feil i polygonene.

Som del av et dokument

Utgangspunktet er at vi ønsker å legge SVG-komponenter inn på en HTML-side. Det er flere måter å tenke seg dette løst på:

Vi kan tenke oss en løsning der vi rett og slett legger SVG-elementene på plass og kvalifiserer dem med namespace, De fleste lærebøkene i XML bruker slike filer om eksempel:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>mixed SVG</title>
</head>
<body>
<h1>En side</h1>
<svg xmlns="http://www.w3.org/2000/svg"
   width="5cm" height="5cm"  viewBox="0 0 50 50">
  <desc>Et enkelt eksempel</desc>
  <rect x="10" y="10" width="20" height="20" 
    fill="yellow" stroke="blue" stroke-width="2"/>
</svg>
<p>med blandet innhold</p>
</body>
</html>

Dette forutsetter at programmet som leser fila er forberedt på å generere SVG når den treffer på en slk node i DOM-treet. Nettleserne synes ikke være klare for det, og greier ikke å kople plug-ins til slik SVG-rendering.

Dersom SVG blir akseptert som en del av det normale nettlesere skal kunne handtere uten plug-in vil denne koden være den naturlige formen å inkludere SVG på.

Alternativet er å bruke det generelle <embed> </embed> elementet, slik vi gjør når vi vil legge inn andre komponenter som fordrer plug-in. Følgende element vi vise fila etbilde.svg, eventuelt tilby seg å installere plug-in først:

<embed width="100px" width="100px" src="supersmiley.svg"
       pluginspace="http://www.adobe.com/svg/viewer/install/">
Se smiley i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/ml/svg/smiley4.html

Referanser
1
SVG (Scalable Vector Graphics) W3C www.w3.org/Graphics/SVG 14-03-2010
2
3
SVG, Plugin Adobe www.adobe.com/svg/viewer/install/ 14-03-2010
4
Server-Side SVG SVG Open www.svgopen.org/2004/papers/ServerSideSurvey/ 14-03-2010
5
Adobe Illustrator Adobe www.adobe.com/products/illustrator/main.html 14-03-2010
Vedlikehold
Børre Stenseth, revidert august 2006
Nytteverdi
... Hva mener du: 1 2 3 4 5 6