Referências

Modelos Base

Um documento «standalone» tem o seguinte conteúdo:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="..." height="..."
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- conteúdo do documento SVG -->
</svg>

Num documento HTML (ou outro…), é possível embeber diretamente conteúdo SVG com:

<svg width="..." height="..."
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- conteúdo do elemento SVG -->
</svg>

Objetos Básicos

  • Linha reta entre x1,y1 e x2,y2: <line x1 = "..." y1 = "..." x2 = "..." y2 = "..." ... />

  • Retângulo em x,y e de tamanho width x height: <rect x = "..." y = "..." width = "..." height = "..." ... />

  • Círculo de centro cx,cy e raio r: <circle cx = "..." cy = "..." r = "..." ... />

Caminhos

<path d = "..." />

onde o atributo d define as operações de construção de caminho. Um caminho é construído com as seguintes operações básicas: A partir do ponto atual,

  • mover para x,y: M x y ou m x y

  • linha para x,y: L x y ou l x y;

  • quadrática para x,y com controlo em cx,cy: Q cx cy x y ou q cx cy x y

  • cúbica para x,y com controlos cx1,cy1 e cx2,cy2: C cx1 cy1 cx2 cy2 x y ou c cx1 cy1 cx2 cy2 x y

  • fechar para o ponto inicial Z ou z

A diferença entre os comandos M,L,Q,C,Z e m,l,q,c,z é que no primeiro caso as coordenadas são absolutas (no espaço do objeto) enquanto que no segundo (com movimentos em minúsculas) as coordenadas são relativas ao ponto atual.

Exemplos

Usando coordenadas absolutas (no espaço do objeto):

<path stroke = "black" fill = "none" d="
    M 0 50
    Q 50 0 100 50
    Q 50 100 0 50
    M 25 40
    L 75 60
    L 75 40
    L 25 60
    L 25 40 "/>

produz

Com coordenadas relativas (ao ponto corrente):

<path stroke = "black" fill = "none" d="
    m 0 50
    q 50 -50 100 0
    q -50 50 -100 0
    m 25 -10
    l 50 20
    l 0 -20
    l -50 20
    l 0 -20 " />

também produz

Hierarquias de Objetos

Uma hierarquia é formada agrupando objetos.

Um grupo é um objeto gráfico formado por vários sub-objetos, que passam a ser trabalhados como um objeto básico.

Por exemplo:

  • rosto

    • contorno

    • nariz

    • boca

    • olho esquerdo

    • olho direito

<g>
    <!-- rosto -->
    <!-- contorno -->
    <!-- nariz -->
    <!-- boca -->
    <!-- olho esquerdo -->
    <!-- olho direito -->
</g>

Em concreto,

resulta de

<svg width = "100" height = "100">
    <!-- rosto -->
    <g stroke = "red" fill = "crimson"
       transform = "translate(50,50)
                    rotate(15)
                    translate(-50,-50)">
        <!-- contorno -->
        <circle cx = "50" cy = "50" r = "45" fill = "none"/>
        <!-- nariz -->
        <path d = "
            M 50 33
            l -10 33
            l 20 0" />
        <!-- olho esquerdo -->
        <circle cx = "33" cy = "35" r = "10" />
        <!-- olho direito -->
        <circle cx = "66" cy = "35" r = "10" />
        <!-- boca -->
        <rect x = "33" y = "70" width = "33" height = "5" />
    </g>
</svg>

NB a transformação e os atributos de traço e enchimento estão definidas no grupo e são herdadas pelos descendentes. No entanto o sub-elemento contorno não é «pintado» porque define explicitamente fill = "none" .

Reutilizar objetos gráficos

Continuando com o exemplo acima, se agora pretendermos dois rosto em vez de um só, podemos copiar o grupo e mudar apenas alguns atributos na cópia. No entanto esta forma de modelar é (fortemente) desaconselhada. O procedimento correto consiste em

  1. definir (em <defs>) e identificar (id = "...") um objeto «modelo» (no sentido de template, e não de model), que não $1 $2ostrado;

  2. usar (<use xlink:href= "#…​" />) esse «modelo»;

Concretamente:

resulta de

<svg width = "256" height = "100"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Definições de objetos «moldes» -->
    <defs> <!-- o que está aqui não é diretamente desenhado -->
        <!-- Grupo «rosto» -->
        <g id = "rosto">
            <circle cx = "50" cy = "50" r = "45" fill = "none"/>
            <path d = "
                M 50 33
                l -10 33
                l 20 0" />
            <circle cx = "33" cy = "35" r = "10" />
            <circle cx = "66" cy = "35" r = "10" />
            <rect x = "33" y = "70" width = "33" height = "5" />
        </g>
    </defs>
    <!-- pintar um rosto com «steelblue» -->
    <use xlink:href = "#rosto"
         stroke = "steelblue" fill = "steelblue"/>
    <!-- pintar um rosto com «crimson» e posicioná-lo à direita -->
    <use xlink:href = "#rosto"
         stroke = "crimson" fill = "crimson"
         transform = "translate(100,0)"/>
</svg>

Transformações

As transformações são definidas pelo atributo transform = "..." que pertençe a qualquer objeto gráfico:

  • translação: transform = "translate(dx,dy)"

  • rotação: transform = "rotate(deg)"

  • escala: transform = "scale(sx,sy)"

  • composição: obtém-se encadeando várias transformações. Por exemplo: transform = "rotate(35)scale(0.5, 2.1)" faz primeiro a transformação de escala e depois a rotação (nb que as transformações são aplicadas da direita para a esquerda);

Tintas

As cores sólidas são definidas pela norma CSS Color Module Level 3.

A aplicação de gradientes e de mosaicos é semelhante e segue o seguinte processo de dois passos:

  1. É definido (em <defs>) um gradiente (<linearGradient>, <radialGradient>) ou um «padrão» (<pattern>) [por exemplo <linearGradient id = "grad1" ... >]

  2. No objeto que se pretende pintar, define-se o atributo de enchimento

Por exemplo, a figura

resulta de

<svg width="640px" height="120px">
    <defs>
        <linearGradient id="grad1">
            <stop
                offset="0"
                stop-color="khaki" />
            <stop
                offset="1"
                stop-color="steelblue" />
        </linearGradient>
    </defs>
    <rect
        rx="4"
        x="0" y="0"
        width="640" height="120"
        fill="url(#grad1)" />
</svg>

Como fica ilustrado neste exemplo, os pontos de paragem de um gradiente (linear ou circular) são sub-elementos do gradiente.

A aplicação de mosaicos é semelhante:

resulta de

<svg width="640" height="120">
    <defs>
        <pattern id="pat1"
            x="0" y="0" width="8" height="8" patternUnits="userSpaceOnUse">
                <line x1 = "0" y1 = "0" x2 = "8" y2 = "8" stroke = "crimson" />
                <line x1 = "0" y1 = "8" x2 = "8" y2 = "0" stroke = "steelblue" />
        </pattern>
    </defs>
    <rect rx="4" x="0" y="0" width="640" height="120" fill="url(#pat1)" />
</svg>

Textos

Um texto é aplicado com o elemento <text> e as propriedades da fonte são especificadas pela norma CSS Fonts Module Level 3.

Em particular

E Pluribus Unum

resulta de

<svg width="128" height="24" style="background:ghostwhite">
    <text
        x="1" y="22"
        font-size="18"
        font-family="serif"
        fill="crimson">
    E Pluribus Unum
    </text>
</svg>

SVG e CSS

Como a norma SVG é uma das principais componentes do HTML5, interage bem com as restantes componentes. Para a computação gráfica interessa em especial a norma (e os elementos) que dizem respeito ao aspeto dos documentos: Cascading Style Sheets.

Além das cores, também a especificação das fontes pode ser feita através das classes CSS:

veni vidi vici

resulta de

<svg width="180" height="24">
    <style>
        .altfont {
            fill: steelblue;
            font-size: xx-large;
            font-family: cursive;
        }
    </style>
    <text x="1" y="22" class="altfont">
    veni vidi vici
    </text>
</svg>