!

Dette materialet blir ikke lenger vedlikeholdt. Du vil finne oppdatert materiale på siden: http://borres.hiof.no/wep/

SVG
Børre Stenseth
? Browser Support ?
HTML >SVG

SVG

Hva
SVG, Scalar Vector Graphics

SVG [1] skal være en del av HTML5. Det vil si at vi skal kunne skrive et svg element rett inn i HTML-koden, uten namespace, embed eller noe annet hokus pokus. Noen av eksemplene på denne modulen 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 det mest nærliggende alternativet for de fleste. Det samme gjelder animasjon av geometriske elementer.

Merk at HTML5 tilbyr også canvas som en tegneomgivelse for blandt annet vektorgrafikk.

Du kan tegne og få SVG-output i flere verktøy, f.eks: Abode Illustrator: [2]

Et rektangel

Et enkelt rektangel kan se slik ut:

Et enkelt eksempel

Koden er slik:

<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>

Vi har laget et svg-element som beslaglegger et område på 5x5 cm. Det adresseområdet, viewBox, 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. 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.

Du kan også av "arkeologiske" årsaker se, og inspisere, denne som en egen SVG-fil, laget før HTML5:

Se gammel versjon i en nettleser med SVG-kapasitet http://www.it.hiof.no/~borres/dw/svg/svgdok1.svg

Flagget

Det norske flagget kan lages slik:

Flaggets proposjoner: Horisontalt: 6R 1H 2B 1h 12R=22 Vertikalt: 6R 1H 2B 1H 6R=16 17.mai

Koden er slik:

<svg width="300px" height="300px"  viewBox="0 0 300 300">
  <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>

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ørste, 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:

En smiley

Koden er slik:

<svg width="200px" height="200px"  viewBox="0 0 400 400">
  <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>

Hva så med munnen. Dette er litt mer utfordrende. Vi må på en eller annen måte kunne forme en kurve. Den enkleste 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:

En smiley

Koden er slik:

<svg width="200px" height="200px"  viewBox="0 0 400 400">
  <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>

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:

litt ymse tekst Hallo dette ble skjevt Ja du store

Koden er slik:

<svg width="400px" height="400px"  viewBox="0 0 400 400">
  <desc>litt ymse tekst</desc>
<g transform="translate(200,200)">
   <text id="TextElement1" x="0" y="0"
      transform="rotate(-30)"
      font-family="Verdana" font-size="20" 
      fill="blue" stroke="none"> 
      Hallo dette ble skjevt
   </text>
   <text id="TextElement2" 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>

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 (reload siden):.

litt dynamisk tekst Hallo

Koden er slik:

<svg width="300px" height="300px"  viewBox="0 0 300 500">
  <desc>litt dynamisk tekst</desc>
<g transform="translate(200,200)">
   <text id="TextElement3" 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>
En annen fil med tekstanimasjon http://www.it.hiof.no/~borres/dw/svg/kaos.html

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. (reload siden for å animere)

En smiley

Koden er slik:

<svg width="200px" height="200px"  viewBox="0 0 400 400">
<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>

Kartdata

SVG kan fungere interaktivt.

Se kartet http://www.it.hiof.no/~borres/dw/svg/norgehtml5.html

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):


<svg width="100%" height="100%" viewBox="0 0 11939 15026">
<desc>Norgeskart</desc>

<script type="text/ecmascript"> 
	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.firstChild);
	}
</script>


<g transform="translate(250,1250)">
<text id="TextElement11" x="0" y="0" font-family="Verdana" font-size="500" fill="black">
Norge
</text>
</g><g transform="translate(250,1850)">
<text id="TextElement12" x="0" y="0" font-family="Verdana" font-size="350" fill="black">
6551 punkter
</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" stroke-width="10"/>
<path onmouseover="kommune_click(evt)" id="Sarpsborg" 
      d="M 3599,1314  L 3594,1324  ... z" fill="none" stroke="black" stroke-width="10"/>
<path onmouseover="kommune_click(evt)" id="Sør-Varanger" 
      d="M 11642,13462  L 11633,13471 ... z" fill="none" stroke="black" stroke-width="10"/>
</g>
</g>
</svg>

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

Effekter

Filterdefinisjonen i koden nedenfor er lånt fra Eddie Traversa's artikkel: "Scalable Vector Graphics: The Art is in the Code", fra www.webreference.com.

Koden er slik:

<svg width="200px" height="200px" viewBox="0 0 400 400">
<defs>
   <filter id="metallic">
      <feGaussianBlur result="blurredAlpha" in="SourceAlpha" stdDeviation="3"/>
      <feOffset result="offsetBlurredAlpha" in="blurredAlpha" dx="2" dy="1"/>
      <feDiffuseLighting result="bumpMapDiffuse" in="blurredAlpha" surfaceScale="5"
         diffuseConstant="0.5"
         style="lighting-color:rgb(255,255,255)">
         <feDistantLight azimuth="135" elevation="60"/>
      </feDiffuseLighting>
      <feComposite result="litPaint" in="bumpMapDiffuse" operator="arithmetic" k1="1"
         k2="0" k3="0" k4="0" in2="SourceGraphic"/>
      <feSpecularLighting result="bumpMapSpecular" in="blurredAlpha" surfaceScale="5"
         specularConstant="0.5" specularExponent="10"
         style="lighting-color:rgb(255,255,255)">
         <feDistantLight azimuth="135" elevation="60"/>
      </feSpecularLighting>
      <feComposite result="litPaint" in="litPaint" operator="arithmetic" k1="0"
         k2="1" k3="1" k4="0" in2="bumpMapSpecular"/>
      <feComposite result="litPaint" in="litPaint" operator="in" in2="SourceAlpha"/>
      <feMerge>
      <feMergeNode in="offsetBlurredAlpha"/>
      <feMergeNode in="litPaint"/>
      </feMerge>
   </filter>
</defs>
<g transform="translate(200,200)">
<circle cx="0" cy="0" r="100" 
   style="filter:url(#metallic);fill:yellow;stroke:rgb(11,11,13);stroke-width:1"/>
<circle cx="40" cy="-40" r="20" fill="rgb(10,10,10)"/>
<circle cx="-40" cy="-40" r="20" fill="rgb(10,10,10)"/>
<path
   d="M-40.0 40 C-30.0 50 -20 60 0 60 20 60 30 50 40 40 "
   style="fill:none;stroke:rgb(11,11,13);stroke-width:6"/>
</g>
</svg>
Referanser
  1. SVG (Scalable Vector Graphics) W3C www.w3.org/Graphics/SVG 14-03-2010
  1. Adobe Illustrator Adobe www.adobe.com/products/illustrator/main.html 14-03-2010
Vedlikehold
Børre Stenseth, revidert april 2011
( Velkommen ) HTML >SVG ( Bildesrie )