SVG
Børre Stenseth

Transformasjoner

Hva

Vi kan transformere deler av en SVG-figur. De tre grunnleggende operasjonene er translasjon, rotasjon og skalering.

For de som har programmert 2D eller 3D-grafikk i ulike settinger er dette kjente operasjoner, og vi vet at de utføres ved hjelp av matriseoperasjoner. I følge lineær algebra kan vi kombinere transformasjoner ved å multiplsere matriser som beskriver hver av deltransformasjonene. Vi kan i tillegg til basistransformasjonene spesifisere spesielle matriser for spesielle behov. Mozilla Debelopers Network [1] har materiale om dette.

Det er to paraleller til den tenkingen vi gjør i tradisjonell grafisk databehandling:

  • Vi kan assosiere SVG-strukturen til en scenegraf. Det vil si at vi kan plante transformasjoner i noder og disse vil arves av barna (og barnebarna). Det vil si at legger vi en translasjon inn i et g-element så vil det ha konsekvenser for all geometri i elementene som er barn av dette g-elementet. Det er slik vi også tenker når vi bruker CSS-regler som jo også er arvelige.
  • Matrise begrepet blir tydelig når vi programmerer mot f.eks. OpenGL. Vi bruker translate(), scale() og rotate() for å bygge nye sammensatte matriser og vi bruker pushMatrix() og popMatrix() for å ta vare på sammensatte matriser (resultatet av matrisemultiplikasjoner). Det vil si at vi holder styr på en stack av akkumulerte matriser og sørger for at den som skal gjelde (currentMatrix) alltid ligger på toppen. Vi kan da på en måte si at vi realiserer trestukturen av transformasjoner dynamisk i koden.

Hvis assosiasjonene ovenfor er fremmede så er det likevel ganske kurant å bygge transformasjoner inn i en SVG-struktur. Et lite eksempel:

_demo
<svg id="demo1" style="background-color:beige" 
     width="400px" height="300px"  viewBox="0 0 400 300">
<g stroke="black" stroke-width="2">
    <g transform="translate(100,100)" fill="red">
        <rect x="0" y="0" width="20" height="20"/>
        <rect x="24" y="0" width="20" height="20"/>        
    </g>
    <g transform="translate(200,100)" fill="blue">
        <rect x="0" y="0" width="20" height="20"/>
        <rect x="12" y="0" width="20" height="20" transform="scale(3)"/>        
    </g>    
    <g transform="translate(100,200)" fill="yellow">
        <rect x="0" y="0" width="20" height="20" transform="rotate(45)"/>
        <rect x="24" y="0" width="20" height="20" transform="rotate(45)"/>        
        <g  transform="translate(100,0)" fill="green">
            <g> 
                <rect x="0" y="0" width="20" height="20" />
                <rect x="12" y="0" width="20" height="20" transform="scale(3,1)"/>
            </g>        
        </g>
    </g>
</g>
</svg>
Referanser