Sie sind auf Seite 1von 155

Building Web Applications with SVG

David Dailey
Jon Frost
Domenico Strazzullo

Published with the authorization of Microsoft Corporation by:


OReilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, California 95472
Copyright 2012 by Jon Frost, David Dailey, Domenico Strazzullo
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form
or by any means without the written permission of the publisher.

Introduo

Scalable Vector Graphics, conhecido como SVG, o padro World Wide Web Consortium para a
interatividade grfica na web e plataformas mveis. SVG um padro maduro, lanado pela primeira
vez h mais de uma dcada e tem sido melhorado pelo W3C desde ento. SVG agora est disponvel,
por padro, em todos os navegadores modernos, bem como em mais de um bilho de dispositivos
mveis. SVG fornece maneiras de criar grficos interativos que podem ser redimensionados sem perda
de qualidade. Como HTML e HTML5, SVG coexiste em perfeita compatibilidade com tecnologias que
j so familiares para os programadores Web, como CSS, JavaScript, DOM, AJAX e, de fato, com o
prprio HTML.

Este livro fornece uma introduo abrangente para a linguagem e como us-la para a interao e
animao. O texto tambm fornece exposio a vrios e importantes pacotes e bibliotecas JavaScript,
incluindo D3, jQuery, e Pergola. Enquanto o livro no fornece uma cobertura exaustiva de todos os
recursos da linguagem SVG, ele oferece orientao essencial no uso dos seus componentes-chave.

Alm da sua cobertura de caractersticas bsicas do SVG, o livro apresenta uma grande variedade de
ferramentas de software para a criao de grficos SVG e para aprimoramento dos mesmos com as
funcionalidades do script. Voc tambm vai encontrar apresentaes slidas para temas complexos,
como animao e filtros SVG. Em muitos lugares, o livro inclui exemplos passo a passo e numerosas
referncias a exemplos e projetos de exemplos para download que voc pode explorar por si mesmo.

Testemunhos SVG

Muitas pessoas estiveram envolvidas na criao de SVG. Como parte da Introduo a este livro,
pedimos a um punhado de pessoas que estavam intimamente envolvidos na evoluo do SVG para
expor um pouco sobre o que eles pensam sobre o passado e o futuro do SVG. Aqui esto as suas
declaraes.

Jon Ferraiolo

O W3C lanou o Grupo de Trabalho Scalable Vector Graphics em 1998 para fornecer a contrapartida
grficos de vetor para HTML. O SVG WG optou por adotar para todos as mesmas abordagens gerais
que o HTML (markup, DOM, scripting, estilo), mas substituindo elementos HTML como <div>, <p>
e <span> por elementos grficos vetoriais, como <rect>, <circle> e <path>. Com vrios eventos em 2001
(aprovao da Especificao SVG 1.0, Adobe SVG Viewer verso 3 (ASV3) e agregao do ASV com o
Adobe Acrobat Reader 5), o SVG era onipresente em navegadores de desktop com o resultado que,
temporariamente, decolou a todo o vapor, com dezenas de milhares de desenvolvedores usando SVG
para vrios tipos de aplicativos grficos interativos (fluxogramas, grficos de negcios e mapeamento).
Mas a adoo do SVG caiu uma vez com a Adobe abandonando o ASV. Posteriormente, o cdigo-fonte
foi aberto e os navegadores adicionaram suporte SVG (primeiro o Mozilla, depois o WebKit). Com o
cdigo aberto, projetos "SVGWeb" comearam a apoiar as verses mais antigas do SVG em anncios do
IE6-8 e a Microsoft deu suporte a SVG no IE9, SVG, mais uma vez recuperou a ubiquidade, e os
desenvolvedores esto agora (re)descobrindo o poder dos grficos de scripts baseados no DOM.

O futuro para o SVG parece muito emocionante, especialmente quando se utiliza SVG como um
componente do HTML5. O W3C, em colaborao com as equipes que desenvolvem navegadores e
com a comunidade, est generalizando muitos das melhores caractersticas do SVG 1.0 de (por exemplo,
recorte, animao, efeitos de filtro) no CSS, para que esses recursos tambm estejam disponveis para
HTML, alm de limpar o SVG para torn-lo mais fcil de utilizar (por exemplo, remoo de exigncia
de XML para SVG). H uma discusso ativa sobre ir para o prximo nvel, com efeitos grficos vetoriais
e raster, em particular os que so capazes de alavancar CPUs. Tendo em conta os recursos de atualizao
automtica dos navegadores modernos, os desenvolvedores sero capazes de tirar proveito dos novos
recursos quase to rapidamente quanto eles so definidos.

Antecedentes: Jon Ferraiolo foi um dos principais arquitetos do SVG. Ele foi o principal autor da
submisso PGML que serviu de ponto de partida para SVG e foi o nico editor da especificao SVG
original do W3C (SVG 1.0). Enquanto empregado da Adobe Systems, Inc., ele foi o arquiteto de vrios
projetos relacionados com o SVG da Adobe, incluindo o Adobe SVG Viewer e suporte a SVG do Adobe
Illustrator. Ele agora um distinto engenheiro da IBM.

Alex Danilo

Nos primeiros dias da web, os navegadores foram mudando rapidamente e a concorrncia era feroz.
Quando o W3C enviou um convite para apresentao de propostas de grficos vetoriais para a web, veio
de encontro aos interessses de milhares de ilustradores. Finalmente, poderiam ser livre de bitmaps
antigos trazendo para a web belos grficos independentes de resoluo. Este foi o nascimento do SVG.

Como sabemos, Roma no foi construda em um dia, e ao longo dos anos, o SVG foi massageado e
afinado com perfeio por um exrcito de aficcionados entusiasmados por grficos vetoriais. O resultado
uma jia que polida e pode brilhar com cores vibrantes quando visto na luz direta.

SVG permite experincias interativas vivas que se adaptam a qualquer tamanho de exibio, uma
maneira de fazer pontes entre imagens e semnticas significativas, uma poderosa sinergia com HTML e
DOM.

Antecedentes: Alex Danilo se juntou ao Grupo de Trabalho W3C SVG no incio de 2002 e agora o
representante de sua empresa Abbra. Implementando para ambos, dispositivos mveis e web, a Abbra
est na vanguarda do desenvolvimento da especificao SVG. Alex tem produzido, muito
frequentemente, a primeira prova de conceito das novas propostas para SVG. Seu foco atual o
desenvolvimento de um rich-media SVG capaz de ser um motor para reas de aplicao multi-
plataforma especialmente em dispositivos com recursos limitados.

Cameron McCormack

Passaram-se 10 anos desde que a Recomendao do W3C para SVG 1.0 foi publicada, e estive
envolvido na comunidade SVG a maior parte desse perodo de tempo, eu posso dizer com
conhecimento em primeira mo que as fortunas do SVG definitivamente foram mistas. Isto no uma
acusao sobre a tecnologia em si, ela slida, mas um problema histrico de execuo e
disponibilidade.

No incio de 2000, houve um grande interesse pelo SVG, como evidenciado provavelmente pela
atividade na lista de discusso "SVG Developers Yahoo Group", um frum que ainda est em execuo
atualmente. Os autores foram criando visualmente ricos grficos dinmicos na web, aplicaes com
SVG antes de se tornar popular (ou possvel) de faz-lo com outra tecnologia web aberta. Que isso era
possvel na poca era, a meu ver, quase inteiramente devido ao investimento da Adobe em SVG e seu
desenvolvimento do Adobe SVG Viewer plug-in. No importava que o apoio dos navegadores para
SVG tenha sido praticamente zero ou que no existia em todos, atravs do uso da Adobe plug-in, o
SVG estava disponvel a todos. Tecnicamente no todos, claro, pois o plug-in foi limitado a
determinados sistemas operacionais e arquiteturas, mas para a maioria dos autores era bom o suficiente.

A ltima verso disponvel do Adobe plug-in, uma prvia da verso 6, foi feita em 2003. A verso pr-
lanamento foi um pouco instvel, mas demonstrou novos recursos atrativos, incluindo um modelo de
componentizao para SVG, contedo cuja principal ideia era a mesma que interessa a Garner hoje,
apesar de uma srie de falsos comeos em matria de normalizao de grupos. No entanto, por um
longo tempo aps o lanamento, nem uma palavra foi ouvida, fora da Adobe, sobre seus planos de
desenvolvimento. Isto causou uma crescente consternao dentro da comunidade de desenvolvedores do
SVG, assim como o progresso das implementaes nativas em navegadores foi lento para recuperar o
atraso com as caractersticas e desempenho do plug-in. O interesse em SVG comeou a diminuir, e a
aquisio pela Adobe da Macromedia e da plataforma Flash s serviu para alimentar ainda mais a noo
de que o SVG estava morto. Os anos seguintes foram a Idade das Trevas do SVG.

Embora implementaes nativas em navegadores melhorassem o SVG durante este tempo, houve uma
constatao pelos desenvolvedores em geral que o SVG no estava pronto para o "horrio nobre". O que
foi provavelmente o maior impedimento para autores que publicam contedo SVG foi a falta de
implementao no Internet Explorer. Com a chegada de uma verso particular do IE ou do Windows,
eu no me lembro qual, a Adobe no manteve o plug-in e este parou de funcionar completamente. Este
foi um duro golpe para os desenvolvedores, porque a Microsoft no tinha planos para implementar o
SVG em tudo, ao contrrio dos outros grandes fabricantes de navegadores que se comprometeram a
apoi-lo.

Em 2008, ocorreu um grande desenvolvimento: a adio do SVG (e MathML) para a Especificao


HTML5, o que permitiu que os autores escrevessem documentos HTML com grficos de vetor
embutidos sem ter que usar documentos "mixed-namespace" XML. Esta foi uma simplificao de boas-
vindas, mas o importante que ele ajudou a vender o SVG como sendo um elemento de primeira classe
da plataforma web.
At 2009, o mesmo ano em que a Adobe finalmente anunciou o que todos sabiam - que seu plug-in no
estava mais sendo mantido - o sentimento era de que finalmente tinha se conseguido afastar a noo de
que o SVG era uma tecnologia inadequada para publicao na web, devido intransigncia da
Microsoft. Isto ajudou o lanamento do "SVG Web", um renderizador SVG baseado em Flash
desenvolvido por uma equipe da Google. Uma vez mais, os autores tiveram uma maneira de direcionar
contedo SVG para o Internet Explorer, j que a maioria dos computadores Windows j tinha instalado
o Flash Player. O SVG Web no s forneceu uma maneira de tornar o SVG compatvel no IE, mas o fez
com uma cobertura razoavelmente completa da especificao SVG e com grande desempenho.

Mas somente em 2010 chegou o que talvez seja a notcia mais bem-vinda comunidade SVG, quando a
Microsoft anunciou uma verso prvia do Internet Explorer 9 como a primeira verso do IE com
suporte a SVG. Finalmente, seria possvel a publicao de contedo SVG utilizando tecnologias web
abertas em todos os navegadores desktop sem a necessidade de quaisquer plug-ins ou solues
alternativas. Viva!
Hoje, o SVG est mais forte ainda em sua posio. Implementaes de navegadores continuam a
melhorar aos trancos e barrancos. Grupos de padres continuam a aproximar SVG e CSS, permitindo o
uso de recursos SVG tais como filtros, padres e gradientes em documentos HTML. O Grupo de
Trabalho SVG atualmente est ocupado trabalhando na prxima grande reviso da prpria especificao
SVG para tratar de questes e adicionar recursos que foram solicitados pela perseverante comunidade
SVG ao longo dos anos. Desenvolvedores de kit de ferramentas JavaScript esto escolhendo SVG como
sua tecnologia de sada grfica.

Antecedentes: Cameron McCormack est envolvido com o SVG desde 2003 e serviu como co-editor da
especificao SVG e co-presidente do Grupo de Trabalho de SVG de 2007 at hoje. Como um
estudante de ps-graduao na Universidade de Monash, na Austrlia, Cameron tambm liderou a
implementao de SVG em Batik, s vezes chamado de "a mais extensa implementao de SVG". Desde
ento, ele passou a trabalhar na Mozilla Corporation, onde seu trabalho com SVG e outros padres web
continua.

Jeff Schiller

Eu me envolvi com Scalable Vector Graphics (SVG) na poca em que o Firefox estava planejando enviar
a sua primeira aplicao parcial do SVG completa no Firefox 1.5. Naquela poca, o suporte nativo foi
principalmente uma curiosidade, uma vez que havia um plug-in para navegador (Adobe SVG Viewer) e
alternativas para grficos vetoriais e sons em aplicaes web (Flash da Macromedia). Mas o que me
intrigou sobre o suporte a SVG nativo foi a integrao com HTML: um DOM, um modelo de evento,
script em JavaScript, estilizao com CSS. Isto permitiria que as aplicaes grficas web pudessem tirar
vantagem do AJAX, que estava acontecendo no momento: ricas aplicaes dinmicas que trabalhavam
em todos os navegadores sem um plug-in.

Mais implementaes SVG completas comearam a aparecer, primeiro no Opera, que definiu o
padro para suporte completo, em seguida, em WebKit e, finalmente, no Internet Explorer, tornando-o
onipresente em toda a web e mobiles. Como o suporte nativo a SVG comeou a aparecer nos
navegadores, o HTML5 realmente comeou a tomar forma na mente dos fabricantes de navegadores e
eu j tive o prazer de acompanhar o alinhamento das trajetrias do SVG e do HTML. Eu acredito que a
chegada de grficos nos navegadores (SVG e Canvas HTML) foram essenciais para tornar a plataforma
web atraente para os desenvolvedores de aplicativos: um poderoso vocabulrio de marcao, um modelo
de documento, uma sintaxe de autoria simples, e melhora contnua do apoio em todos os principais
navegadores. O refinamento de ambas, implementaes e especificao, tm feito do SVG uma arma
realmente eficaz no arsenal do desenvolvedor web e eu estou constantemente espantado com o que as
pessoas esto fazendo com ele.

Antecedentes: o nome de Jeff Schiller familiar na comunidade SVG. Alm de ser o autor e colaborador
para o desenvolvimento de ferramentas populares e teis como SVGEdit, ele tambm manteve por
muitos anos o local mais definitivo da web para comparao entre navegadores da integralidade da
execuo do SVG. Ele tambm liderou e presidiu o "SVG Interest Group" do W3C, e fez numerosas
contribuies para a evoluo do padro em si. Jeff comeou seu trabalho com SVG enquanto
trabalhava na Motorola e agora um funcionrio do Google.

Doug Schepers

A idia fundamental do SVG bonita: tirar o melhor de programas populares de vetores como
Illustrator, dar estrutura, capacidade de adaptao dinmica, e hiperlinks de formatos de web
como HTML e CSS, e em seguida, adicionar em animaes e rasters efeitos como filtros para torn-lo
divertido e funcional.

Agora que o SVG tem suporte em todos os navegadores modernos, com toneladas de aplicativos, o
Grupo de Trabalho W3C SVG est se voltando para SVG 2. O que est nas cartas? Integrao mais
perfeita com HTML5 e com APIs variadas que vo se tornando apps impressionantes na web (embora a
maioria delas j trabalhem com SVG), uma geral na linguagem para tornar as tarefas comuns mais fceis
para desenvolvedores e implementadores, e uma grande melhoria na API DOM para aumentar a
velocidade e usabilidade. Estamos trabalhando tambm em estreita colaborao com o Grupo de
Trabalho CSS em recursos compartilhados, como filtros para HTML, e pretendemos adotar algumas
novas funcionalidades CSS, incluindo quebra automtica de texto complexas, para dentro e
em torno de formas, um pedido SVG de longa data.

E embora possa parecer um pouco chato, temos um plano para trabalhar em caractersticas menores,
mais modulares; o que isso significa para os desenvolvedores e designers? mais recursos, mais rapidez.
Procure por coisas como parmetros (imagens altamente adaptveis) e recursos para o mapeamento
(como bordas no-escalveis e nveis de detalhe declarativos) para sair como mdulos. E estamos sempre
procura de casos de uso e requisitos que resolvam os problemas do mundo real para os
desenvolvedores.

Antecedentes: Doug Schepers esteve envolvido em SVG como desenvolvedor desde os primeiros dias,
comeando em 2001. Ele estava profundamente envolvido no aumento de conscincia do pblico para
o SVG. Em 2007 ele foi contratado pelo W3C para servir no Grupo de Trabalho. Pegadas de Doug
podem ser vistas em toda a especificao SVG de seus primeiros dias at o presente.

Quem deve ler este livro

Este livro serve tanto como uma introduo bsica como um tratamento mais avanado que mergulha
profundamente em alguns dos aspectos avanados do SVG. Deve ser igualmente acessvel para um
programador web profissional, um estudante de graduao com alguns semestres de curso de
computao, um cientista que quer fazer grandes conjuntos de dados mais interativo, ou um designer
grfico com um forte lado tcnico. Em suma, se voc estiver familiarizado com as noes bsicas de
desenvolvimento web e computao grfica e tem interesse em desenvolver sites com grficos de alta
qualidade e interativos, ento este o livro certo para voc.

Suposies

Este livro presume alguma familiaridade com HTML e grficos web. Experincia prvia com
programao no um requisito, embora a experincia anterior em programao v ajud-lo a
compreender alguns dos captulos (como captulos 4 e 7) que envolvem programao. A familiaridade
com os conceitos bsicos de geometria de coordenadas e fluncia em lgebra do ensino mdio
provavelmente tambm o ajudar na compreenso, embora isso seja uma constante em qualquer assunto
que envolva tratamento de grficos, a incurso em matemtica aqui deve ser bem suave.
Com um foco pesado em conceitos de banco de dados, este livro assume que voc tem uma
compreenso bsica dos sistemas de banco de dados relacional como o Microsoft SQL Server, e tambm
uma breve exposio a linguagem de consulta conhecido como SQL. Para expandir o seu conhecimento
em SQL e da plataforma de banco de dados do Microsoft SQL Server, outros livros da Microsoft Press,
como o "Programao SQL Server 2012" oferece ambas as introdues e informaes completas e
abrangentes sobre T-SQL e SQL Server.

Quem no deve ler este livro

O artista grfico que no gosta de programar. SVG uma linguagem declarativa baseada em XML; Por
conseguinte, tem uma sintaxe rigorosa que no complacente com os erros de gramtica. Se voc estiver
interessado em um ambiente puramente point-and-click, ou simplesmente deseja criar uma interface
grfica do usurio contendo desenhos e ilustraes, um pacote como o Inkscape ou Illustrator pode vir a
ser um melhor rumo para a sua expresso criativa.

Autores da Web que desenvolvem pginas com um pacote como o Microsoft Expression Studio ou
Adobe Dreamweaver em vez de codificao HTML mo, podem estar interessados em algumas das
novas ferramentas de software que esto sendo desenvolvidas para integrar SVG e HTML. No entanto,
enquanto este livro discute algumas destas ferramentas resumidamente, o livro no est concebido como
uma guia na utilizao de pacotes de design.

Organizao deste Livro

Este livro est organizado em sete captulos. Captulo 1, "Noes bsicas de SVG", orienta o leitor para
SVG em si, mostrando como comear, os contextos em que grficos SVG podem ser criados e uma
amostragem diversificada de exemplos que podem aguar o apetite do leitor. Captulo 2, "Criao e
edio de grficos SVG," e Captulo 3, "Adicionando texto, Estilo, e transformaes", entra a dinmica
do ncleo do SVG: as formas bsicas, padres, gradientes, clipes, mscaras e imagens. Captulo 4,
"movimento e interatividade", introduz os dois aspectos fundamentais do SVG interatividade: animao
e scripts. Captulo 5, "Filtros SVG," discute filtros, uma das partes mais complexas e poderosas da
linguagem grfica. Captulo 6, "Ferramentas e Recursos SVG," e Captulo 7, "Construindo Aplicaes
Web: Estudos de Caso" introduz e fornece exemplos da ampla gama de ferramentas e bibliotecas que
suportam o desenvolvimento SVG.
Convenes e caractersticas deste livro

Este livro apresenta informaes usando as convenes destinadas a tornar a informao legvel e fcil de
seguir.
Este livro tem vrios exemplos em que o leitor pode examinar a ilustrao em si e o cdigo utilizado
para criar o exemplo.
Na ocasio, o cdigo mostrado um trecho que mostra apenas as peas necessrias para a compreenso
do texto narrativo. Em tais casos, fornecido um link para um trabalho exemplo na Internet, de modo
que o leitor possa examinar um trabalho completo.
Em caso de cdigos fontes muito longos, o exemplo foi anotado numa tabela de modo que blocos de
cdigo e comentrios explicativos possam ser vistos lado a lado.

Sobre o contedo Companion

A maioria dos captulos deste livro incluem exerccios que permitem que voc, interativamente, possa
experimentar novos materiais aprendido no texto principal. Os exemplos de trabalho podem ser visto na
web em: http://www.microsoftpressstore.com/title/9780735660120
ou
http://cs.sru.edu/~svg
Os exemplos so organizados por nmero do captulo, bem como ligados a partir dos endereos acima.

Instalando as Amostras de Cdigo

No h nenhuma necessidade de "instalar" os exemplos de cdigo para este livro, voc simplesmente
precisa de um navegador que possa exibir SVG.
Captulo 1 - SVG Bsico

Scalable Vector Graphics (SVG) uma norma grfica mantida e aprovada pelo World Wide Web
Consortium (W3C), o mesmo grupo que criou e continua a manter o HTML, CSS, XML, e outras
tecnologias que constituem a World Wide Web.

O "o qu", "porqu" e "onde" do SVG

SVG muito mais do que seu nome sugere. verdade que o SVG uma linguagem que permite a
criao de elementos de vetor bidimensionais, que so simplesmente representaes matemticas de
objetos grficos, e que estes vetores so infinitamente escalveis e podem ser transformados dentro dos
limites do sistema de coordenadas 2D. No entanto, o SVG nico medida em que um padro
aberto definido pelo W3C (http://w3c.org/svg/), e como outras linguagens do W3C, como HTML e
XML, ele tem seu prprio "Document Object Model"(DOM) que traz consigo muitos benefcios, e
interopervel com outros padres abertos e linguagens como JavaScript, CSS e HTML.

SVG tem sido trabalhado ao longo da ltima dcada e tem amadurecido muito durante esse tempo, em
colaborao com as partes interessadas em todo o mundo. O grande apelo de SVG que, como HTML,
fcil de ler e editar, permitindo a interatividade complexa e animaes por meio de scripts e
"Synchronized Multimedia Integration Language" (SMIL), que um outro padro W3C. Os
navegadores Web tm amadurecido ao longo dos ltimos anos, e todos os mais importantes agora
suportam nativamente a especificao SVG, de modo que voc no precisa mais mexer com plug-ins
SVG proprietrios. Todas estas capacidades permitem um grau muito maior de criatividade, com
interatividade complexa mistura com animao e dados em tempo real, tudo dentro do contexto de
aplicaes web SVG melhoradas. Isto ideal para designers e desenvolvedores modernos, como ficou
demonstrado ao longo deste livro.

O qu

SVG baseado em vetores, em vez de pixels. Enquanto uma abordagem baseada em pixel (usado por
programas como o Adobe Photoshop) coloca pigmento ou cor em coordenadas (x,y) para cada pixel em
um bitmap, uma imagem baseada em vetor (usada por programas como o Adobe Illustrator) compe
uma imagem como um conjunto de formas, cada uma descrita por uma frmula relativamente simples e
preenchida com uma textura (um termo amplamente usado aqui para se referir a uma mistura de cores,
gradientes e padres).

SVG escalvel. Como voc j deve saber, se voc aumentar o zoom em uma arte com base em pixel,
voc acabar chegando a uma resoluo mxima. Mesmo com as cmeras de 10 megapixels que agora
so lugar-comum (ou de cmeras de 100 megapixel que podem custar uma pequena fortuna),
aumentando-se o fator de zoom muito alm da resoluo de tela, far com que a imagem fique
"pixelada". A escalabilidade uma enorme vantagem para o surgimento de dispositivos da web mvel,
bem como para exibio de imagens muito grandes (como para publicidade ao ar livre).
A imagem seguinte mostra a diferena entre o que acontece quando voc aumenta o zoom em um vetor
grfico (esquerda) e um bitmap ( direita).
O Porqu

Algumas das vantagens de SVG agora so discutidas, com breves explicaes:

Grficos do lado do cliente - O SVG usa grficos do lado do cliente, por isso o impacto no seu servidor
web leve. Alm de ser escalvel, SVG dinmico e interativo. Um usurio pode, interativamente,
explorar os dados subjacentes a um quadro de novas maneiras.

Cdigo aberto (XML) - Qualquer pessoa pode visualizar o cdigo-fonte que est na base do grfico.
legvel por seres humanos e se parece muito com HTML.

Acessibilidade - Como o cdigo fonte SVG escrito em XML, ele tambm pode ser lido por tela de
leitores e motores de busca. Enquanto uma imagem pode valer mais do que mil palavras, um megapixel
de imagem no vale muito para algum que no pode ver. A capacidade de SVG para trazer geometria
para aqueles que no podem v-lo, estende seu alcance em muitos domnios que as imagens com base
em pixel simplesmente no podem ir.

Padro aberto - Porque ele foi criado pelo W3C (a mesma organizao que nos trouxe HTML), SVG
no-proprietrio e com fornecedor neutro.

Tecnologias familiares - SVG usa tecnologias j familiares aos programadores web: DOM, JavaScript,
CSS e AJAX. Ao invs de ter que aprender tudo de tecnologia, linguagens de programao e
terminologia para lidar com a rea complexa e tcnica dos grficos de computador, designers,
programadores e profissionais de web podem alavancar habilidades aprendidas noutro local.

Aplicaes Web - SVG adequado para incorporao com HTML5, aplicaes baseadas na web, e
aplicaes ricas de Internet (RIAs). Os ltimos 10 anos viram uma grande elevao do status da frase
"aplicativo baseado na web". No muitos anos atrs, as pessoas da comunidade web usavam de sarcasmo
ou descrena para responder quando algum falava sobre o desejo de criar um aplicativo baseado na
Web que fosse acessado pelo navegador. A inspeco rpida da histria do HTML5 revela que a criao
de aplicaes web era uma das intenes primrias por trs do desenvolvimento desta especificao
emergente. A incorporao da linha em SVG, a especificao HTML5, uma grande vantagem para os
desenvolvedores web.

SMIL A "Synchronized Multimedia Integration Language" (SMIL) uma linguagem declarativa


W3C de apoio a multimdia e animao para no-programadores. SMIL parcialmente incorporado na
especificao SVG. Aqueles que tm ou tiveram um maior conhecimento em programao para
animao em JavaScript, podem ficar surpresos com a facilidade com que certas animaes complexas
podem ser criadas usando animao SVG (ou SMIL), bem como da capacidade de atualizar muitos
objetos na tela quase ao mesmo tempo. Enquanto SVG tambm suporta a animao com script atravs
de JavaScript, SMIL traz convenincia, parcimnia, e elegncia para a tarefa.

A adoo do SVG - A partir de 2010, SVG suportado nativamente pelas verses mais atuais dos cinco
principais navegadores. Alm disso, pode ser encontrado nos conjuntos de chips de mais de cem milhes
de telefones mveis, com grande apoio que est sendo oferecido a partir da Nokia, Ikivo, SonyEricsson,
Opera Mobile, Samsung, iPhone, e vrios outros. Isso ser discutido mais na prxima seo.

Outras tecnologias - SVG tem sobreposio com Flash, Vector Markup Language (VML), e
Silverlight, mas ele tem as vantagens de ser plataforma no protegida, padronizada, admite cruzamento
com outras plataformas, e interopervel com outras linguagens XML e padres W3C.

O onde

Os grficos vetoriais esto em todos os lugares. O mundo da arte, por exemplo, est repleto de exemplos
da utilizao de grficos de vetor. Como o professor Jerrold Maddox escreveu em "SVG e arte:
Ampliando as possibilidades, diferentes tempos e lugares","Imagem com base em formas vetoriais: como
e como feita o meio mais popular de arte no mundo"
(http://www.personal.psu.edu/jxm22/svgopen/). Assim, a partir de uma perspectiva global e histrica,
podemos ver imagens que no so baseadas em vetores como a anomalia mais do que a regra.

SVG, hoje em dia, est em todos os lugares. Estima-se que 1,5 bilhes de dispositivos no mundo
tenham SVG habilitado (a partir de http://en.wikipedia.org/wiki/Usage_share_of_web_browsers e
http://marketshare.hitslink.com/browser-market-share.aspx?spider=1&qprid=2).

Se somarmos a isso os dois fabricantes de mobiles, cujos dispositivos esto habilitados SVG (Ikivo com
350 milhes de usurios [http://www.ikivo.com/04about.html] e Apple, cujo iPhone possui outros 100
milhes [http://mashable.com/2011/03/02/100-million-iphones/]) e estimativa da Abbra que "Hoje
mais de 700 milhes de celulares possuem suporte para a verso 1.1 SVG - mais que o dobro do
concorrente mais prximo, a tecnologia de FlashLite "(http://abbra.com/products.html), ento a nossa
estimativa sobe para cerca de dois bilhes de dispositivos que esto com SVG pronto!

A Adobe foi quem primeiro deu suporte para SVG no navegador (por meio de um plug-in conhecido
como ASV 3),em 2000, embora o apoio em outras aplicaes (como o CorelDRAW e Microsoft Visio)
fosse anterior (http://www.w3.org/G6raphics/SVG/History). O SVG teve um apoio considervel em
programas de desenho, incluindo Illustrator, CorelDRAW, e Inkscape, h muitos anos, e tambm
suportado em uma variedade de aplicaes de Internet Protocol Television (IPTV) e no KDE popular
ambiente de desktop para Linux.

No mercado de navegadores, o Konqueror foi o primeiro navegador a suportar nativamente o SVG, em


2004 (http: //en.wikipedia.org/wiki/Scalable_Vector_Graphics#Native_support). A partir do incio de
2005, o navegador Opera teve amplo suporte a SVG, e o Firefox desenvolveu suporte para SVG bsico
pouco depois em sua verso 2. Em meados de 2007, o Safari tinha implementado suporte bsico
tambm. Google estreou em seu navegador Chrome em 2008, e em 2009 a Microsoft anunciou que o
Internet Explorer finalmente teria suporte nativo, ficando, o SVG, com suporte em todos os grandes
navegadores.

Alm dos navegadores, existem vrias aplicaes e softwares que lem ou exportam contedo SVG (veja
a lista no http://en.wikipedia.org/wiki/Scalable_Vector_Graphics).

Voc ver um exemplo passo-a-passo mais detalhado no final deste captulo, mas importante que voc
j tenha alguma idia do que est envolvido na visualizao e criao de grficos SVG.

Visualizando SVG

Inicie qualquer navegador moderno e aponte-o para o site relacionado a este livro, http://cs.sru.edu/~svg
.com. Internet Explorer, Firefox, Chrome, Safari, Opera todos tm suporte de visualizao SVG na web,
assim voc pode usar qualquer um desses. A exceo mais importante esta: se voc estiver usando o
Internet Explorer, voc precisar atualiz-lo para o IE9 (que requer o Microsoft Windows Vista ou
posterior), ou voc precisar baixar o SVG plug-in gratuito (ASV verso 3.03) da Adobe, no endereo
http: //www.adobe.com / svg / espectador / instalao / mainframed.html. Para todos os outros
navegadores listados, usando a ltima verso ser melhor, porque todos estes browsers esto fazendo um
progresso constante e frequente em suas implementaes da especificao SVG.

Como outro exemplo da importncia do uso de verses atuais de navegadores, o Firefox 3.6 no suporta
animao SMIL, enquanto o Firefox 4.0, sim. Voc ver mais sobre as idiossincrasias de suporte ao
navegador nas discusses dos temas relevantes, mas note que as partes que dizem respeito a SVG, a
animao, filtros e fontes so mais propensos a mostrar diferenas de um navegador para outro.

Escrita SVG

H muitos caminhos diferentes que se pode seguir para desenvolver SVG. Este livro ir mostrar-lhe
vrios deles com mais detalhes no Captulo 6, "Ferramentas SVG e recursos". Nesse meio tempo,
recomendamos a utilizao de qualquer editor de texto simples, por exemplo, o Bloco de notas para
Windows ou TextEdit (configurado corretamente para Mac; http://support.apple.com/kb/HT2523)-ou
ver qualquer uma das infinidade de ferramentas de edio em Linux ou UNIX (nano, pico, emacs, vi,
ed, kate, vim, kwrite, gEdit, etc.).

Primeiro, insira esse arquivo SVG muito simples em seu editor de texto e salve o arquivo com o nome
myfirstfile.svg (voc pode salvar o arquivo em seu disco rgido local ou em um servidor remoto,
contanto que voc saiba como chegar a ele a partir do seu navegador):
<svg xmlns="http://www.w3.org/2000/svg">
<circle r="50"/>
</svg>

O arquivo tambm visvel em http://cs.sru.edu/~ddailey/svg/simplest.svg voc no deve ter nenhum


problema vendo o arquivo que criou. Voc ver informaes sobre ambientes de edio mais avanados
no final deste captulo, e voc vai, naturalmente, ver muitos outros exemplos de cdigo SVG durante
todo o resto do livro.

Treze exemplos que mostram as capacidades do SVG

Para apreciar plenamente o poder de SVG, completo com as suas capacidades de interatividade e
animao, eu encorajo-vos a dar uma olhada na pgina de tutorial no site do livro
(http://cs.sru.edu/~svg), que contm links para exemplos interessantes, e tambm para explorar e ler os
exemplos ilustrados e brevemente discutidos abaixo.

Exemplo 1: Paisagem Randmica Dinmica Desenhada com JavaScript e SVG

O cenrio aqui, inspirado pelos discos frequentes de um autor de sua terra natal, no Novo Mxico, em
sua ps-graduao no Colorado, mostra o efeito do movimento de paralaxe nas vrias cadeias de
montanhas Lder do sop at a Diviso Continental. Como o ponto de vista se move continuamente
para o norte em direo ao Wyoming, segue um balo de ar quente impressionista. Sua posio vertical,
velocidade e mudana de vento deforma-o aleatoriamente um pouco medida que avanamos. As vrias
camadas de montanhas recuam atrs de ns esquerda, com os picos mais altos restantes mais visveis.
Devido a utilizao de elementos aleatrios, no h duas paisagens iguais (ignorando a infinitesimal
probabilidade de extrema coincidncia). O exemplo pode ser visto em (http://srufaculty.sru.edu/david
.dailey/svg/balloon.svg).

Veja como feito:

O cu - O cu composto por dois retngulos. Um deles, o fundo, simplesmente preenchido com um


gradiente linear que consiste em cores que se movem de tons mais brilhantes do cu azul ao cinza, de
baixo para cima. O segundo retngulo proporciona um efeito de globo de neve. O primeiro plano e a
poluio atmosfrica, devido superpopulao das comunidades ao longo da cordilheira da frente, so
simuladas atravs das transies de cores nos contrafortes e a sobreposio de cinza resultante do fundo e
do primeiro plano.

O efeito de globo de neve - Este produzido usando um gradiente radial para variar a transparncia no
primeiro plano. Com os gradientes SVG, voc pode variar no s as cores mudando gradualmente de
uma para outra, mas tambm a sua opacidade relativa.
O balo - O balo inteiramente feito atravs de JavaScript. Uma srie quase paralela de Curvas Bzier
criado com pontos de incio e pontos de extremidade que coincidem. Os pontos de controle so
diferentes e mudam ao longo do tempo. O grupo inteiro (um elemento <g> em SVG) tem ento as suas
posies, horizontal e vertical, variando atravs de um circuito cronometrado que atualiza a tela a cada
10 milissegundos.

O desenho das montanhas - H quatro camadas de montanhas, cada uma preenchida com um gradiente
linear que muda de amarelo-amarronzada nas plancies e colinas para o azul-branco dos picos cobertos
de neve da Diviso Continental. A sugesto do verde no segundo intervalo por trs dos montes pretende
sugerir a presena de florestas. As alturas dos picos so determinadas de forma aleatria, com uma
matriz de coordenadas (x,y) aleatrias sendo geradas primeiro e, em seguida, classificadas por seus
valores de x. Em seguida, elas so divididas em tripletos, de modo que os picos podem ser ligados por
uma srie de curvas, tendo cada uma o ponto de extremidade anterior e o lado separado por pontos em
uma curva Bzier cbica.

O movimento das montanhas - As camadas de primeiro plano so simplesmente deslocadas para a


esquerda mais rapidamente do que as camadas na parte de trs. Cada matriz tem o seu primeiro
elemento removido de modo que um outro elemento aleatrio pode ser adicionado na extremidade da
matriz, sem a matriz tornar-se arbitrariamente grande. Qualquer memria do que aconteceu
sistematicamente eliminada.

Exemplo 2: Pontos de Posicionamento eqidistantes ao longo de uma curva Bzier

A matemtica das curvas Bzier, enquanto bastante acessvel a um matemtico, no so triviais. Curvas
Bzier no foram descobertas antes de 1959 (ver http://en.wikipedia.org/wiki/B%C3%A9zier_curve),
130 anos depois variste Galois resolveu a teoria de razes de polinmios e lanou as bases para grande
parte da lgebra dos sculos 19 e 20. Felizmente, SVG (seguindo o exemplo do Adobe Illustrator 88) d
acesso direto e intuitivo para estas curvas maravilhosamente expressivas em termos de capacidade de
desenhar, medir, subdividir, orientar, e animar. Neste exemplo, a curva desenhada com um conjunto
simples de comandos de marcao, e cada vez que o usurio clica a curva ou perto dela, JavaScript
usado para medir a curva e dividi-la em um nmero cada vez maior de partes, com a opo de animar o
processo.

O desenho da curva - A marcao utilizada bastante simples:


<path d="M 10 150 C 200 80 350 300 450 100" id="B"
stroke="black" fill="none" stroke-width="4"/>

Medio e subdiviso da curva - A ligao entre a linguagem JavaScript e SVG permite a voc
"conversar" com as propriedades das coisas que foram desenhadas atravs de marcao ou de forma
dinmica, e manipul-las utilizando mtodos. Neste caso, estamos usando duas chamadas de funo:
G = B.getTotalLength(); e P = B.getPointAtLength(L * i / n);. A primeira manipula as medidas do
caminho B, e retorna um valor numrico; a segunda retorna um ponto (um objeto com ambos os
valores x e y) uma dada frao da distncia ao longo de B. O Script ento utilizado para criar novas
elipses de diferentes cores nesses marcos fracionrios.

Exemplo 3: Animao simples (apenas 38 linhas de marcao e sem script)

Este exemplo tem sido citado por outros pela riqueza que atinge mesmo com tanta simplicidade. O
exemplo usa a animao para SMIL simultaneamente variando 4 atributos diferentes de 26 objetos
diferentes. Na conferncia SVG Open 2010 em Paris, uma das manifestaes da Microsoft mostrou que
este exemplo em particular pode ser animado usando um dos vrios emuladores de SMIL para SVG,
embora, como est escrito, a maioria dos navegadores possa executar a animao sem assistncia
adicional. Criando uma animao to rica com outras tecnologias, como a HTML5 tag <canvas> ou
Applets Java, seria preciso muito mais cdigo, pensamento, experimentao e tempo para se desenvolver.

Desenhando uma ptala da flor - Uma elipse desenhada com um determinado centride e diferentes
raios nas direes x e y. um pouco mais transparente do o normal (a opacidade ajustada para 0,4).
Em seguida, enche-se com um gradiente (neste caso, um gradiente linear de vermelho para azul e, em
seguida, de verde para amarelo).

Replicando a ptala - O SVG permite uma reutilizao considervel do cdigo. Neste caso, a ptala
inicial reutilizada quatro vezes atravs de uma srie de elementos <use>, a cada um dos quais aplicada
uma rotao diferente. Isto cria um agrupamento de ptalas, que em seguida agrupado e reutilizado 5
vezes mais, para um total de 25 ptalas, sendo desenhadas com apenas 9 linhas de marcao.

Animando a ilustrao - A ptala inicial da flor (que mais tarde replicada) tem trs animaes
separadas aplicada a ela. A primeira altera gradualmente a sua orientao de 0 a 360 graus ao longo de
um perodo de 7 segundos. As prximas duas animaes variam o valor x do centride e o raio na
direo y, respectivamente, em 8 e 3 segundos. Porque 3, 7, e 8 so relativamente primos, toda a
animao vai se repetir a cada 168 segundo (3 7 8 = 168). A animao aplicada a uma ptala que
ento reutilizada 24 vezes, cada uma das 25 ptalas herdam a mesmo animao, com a rotao e
reposicionamento sendo aplicados em relao a cada posio inicial diferente. O crculo no centro da
composio tem a sua prpria cor animada para adicionar um pouco de variedade cromtica.
Exemplo 4: O uso de gradientes e padres

Este exemplo consiste em apenas 19 linhas de markup (no contando suas animaes) e sem JavaScript.
Ele demonstra que alguns resultados bastante intrigantes podem ser inventados pela justaposio de
alguns elementos SVG bastante simples. Depois de ter se acostumado a SVG, animaes desse tipo
sero extremamente fceis de criar e experimentar.

Criando o padro de repetio - Neste caso, o padro consiste em dois crculos (um preenchido com um
gradiente radial off-center e outro com uma cor plana e uma borda de cor diferente).
Restringindo o padro dentro de uma forma - O padro em seguida aplicada a uma elipse.

Exemplo 5: Interseco de caminhos e recortes de imagens

SVG permite que as imagens bitmap (.png, .jpg, .gif e) sejam importadas e usadas em conjunto
com outros grficos primitivos. Como voc ver mais tarde, isso feito atravs do elemento <image>.

Imagens e outras formas podem ser cortadas para os limites definidos por uma determinada forma,
(neste caso, uma estrela de cinco pontas), utilizando o elemento <clipPath>.

H mais de uma maneira de grampear caminhos que se cruzam. Aqui, o retngulo de cor lavanda
intersecta as estrelas de cinco pontas de duas formas bastante diferentes.

Como quase todas as coisas em SVG, caminhos de clipes podem ser animados. O exemplo usa
animao SMIL para rodar as estrelas, revelando diferentes partes das faces subjacentes.
Este exemplo particular, construdo pela primeira vez em 2006, serviu como um teste de mini-referncia
para os navegadores. Originalmente, ele s funcionou corretamente no Internet Explorer com o ASV.
Com o tempo, o Opera e cada um dos outros navegadores foram gradualmente atualizados na
manipulao correta da interseco de caminhos de clipe tambm.

Grampeando uma imagem a uma forma - A imagem esquerda definida por um elemento <image>.
Os seus atributos clip-path = "url (#CPST)" referncias do elemento <id clipPath = "CPST">, que
contm um elemento <path> em forma de estrela.

Grampeando um clip-path - Isso feito de duas maneiras neste exemplo: Primeiro, o elemento <image>
ao qual um clip-path foi aplicado reutilizado com um elemento<use>. O elemento <use>, em seguida,
tem um outro clip-path aplicado a ele (que passa a consistir no retngulo cor lavanda). Os dois clip-path
se cruzam como seria de esperar. A outra abordagem construir um <clipPath> que tem definido o seu
prprio atributo clip-path. Isso funciona no Internet Explorer 9, Opera e Internet Explorer com ASV,
como seria de esperar, e o mesmo, independentemente se o caminho do clipe secundrio aplicado ao
<clipPath> pai ou aos elementos dentro dele. Os outros navegadores mostram uma variedade de
respostas idiossincrticas para esta abordagem.

Exemplo 6: Texto animado ao longo de uma curva Bzier

Para qualquer um que se excitava com as novas aplicaes do ambiente Macintosh do meio para o final
da dcada de 1980, a capacidade do Adobe Illustrator para permitir o layout de texto seguindo uma
curva arbitrria, usando uma interface grfica de usurio simples (GUI), caiu na categoria dos "muito
legal." O exemplo demonstra que o SVG pode fazer isso e ir um passo alm: ela pode animar o texto
que se move ao longo da curva!

Colocar texto ao longo de um caminho - Enquanto isso ser discutido com exemplos no final do livro,
funciona mais ou menos assim: primeiro, o texto (uma seqncia de caracteres) colocado em um
elemento SVG <text>. Tambm no <text> vai um elemento <textPath> que tem uma referncia URI
simples para o ID do elemento <path>.

Animao de texto que seguindo o caminho - Um atributo de <textPath> StartOffset. Seu valor
determina um deslocamento para a posio inicial do texto. Isto , um valor zero significa que a
texto comear no incio do trajeto; valores mais altos significam que o texto comear mais perto do
final do trajeto. O efeito conseguido simplesmente por animar esse valor com um elemento SVG
<animate>.
Exemplo 7: Animao de gradientes com transparncia refletida

Alguns dos efeitos propostos por SVG parecem ser mais interessantes do que teis. Este , primeira
vista, matemtica pura, at que a imaginao descobre (ou inventa) a sua utilidade. Os gradientes radiais
disponveis em SVG tm a capacidade de repetir bandas de cor, utilizando os valores de "refletir" ou
"repetir".

Os dois gradientes refletidos - SVG tem dois tipos principais de gradientes: linear e radial. O gradiente
radial permite um tipo especial chamado gradiente refletido. Neste caso, duas elipses idnticas esto
localizadas uma sobre a outra. Ambas tm faixas alternadas de opacidade e transparncia coincidindo
com as suas cores alternadas, o que nos permite ver atravs do background.

A animao - Os pontos centrais e focais dos gradientes so refletidos em seguida, de forma


independente animados usando animao SMIL.

Exemplo 8: Relgio com estilo impressionista

H muitos relgios SVG na Web. Mostrar as horas parece ser um meio de expresso madura com a
oportunidade. Este em particular no provavelmente o mais astuto, elegante, atraente, fantstico,
decorativo, ou verso comercial disponvel, mas sua capacidade de fazer o que faz com apenas 79 linhas
de cdigo (cerca de metade JavaScript e metade SVG) pode ajudar a ilustrar a facilidade e a brevidade
com que voc pode alcanar altos efeitos.
A animao Toda a animao tratada de forma declarativa (usando SMIL). Isto , no existem
instrues JavaScript envolvendo setTimeout() ou setInterval () (usado para animao web
convencional). A animao genrica que manipula a rotao dos ponteiros do relgio declarada em
linguagem de marcao e, em seguida, clonada atravs de JavaScript com as suas propriedades sendo
modificadas em um "loop" que processa os detalhes de quo rpido cada ponteiro deve se mover. Da
mesma forma, as engrenagens so clonadas a partir de um prottipo de engrenagem, com os padres de
trao em torno das suas bordas e s suas rotaes atribudo velocidades diferentes.

A marcao - A marcao mantida mnima usando script para replicar muitas cpias de coisas
similares. SVG ainda no tem um elemento <replicar> que possa permitir que algum destes scripts
sejam manipulados de forma declativa. Nesse meio tempo, ns podemos usar a marcao e roteiro para
o que cada um faz melhor - SVG permite o entrelaamento agradvel de ambos. O JavaScript tambm
usado para atribuir cores, tamanhos e velocidades para as vrias engrenagens, e para determinar a hora
real do dia para que os ponteiros do relgio possam ser inicializados.

O relgio - As marcas de horas tambm so feitas de forma declarativa, definindo o atributo "dash-
array" da borda em torno do relgio. O aparecimento de uma ligeira curvatura para o relgio feita
atravs de um gradiente radial.

Exemplo 9: Usando um filtro para criar ondas sobre uma imagem

Este exemplo mostra alguns dos aspectos mais avanados de scripts de gradientes animados utilizados
em conjunto com filtros para distorcer uma imagem. A verso animada mostra ondulaes
(customizveis pelo usurio utilizando elementos de entrada HTML) move-se atravs de uma imagem
como ondulaes movimentando a reflexo de uma imagem em um lago.

A criao de crculos concntricos - Os crculos so criados com script. Um gradiente pode ter diferentes
bandas de cor, chamadas de "stops", definidas no seu interior. Neste caso, uma srie de crculos
concntricos (laranja e verde) foi criada por meio de script e adicionou-se um gradiente, que ento
aplicado a uma elipse sob a imagem de uma face.

Animando crculos concntricos - O raio (ou offset) de cada "stop" ento modificado gradualmente
atravs de mudanas sutis em um loop "setTimeout()" definido em JavaScript. Curiosamente, o script
para este exemplo reside no HTML, em vez de dentro do SVG e o SVG DOM acessado de l.

Distorcendo a imagem - Uma vez que as duas coisas acima tenham sido feitas, o resto bastante fcil.
Um filtro criado que transforma ambos, os crculos concntricos e a face, em camadas, e em seguida, a
distoro aplicada atravs de um efeito de filtro conhecida como <feDisplacementMap>, usando o
canal vermelho do gradiente para determinar o grau de distoro relacionado com a imagem. Porque o
verde no contm vermelho mas o laranja, sim ,<feDisplacementMap> fornece a distoro diferencial
em faixas concntricas.

Exemplo 10: Usando <replicar> para simular digitalmente a elevao de um mapa

O SVG ainda est evoluindo. A verso 2 da especificao est atualmente sob deliberao de Trabalho
do Grupo W3C. Embora a linguagem tenha atualmente apenas dois tipos de gradientes (lineares e
radiais), existem vrias propostas para aumentar esse nmero. Uma, a proposta de permitir marcao
declarativa para criar muitos objetos que so interpolados de um para outro - como animao, somente
espacial em vez de temporal - usando <replicate>. Enquanto <replicate> lidaria com uma ampla
variedade de questes (como o retrato 3D rotativo de um acidente geogrfico), outras propostas so de
um escopo consideravelmente menos amplo.

Interpolao entre caminhos - Neste exemplo, muitos polgonos concntricos (com nmeros variveis
de pontos em sua definio) so definidos por meio de interpolao e depois clonados.

Simulando rotao 3D O script, em seguida, manipula os dados para permitir a rotao em trs
dimenses.

Exemplo 11: Paraleleppedos

Aqui est outro exemplo que mostra o uso do <replicate>. Este exemplo replica polgonos interpolados
em duas direces. Enquanto <replicate> no suportado (ainda) pela especificao SVG, ele
suportado por meio de um "open source" JavaScript que permite SVG - como marcao declarativa
para serem intercaladas com SVG real para criar uma vasta gama de efeitos.

A forma bsica - Em primeiro lugar, um quadriltero desenhado com um SVG utilizando o


elemento<path>.
Replicando da esquerda para a direita - Em seguida, replicado pela colocao de um elemento
<replicate> dentro do elemento <path>. O elemento<replicate> instrui sobre a forma e posio do
quadriltero a ser gradualmente duplicado a partir da esquerda para a direita. Alm disso, o gradiente
aplicado para o quadriltero recuperada, e uma de suas faixas de cores que definem (ou escalas)
gradualmente mudou de vermelho para verde, e, finalmente, a prpura (com os valores de cor de
gradiente sendo modificados).

Replicando verticalmente - Os resultados da primeira replicao so vistos como parte de um grupo que
replicado para cima, com a sua escala sendo modificada, enquanto ele clonado.

Exemplo 12: Padres triangulares

Enquanto SVG tem um elemento <pattern>, que permite a criao de azulejos retangulares repetidos,
se voc pretende utilizar padres no retangulares ou modificar individualmente os elementos de uma
parte de um padro para outro, ento o script pode ser o melhor caminho. A justaposio de opacidade,
rotao, inclinao, e tringulos algo facilmente feito em SVG. A rotao dos tringulos interiores cria
formas de folhas de trevo ou favos de mel, dependendo da orientao.

As formas bsicas - Comeamos com dois tringulos, com diferentes orientaes e gradientes. Algumas
opacidades dos gradientes so usadas para permitir que o fundo seja visto.

Duplicao usando o script - Nesse caso, o script usado para construir uma telha triangular atravs da
clonagem dos tringulos iniciais. O centro de cada tringulo ento preenchido com uma outra forma
triangular preenchida com cores aleatrias (a partir de um leque muito restrito de possibilidades).

Efeitos Concluindo, uma inclinao subjacente aplicada e, lentamente, animada para dar um senso
quase subliminar de "atmosfera." Para navegadores que suportam animao SMIL, alguns destes efeitos,
incluindo rotao, so animados.

Exemplo 13: Uma Aplicao Web para desenhar grficos (Redes)

Este aplicativo especial foi construdo e reconstrudo por seus autores em diversas linguagens (CT,
HyperTalk, Java, VML, e agora SVG com JavaScript) nos ltimos 25 anos. Ele se provou inestimvel
para o ensino de matemtica discreta para estudantes de graduao. Basicamente, usando algumas
milhares de linhas de JavaScript, constri uma interface de clique-e-arraste GUI para permitir a criao,
edio, replicao, armazenamento e recuperao de grficos finitos. Como muitos aplicativos da web
emergentes, o SVG aqui tem um papel secundrio, com JavaScript e manipulao de eventos
consumindo o esforo predominante. O SVG pode ser utilizado para desempenhar um papel crucial no
domnio cada vez mais importante de aplicaes web.

Desenho - Uma vantagem da utilizao do SVG alm de ser uma tecnologia para grficos mais leve
comparando com tecnologias HTML como o <canvas> - para a construo de aplicaes web que os
objetos em SVG esto no DOM. Isto significa que os eventos podem ser facilmente ligado a objetos e
manipular eventos SVG, bem como aqueles nas partes no grficas do HTML. Assim, as coordenadas
do mouse (bem como os alvos dos eventos) podem ser facilmente manipulados para permitir a criao e
reposicionamento de objetos, no sentido clssico de uma interface grfica.

Conexo - Novamente, porque os objetos SVG esto no DOM, fcil de construir referncias
JavaScript a esses objetos de forma que arrays de objetos e suas propriedades possam ser mantidos
com ligaes de volta para suas instncias visveis. fcil de conectar e desconectar os ns de grficos,
precisamente porque eles so objetos, tanto em JavaScript quanto em SVG.

Interface - O exemplo mostrado aqui utiliza JavaScript para construir um sistema de menu, juntamente
com caixas de dilogo, e da capacidade de exportar e importar desenhos do usurio. No entanto, grande
parte dessas funcionalidades tambm podem ser fornecidas atravs de ferramentas de alto nvel, tais
como D3, e Pergola (discutido em captulos posteriores).
Mergulho em: Uma Abordagem Passo-a-passo para a construo de um Documento SVG Simples

Ns j introduzimos um exemplo muito simples de um arquivo SVG neste captulo, na seo "Escrever
SVG".

Vamos recomear nesse ponto:


1. Abra um editor de texto confivel (algo que lhe permite ver e guardar "plain text" - tipicamente texto
ASCII ou UTF-8 em formato .txt).

2. Crie um arquivo contendo as seguintes linhas de cdigo, e salve-o como first.svg:


<xmlns SVG = "http://www.w3.org/2000/svg">
<circle r = "50" />
</ svg>

3. Abra o mesmo arquivo em um navegador web. Voc pode deixar seu editor de texto aberto, porque
voc pode querer revisar o arquivo depois para acrescentar coisas novas. Para o seu navegador, voc pode
usar uma verso atual do Chrome, Firefox, Internet Explorer (ver notas sobre isso na seo
"Visualizando SVG", anteriormente no captulo), Opera ou Safari.
Voc deve ver algo que se parece com a imagem abaixo, que mostra capturas de tela de
Firefox, Chrome, Opera, Internet Explorer e Safari (da esquerda para a direita, de cima para baixo).

Intervalo e Anlise

A seguir, vamos discutir o cdigo do exerccio anterior para que voc possa ver o que ele faz.

<xmlns SVG = "http://www.w3.org/2000/svg">


<circle r = "50" />
</ svg>
SVG Como XML

A primeira e ltima linhas mostram que SVG, como um dialeto XML, uma linguagem de marcao.
Cada elemento no caso mais simples, uma nica palavra entre os suportes de ngulo - deve ter um
comeo (o <svg> neste caso) e um fim (o </svg> neste exemplo). Voc pode acabar com a tag como esta:
<svg> </svg>
Ou voc pode acabar com ela assim:
<circle ... />
Este segundo exemplo chamado de uma tag com auto-terminao, porque a barra (/) ocorre no final
da tag. Note que a segunda linha neste exemplo recuada como uma conveno para tornar o cdigo
mais legvel - o recuo no necessrio.

Atributos

Todos os elementos SVG tem uma coleo de atributos que so divididos em duas categorias: os
atributos regulares e atributos de apresentao (http://www.w3.org/TR/SVG/attindex.html). A primeira
categoria inclui, por exemplo, atributos geomtricas, tais como "x", "cx", e "largura". A segunda
categoria inclui, por exemplo, os atributos de pintura, como preenchimento, largura de trao, exibir e
opacidade.
O elemento <circle>, por exemplo, tem um atributo "r" (que significa raio). O fato do atributo "r"
ter um valor de 50 unidades (no caso mais simples e padro) significa que o raio do crculo ser de 50
pixels.

O Namespace SVG

O elemento <svg> tem o atributo / valor par xmlns = "http://www.w3.org/2000/svg" (o que significa
que o namespace XML usado para interpretar o documento ser especificado pelo W3C).

O atributo "xmlns" (que parece no ter sido parte da linguagem originalmente, porque os visualizadores
Adobe e Opera so os nicos que no a requerem) necessrio para a maioria dos navegadores para ser
capaz de exibir o cdigo como SVG.
Essencialmente, o atributo "xmlns" apenas informa ao navegador que ele vai estar falando um novo
dialeto XML. Isso ocorre porque a maioria dos navegadores do sculo 20, assumiram que a nica
linguagem que seria preciso saber era HTML. Escrever <svg> no suficiente para permitir que o
navegador saiba disso, porque a especificao XML requer um "namespace". bastante lamentvel, do
ponto de vista dos professores e aprendizes, que as linguagens de computador que aprendemos esto
cheias de mistrios que no tm nenhum propsito aparente at que um se torna um guru. No entanto,
voc pode pensar do cdigo xmlns = "http://www.w3.org/2000/svg "dentro do elemento <svg> como
apenas isso: um encantamento misterioso provavelmente colocado na linguagem para se certificar de
que os alunos casuais saibam. Acontece que no to importante entender.

Coordenadas da tela

Antes de iniciar o segundo exerccio, onde voc poder comear a experimentar o SVG, considere como
espao de desenho a prpria janela do navegador. Cada ponto dentro do espao de desenho (tambm
conhecido como Plano cartesiano) identificada por um par de coordenadas (x,y). O canto superior
esquerdo da tela o ponto (0,0) e - dependendo da resoluo da tela e o tamanho atual da janela o
canto inferior direito poderia ter coordenadas, tais como (800,640), (951,651), ou (1440,900). O
nmero de pixels determina a resoluo do ecr. A resoluo em dispositivos mveis varia
consideravelmente; 240 320 pixels um tamanho popular para dispositivos menores e mais antigos.

Alterando o seu cdigo e experimentando

Neste exerccio, voc vai fazer um experimento com o crculo que voc desenhou no exerccio anterior,
alterando a sua localizao, tamanho e cor, reconstruindo-o de modo que apenas o seu limite externo
permanea preto.

1. Mova o crculo para o centro da tela. Voc pode fazer isso definindo as coordenadas x e y do centro
do crculo (CX e CY, respectivamente) a 50 por cento, o que medido em relao a largura e altura da
janela do browser.
<xmlns SVG = "http://www.w3.org/2000/svg">
<circle r = "50" cx = "50%" cy = "50%" />
</ svg>

Aumente o raio e defina-o com uma proporo fixa da largura do navegador.

Nota: Um atributo geomtrico, tais como CX, CY, ou r, neste caso, pode ser definido com qualquer
valor proporcional (em relao ao tamanho da janela) ou um valor absoluto (pixels, por padro).

<xmlns SVG = "http://www.w3.org/2000/svg">


<circle r = "25%" cx = "50%" cy = "50%" />
</ svg>
Mude sua cor. Voc pode fazer isso definindo o atributo de preenchimento nomeando uma nova cor ou
em uma variedade de outros meios (por exemplo, usando CSS ou HTML hexadecimal, valores RGB ou
valores HSB).
<xmlns SVG = "http://www.w3.org/2000/svg">
<circle r = "25%" cx = "50%" cy = "50%" fill = "DarkOrange" />
</ svg>

Altere o cdigo de modo que apenas a parte externa do crculo fique colorido. Isso envolve trs tarefas:
definir o preenchimento do crculo com "none" de modo que seu interior fique transparente, definindo
a sua borda com alguma cor (por exemplo, DarkOrange), e definindo uma largura para a sua borda. O
cdigo a seguir tambm ajusta a cor do DarkOrange cor nomeada para # e60, que um pouco mais
baixa na canal vermelho e bem mais baixa no canal verde do que o hexadecimal DarkOrange
equivalente, # FF8C00.
<xmlns SVG = "http://www.w3.org/2000/svg">
<crculo r = 25%" cx = 50%" cy = 50%" fill = "none" stroke-width = "# e60" = "25" />
</ svg>

Fazer o interior transparente. Voc pode fazer isso colocando um outro crculo opaco atrs dele e
deslocando um pouco para a esquerda. Observe que o primeiro objeto definido aparece atrs dos objetos
que aparecem mais tarde na rvore do documento. Neste caso, ns tambm adicionamos outro
"namespace" identificador (o que no estritamente necessrio aqui, mas ser necessrio para elementos
que usam o SVG ligando facilidades para conectar-se a documentos externos ou fragmentos de cdigo
definidos em outro lugar dentro do mesmo documento). aqui que voc passa a se acostumar a v-los,
porque parte da declarao padro de um tpico documento SVG.
<svg xmlns=" http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<circle cx="30%" cy="50%" r="25%" fill="lightgreen" stroke="#e60" stroke-width="25"/>
<circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25"/>
</svg>

Criao de um efeito dado


Neste exerccio, iremos apresentar uma foto e pedir-lhe para analisar e, em seguida, tentar desenh-lo.
1. Observe o seguinte desenho SVG, referido como "objetivo":

2. Identifique o tipo de objetos que parecem ser utilizados no desenho. Neste caso, verifica-se que
existem trs objetos: um crculo (que se assemelha muito a nossa forma anterior), uma forma oval
(chamada de elipse em SVG), e um retngulo.

3. Identifique a ordem em que os objectos so desenhados. O objeto mais frontal parece ser a elipse, e
seu padro de preenchimento amarelada aparece ligeiramente transparente, porque voc pode ver os
outros objetos por trs dela. De trs para a frente (que coincide com a ordem na qual o objetos sero
desenhadas), parece haver um crculo, um retngulo, em seguida, uma elipse. importante notar que o
objeto do topo (a elipse) transparente no seu interior, mas no na sua borda.

4. Determine se os objetos parecem ser desenhado com valores relativos (percentuais) ou absolutos
(pixels) para os seus atributos geomtricos. Voc pode achar que til para ver o desenho na web, onde
voc pode ver como o desenho afetado pelo redimensionamento do navegador. Voc pode encontrar o
desenho aqui: http://granite.sru.edu/~ddailey/svg/lesson3.svg.
Neste caso, faz sentido comear com a suposio de que a geometria foi elaborada em relao ao
tamanho da janela, por trs razes: porque o crculo parece ser o mesmo que no segundo exerccio (que
tinha valores relativos em sua geometria), porque a linha superior do retngulo parece coincidir com o
centro do crculo, e por causa da elipse, parece partilhar o mesmo centro que o crculo.

5. Comece com o mesmo arquivo que voc criou no final do exerccio anterior, porque parece que os
dois arquivos compartilham o mesmo crculo, e o objetivo da ilustrao envolveria a colocao desse
crculo sob os outros objetos, o que significa o incio do cdigo de marcao.

<svg xmlns=" http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >


<title>Collage involving &lt;rect&gt; , &lt;circle&gt; and &lt;ellipse&gt; </title>
<circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25"/>
</svg>

O cdigo anterior contm uma linha adicional: um elemento <title>. Como um formato de imagem,
SVG tem um grande potencial para tratar de questes de acessibilidade para pessoas com deficincia
visual, por isso melhor adquirir o hbito de adicionar um ttulo para todos os seus documentos. Voc
ver mais sobre acessibilidade mais adiante neste livro, porque um tema importante, particularmente
para SVG.

6. Adicionar um retngulo de azul na parte superior do crculo e ajustar seu tamanho, posio, cor,
borda, e largura do traado:

<svg xmlns=" http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >


<title>Collage involving &lt;rect&gt; , &lt;circle&gt; and &lt;ellipse&gt; </title>
<circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25"/>
<rect x="10%" width="80%" y="50%" height="10%" fill="#8ff " stroke="black" stroke-width="6" />
</svg>

O elemento <rect>, como o <circle>, pode ter de preenchimento, borda (stroke), largura de borda
(stroke-width), e outros atributos. O x e y especificam as coordenadas do canto superior esquerdo do
retngulo, height (altura) e width (largura) especificam o seu tamanho. Se voc quer o topo do
retngulo coincidindo com o centro da janela, voc pode definir x para "50%". Voc tambm quer que
ele fique no centro da tela na horizontal, de modo que a distncia de sua extenso mais direita
(especificado pela largura + x) para a borda direita da janela deve ser igual a x. Ao experimentar um
pouco com valores diferentes de x e o valor correspondente de largura (determinados pela restrio de
centragem), voc pode visualmente estimar os valores acima (ou valores semelhantes). Note-se que
100% - (80% + 10%) = 10%, o que significa que o retngulo ser centrado horizontalmente, embora
no seja centrado verticalmente. Os valores para o largura e preenchimento de borda pode, do mesmo
modo, ser estimado atravs da experimentao.

7. Coloque um oval no topo de tudo e preencha-o com uma mscara transparente de amarelo,
mantendo a sua borda opaca:

<svg xmlns=" http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >


<title>Collage involving &lt;rect&gt; , &lt;circle&gt; and &lt;ellipse&gt; </title>
<circle cx="50%" cy="50%" r="25%" fill="none" stroke="#e60" stroke-width="25"/>
<rect x="10%" width="80%" y="50%" height="10%" fill="#8ff " stroke="black" stroke-width="6" />
<ellipse cx="50%" cy="50%" rx="10%" ry="40%" fill="yellow" fill-opacity=".45" stroke="purple" stroke-
width="15" />
</svg>

Uma elipse, como um crculo, tem um centro definido por cx e cy. No entanto, devido diferena nas
suas extenses verticais e horizontais, tem dois raios: RY e RX, respectivamente. Como esta oval mais
alta do que larga, voc pode aproximar os valores acima bem de perto, testando alguns valores e ver o
que acontece. Alternativamente, voc pode realmente medir o desenho na tela para duplicar o efeito
mais precisamente.

O cdigo anterior introduz um novo atributo: opacidade. Todos os objetos tpicos desenhados (tais
como retngulo, crculo, polgono, elipse, e caminho), todos tm um atributo opacidade. Quando a
opacidade definida como "1.0", borda e preenchimento de um objeto so completamente opacos.
Quando a opacidade definida como "0.0", o objeto completamente invisvel. Se voc no especificar
a opacidade, o navegador assume que a opacidade 1. Se voc deseja especificar diferentes nveis de
opacidade para a borda de um objeto e preencher, voc pode fazer isso usando os atributos "stroke-
opacity" e "fill-opacity".
Captulo 2 - Criar e editar grficos SVG

Este grfico incorpora todas as formas bsicas, a curva de Bzier simples, curvas de Bzier cbica mais
complexas e imagens bitmap. Ele tambm demonstra o agrupamento lgico e a reutilizao de grficos
relacionados, e, finalmente, como reunir tudo em um padro de azulejos reutilizvel, que tambm
conhecido como mosaico do avio.

Criando vetores de formas bsicas

Para comear, ns falaremos sobre os seis elementos bsicos da forma: <line>, <rect>, <circle>, <ellipse>,
<polyline>, e <polygon>.

Linhas: Para criar uma linha visvel em SVG, basta definir os X2 e Y2 valores do elemento<line>. Voc
pode definir a cor de linha e outras propriedades tambm usando os atributos (stroke) relacionados a
borda.

<line x2="300" y2="100" stroke="green" stroke-width="10" stroke-linecap="round" />


Observao: Por padro, a maioria das propriedades das formas SVG tm valores iniciais ou padro. Por
exemplo, o valor inicial da maioria das propriedades de posicionamento zero (0,0), que a razo de
no ter que especificar as coordenadas X1 e Y1 para o elemento <line>. Alm disso, a cor de
preenchimento padro para formas preto, por isso a forma <circle r = "50"> ou <polygon points =
"850,75 850.325 742.262 742.137" /> aparecer na cor preta, embora o preenchimento no tenha sido
especificado.

Breve reviso de SVG - Apresentando atributos

Alm dos atributos de comandos que definem uma forma de posio (ccordenadas x,y), raio(r), largura
(width) e altura (height), SVG tem tambm muitos atributos que definem um estilo de forma. Voc
provavelmente j est familiarizado com atributos como exposio(display), visibilidade(visibility),
fonte(font) e espao entre caracteres (letter-spacing). SVG tambm tem muitas propriedades especficas
de estilizao SVG (como no exemplo de cima, que mostra como o atributo "stroke" permite definir a
cor da linha).

Os atributos de apresentao SVG podem ajud-lo a definir rapidamente os valores geomtricos e de


cores dos elementos SVG; aplicar gradientes, filtros e recortes; e controlar o comportamento interativo.
O Captulo 3, "Adicionando Texto, o estilo, e transformaes", abrange apresentao de atributos com
mais profundidade, mas a Tabela abaixo fornece uma referncia rpida para propriedades comuns que
voc vai usar neste captulo.

Valores comuns de atributos

stroke: Especifica a cor do trao. Os valores de cor vlidos so os mesmos que em CSS3 e HTML5:
nome de cor (por exemplo, "blue",), hexadecimal (por exemplo, "# f34a12"), RGB (por exemplo, "rgb
(255,255,255)"), HSL (Por exemplo, "RGB (100%, 50%, 90%)"),%), e assim por diante.

stroke-width: Especifica a largura do trao ou para uma forma de texto, utilizando um valor de
percentagem ou comprimento. Quando se utiliza um valor de comprimento, recomendamos que seja
especificado o tipo de unidade (px, cm, etc.) para impedir questes de incompatibilidade entre
navegadores. importante ressaltar que as unidades especificadas na tag <svg> mais externa so
herdadas por todos os descendentes, e que o valor padro px. Note que o trao est centrado sobre a
borda de uma forma, por isso, se a largura do trao definida para um valor grande, o preenchimento
da forma no pode ser mostrado.

stroke-opacity: Este um nmero entre 1,0 e 0,0. Um valor de 1 faz com que o trao seja totalmente
opaco e 0 ir torn-lo invisvel.

stroke-dasharray: Esta uma lista de valores de coordenadas do usurio (px) que determina o
comprimento ou o padro de espaamento para ser feita entre segmentos ao longo do traado do texto
ou da forma.

stroke-linecap: Define a forma em ambas as extremidades de uma linha. As opes so "butt" (o


padro), "round", e "square".
stroke-linejoin: Determina a forma para ser usada nos cantos dos caminhos ou formas bsicas. As
opes so "miter"(o padro), "round", e "bevel".

fill: Especifica a cor da forma ou texto.

fill-opacity: Semelhante stroke-opacity. Note que se a opacidade entre 0 e 1, e o valor do trao


definido como uma cor ou opacidade diferente do que a cor de preenchimento, ento, a parte interna
do traado ser de uma cor diferente do que a parte exterior, o que pode criar alguns efeitos agradveis.

fill-rule: Determina quais partes de uma forma sero preenchidas. As opes so "nonzero" (o padro) e
"evenodd". Note que este geralmente simples, mas para formas mais interessantes ou complexas, o
resultado de "fill-rule" pode ser menos bvio, como explicado nas propriedades de preenchimento:
"nonzero" e "evenodd".

Retngulos

O elemento retngulo (<rect>) requer atributos "width"(largura) e "height"(altura), mas voc tambm
pode especificar os atributos x e y, que definem a posio em relao ao canto superior esquerdo da
forma na tela SVG. Se eles no forem especificados, o padro ser (0,0). Rx e Ry so atributos opcionais
que aplicam um arredondamento uniforme para todos os cantos e tambm esto disponveis. Se apenas
for especificado rx, ry ser igual a rx.

<rect x="50" y="50" width="300" height="170" rx="90" ry="50" stroke="darkseagreen" stroke-width="10"


fill="lightgray" fill-opacity="0.6" />

Crculos

Como mencionado no Captulo 1, "Primeiros passos em SVG," o SVG elemento <circle> requer apenas
um valor para o raio. Na imagem a seguir, os valores de cx e cy esto definidos para (100,50).
<circle cx="150" cy="150" r="100" stroke="darkseagreen" stroke-width="10" fill="grey" fill-opacity="0.6"/>

Elipses

O elemento <ellipse> fornece o atributo adicional "ry" para que tanto os valores dos raios x e y possam
ser definidos como mostrado abaixo:

<ellipse cx="110" cy="55" rx="70" ry="35" stroke="darkseagreen" stroke-width="0.8" fill="lightgray" fill-


opacity="0.6" />

Polilinhas e polgonos

H apenas duas formas bsicas adicionais: a polilinha e o polgono. Eles so muito semelhantes pois
ambos exigem que os pontos de atributo, que contm uma lista de pares de valores (x, y), sejam
desenhados em uma srie de linhas retas como se uma caneta fosse utilizada para desenhar no papel.

A principal diferena de forma entre os elementos polilinha <polyline> e polgono <polygon> em SVG,
que o caminho <polyline> no ser fechado por padro - os dois pontos finais no sero conectados a
menos que voc especifique. Se voc deseja uma forma <polyline> fechada, voc precisa especificar
desenhando um ponto final que coincida com o ponto de partida. O polgono <polygon>, por outro
lado, vai fechar automaticamente a forma a partir do ltimo ponto especificado, como mostrado neste
exemplo:
// aberto
<polyline points="200,60 240,230 310,230 350,60" fill="lightcyan" fill-opacity="0.7" stroke="darkviolet" stroke-
width="25" stroke-linecap="round" stroke-opacity="0.2" />

// fechado
<polygon points="100,50 115,120 150,150 115,180 100,250 85,180 50,150 85,120" fill="darkorange" fill-
opacity="0.5" stroke="papayawhip" stroke-width="20" stroke-opacity="0.7" stroke-linejoin="miter"/>

Criatividade com formas bsicas

A beleza da linguagem SVG que, com apenas esse conhecimento bsico, voc j capaz de comear a
construir alguns vetores grficos complexos que se prestaro em todos os principais navegadores. Como
um exemplo, esta imagem seguinte demonstra algumas das coisas extravagantes que voc j pode fazer
com um pouco de criatividade e conhecimento das propriedades das formas SVG.

O prximo exemplo mostra como o elemento <line> pode ser estilizado, com resultados surpreendentes.
Todos as formas do lado esquerdo da figura foram criadas com um nico elemento <line>, e todas as
formas do lado direito foram criados com apenas dois elementos <line>.
Ainda mais interessante, o seguinte exemplo minimalista demonstra como criar formas circulares
extravagantes usando apenas um ou dois elementos <circle>.

Este terceiro exemplo usa apenas um ou dois elementos <polygon> - novamente com resultados
interessantes:

Caminhos (Paths) em SVG

O elemento <path> o mais flexvel desenho primitivo em SVG. Ele contm subcomandos que
permitem imitar todas as outras formas bsicas. Como tal, um pouco mais complicado para aprender.

Como outras primitivas de desenho, tais como <rect> e <ellipse>, <path> pode ter atributos como
preenchimento (fill), trao (stroke), e matriz trao (dash array). Por outro lado, <path> usa uma sintaxe
especial para descrever a maneira como ele realmente desenha. Ele empresta um pouco de sua origem
(pelo menos ideologicamente) a partir dos grficos desenhados pela tartaruga, utilizados na linguagem
de programao Logo, a linguagem que ajuda a introduzir as crianas nas noes bsicas de
programao de computadores.

O elemento SVG <path> muito expressivo devido gama de poderosos comandos que usa. Tal como
acontece com o elemento HTML5 <canvas>, caminhos podem ser usados para desenhar pen-up e os
movimentos de caneta para baixo, curvas quadrticas e cbicas de Bzier e arcos elpticos, tudo dentro
de um nico caminho. Ou seja, voc move a caneta (ou ponto de desenho) de posio para posio,
levantando-a e baixando-a, e fazendo cursos de diferentes tipos. Estas instrues dentro da sintaxe
<path> so chamadas subcomandos do caminho do objeto. Em SVG, voc vai encontr-los nos
atributos de dados (d) do <path>.

Paths normalmente comeam com o subcomando M, que instrui o desenho para comear em um ponto
especfico (x, y), tal como (100, 100), assim:
d = "M 100,100 ..."
De l, voc continua a adicionar pontos, isto , pares (x, y) descrevendo os segmentos a serem unidos ao
longo do caminho. A seo a seguir mostra como isso funciona.

<path> Subcomandos: M e L

Comece especificando onde o desenho comear. Como o primeiro comando para o atributo d, voc
insere uma notao tais como M x y, em que x e y so nmeros. Voc pode pensar em M x y no sentido
de "Movimente a caneta para as coordenadas (x, y). "A partir da, voc tem a opo de desenhar uma
linha (L), uma curva quadrtica (Q), uma curva cbica (C), ou um arco (A). Por exemplo, d = "M 50
50 L 150 150" iria traar uma linha diagonal do ponto (50,50) para o ponto (150,150).

<path stroke="black" d="M 50 50 L 150 150"/>


<path d="M 150 50 L 250 150 350 100"/>

Voc deve observar vrias coisas neste exemplo:

O segundo caminho no especifica um trao (stroke); por padro, o valor preenchido com preto. Se
voc especificar preencher = "none", a figura ser invisvel a menos que voc especifique um trao
(stroke).

Voc pode, por uma questo de legibilidade, usar vrgulas entre pares de coordenadas, o espao aps a
vrgula fica opcional.

Voc pode omitir a letra de comando em comandos subseqentes se o mesmo comando usado vrias
vezes seguidas, como mostrado no segundo percurso, no qual o comando seguido por L dois pares de
valores. Note-se tambm que, se um comando "MoveTo" (M ou m) for diretamente seguido de
mltiplos pares de coordenadas, os pares subsequentes so tratados como comandos "LineTo"
implcitos.
Propriedades de preenchimento (fill): "nonzero" e "evenodd"

Uma vez que um caminho (path) est preenchido com preto por padro, natural se perguntar o que
acontece quando os caminhos (path) se cruzam entre si. Como mencionado na Tabela 2-1, o valor de
preenchimento regra padro diferente de zero (nonzero), o que significa que, por padro, a unio das
regies atravessadas pelo caminho est preenchida, a menos que voc especifique o contrrio. Voc pode
encontrar mais informaes sobre isso na seo "Propriedades de preenchimento" da especificao SVG,
em http://www.w3.org/TR/SVG/painting.html#FillProperties.
Aqui est um exemplo para mostrar a diferena entre os valores de preenchimento de regras "nonzero" e
"evenodd".

<path d="M 70,290 L 150,150 200,250 40,250 100,150 170,290"/>


<path d="M 70,290 L 150,150 200,250 40,250 100,150 170,290" fill-rule="evenodd"
transform="translate(250,0)"/>

Este exemplo demonstra a tcnica de preenchimento padro, bem como a regra de preenchimento
"evenodd" em uma forma que corta a si mesmo em mais de um lugar.

Nota: Para demonstrar como a regra de atributo "fill-rule" funciona neste exemplo, ns mudamos a
forma segundo percurso, que tem "EvenOdd" aplicada a ele, 250 unidades ao longo do eixo x - atravs
da utilizao do mtodo "translate" do atributo "transform". Voc vai aprender mais sobre as
capacidades do "transform" no Captulo 3.

Um exemplo de construo de formas complexas

Esta seo mostra como voc pode usar o comando M para criar formas mais complexas com<path>.

O cdigo a seguir cria dois caminhos (paths), com um aparentemente tirado de dentro do outro (no
sentido que as coordenadas de um esto contidas no interior do polgono definido pelos outros):

<path d="M 100,350 300,100 500,350" fill="none" stroke="black" stroke-width="20"/>


<path d="M 250,320 250,220 350,220 350,320" fill="none" stroke="black" stroke-width="20"/>

A figura contm dois caminhos: um com trs pontos, o outro com quatro. Note como o tringulo
engloba o retngulo.
A seguir, simplesmente adicionando o subcomando "z" na extremidade de cada uma das cadeias, fecha o
caminho, desenhando uma linha final de volta ao ponto de partida do caminho. Depois que fizer isso,
os caminhos sero fechados em vez de deixado em aberto entre os terminais.

<path d="M 100,350 300,100 500,350 z" fill="none" stroke="black" stroke-width="20"/>


<path d="M 250,320 250,220 350,220 350,320 z" fill="none" stroke="black" stroke-width="20"/>

Alternativamente, voc pode criar a imagem anterior utilizando apenas um nico objeto como segue:
<path d="M 100,350 300,100 500,350 z
M 250,320 250,220 350,220 350,320 z"
fill="none" stroke="black" stroke-width="20"/>

Este mtodo pode economizar um pouco em marcao, mas um pouco mais difcil. No entanto,
existem alguns benefcios adicionais nesta abordagem que valem a pena considerar. Atravs da
combinao dos dois formatos acima em um caminho composto, voc pode definir a regra de
preenchimento desse caminho como "evenodd". O efeito lquido disso que a cor de preenchimento da
forma no ir ser aplicada na regio interior (embora pudesse ser aplicado a regies dentro da regio
interior). Tente este cdigo combinado:
<path d="M 100,350 300,100 500,350 z
M 250,320 250,220 350,220 350,320 z"
fill="#ff8" stroke="black" stroke-width="15" fill-rule="evenodd"/>

Voc pode ver a vantagem no prximo grfico. Os retngulos que so a base do tringulo so visveis
atravs do orifcio retangular na forma. Este efeito seria difcil de se produzir se as duas peas deste
caminho composto fossem caminhos separados, porque para ser visvel, o retngulo teria de estar na
parte superior do tringulo, mas, nesse caso, nada no seu interior para alm do prprio tringulo seria
visvel.
Temos apenas uma demosntrao de como criar uma forma vetor grfica complexa usando um nico
elemento SVG <path> que contm um tringulo amarelo com um buraco rosa mostrando retngulos
verdes e vermelhos por baixo. A prxima seo discute a criao de formas usando curvas de Bzier.

Curvas de Bzier quadrtica: O subcomando Q

Tomei conscincia das curvas de Bzier em meados dos anos 1980 quando descobri que o Adobe
Illustrator tinha habilidade para desenhar curvas incrveis rapidamente.

A curva Bzier quadrtica trabalha em SVG basicamente assim: Voc define um ponto inicial (por
exemplo, 100 200) usando um comando "pen-down". De l, voc define um rumo em direo ao
ponto seguinte; no entanto, em vez de realmente passar para o prximo ponto, voc apenas aponta nessa
direo.
Assim, por exemplo, enquanto "M 100 200 L 200 400" vai fazer voc realmente chegar ao ponto
(200,400), "M 100 200 Q 200 400 ... "vai apenas apontar nessa direo. Em ltima anlise, voc
tambm precisa de um destino final, que o ltimo par de coordenadas necessrio para uma curva
Bzier quadrtica.
No exemplo que se segue, o comando "M 100.200 L 200.400 300.200" desenha um caminho vermelho
entre os trs pontos indicados atingindo cada um deles. Mas simplesmente substituir o L com um Q (ie,
"M 100.200 Q 200.400 300.200") produz uma curva que passa atravs de ambas as extremidades e
tangente s linhas associadas da linha de caminho aliada nos pontos de extremidade dos segmentos.

<path d="M 100 200 Q 200,400 300,200" fill="none" stroke="blue" />


<path d="M 100 200 L 200,400 300,200" fill="none" stroke="red"/>
Revisitando o exemplo anterior, que modificou a regra de preenchimento para produzir um espao vazio
no meio da curva, voc pode desenhar a mesma curva com "splines" quadrticas em vez de linhas para
ver o efeito.
Aqui est um exemplo de um grfico que usa uma spline quadrtica:

<path fill-rule="evenodd" d="M 70 140 L 150,0 200,100 L 40,100 100,0 L 170,140 70 140"/>
<path fill="red" fill-rule="evenodd" d="M 70 140 Q 150,0 200,100 Q 40,100 100,0 Q 170,140 70 140"/>

Observe como o exemplo acima

<path id="H" fill="#bbb" fill-rule="evenodd" d="M 70 140 L 150,0 200,100 L 40,100 100,0 L 170,140 70 140"/>

pode ter seus Ls modificado para Qs:

<path id="X" fill="#b42" fill-rule="evenodd"d="M 70 140 Q 150,0 200,100 Q 40,100 100,0 Q 170,140 70 140"/>

Isso produz uma forma semelhante seguinte (ns mudamos as cores e acrescentamos identificadores
aos caminhos para fcil referncia no texto aqui):

A figura mostra dois caminhos (paths) produzidos a partir do cdigo anterior. Ambos os caminhos tm
os mesmos pontos, mas um linear (ID = "H") e a outra quadrtico (ID = "X"). Observa-se nos
ngulos da forma avermelhada (X) que as curvas so mais afiadas do que arredondadas. Vamos dar uma
olhada mais de perto. Se voc estiver familiarizado com ns trevo (veja http://en.wikipedia.org/wiki/
Trefoil_knot), ento essa a direo na qual estaremos apontando.
Em primeiro lugar, observa-se que se a forma desejada passar atravs de qualquer um dos seis pontos do
caminho linear H, ento para que as partes da curva que se encontram ali sejam suaves, e para qualquer
uma delas ser tangente s linhas de H, a nova curva teria que se estender alm dos limites da X.
Voc poderia estender as linhas de X em um tringulo equiltero maior e, em seguida, trabalhar na
construo de seu n de trevo. Voc poderia fazer isso com curvas Bzier cbicas definindo uma curva
que passa pelos mesmos trs pontos de extremidade, o que j faz, mas que guiada pelos pontos de
controle que consistem em trs pontos do tringulo circunscrito (mostrado na prxima figura com a
linha verde claro).

<path fill="#c53" fill-rule="evenodd" opacity="0.5"


d="M 70 140 C 17.5 ,140 150,0 200,100 C 220, 140 40,100 100,0 C 127,-47 170,140 70 140"/>

Como exemplo final, a seguir demonstramos como costurar curvas de Bzier em conjunto sem
problemas. Para que isso acontea, as inclinaes das linhas em cada lado do ponto da extremidade de
um segmento devem ser as mesmas.

Observe que os caminhos marrom e azul partilham os mesmos pontos inicial e final, e os pontos de
controle final e mdio (150, 200). Eles diferem apenas em termos dos pontos de controle em torno do
ponto mdio. O caminho em direo azul visa (100,100) e, em seguida, muda de direo em direo a
(200,300), que passa atravs do ponto mdio da sua forma e tangente linha, conforme mostrado.
Porque os trs pontos relevantes, (100,100), (150,200), e (200, 300), esto alinhados, as encostas de
ambos os segmentos so as mesmas no ponto onde eles se encontram, o que implica que a curva suave
(contnua diferencivel) naquele ponto.

Criao de curvas suaves: os subcomandos S e T

Estes comandos de atalho ajudam com a criao de curvas suaves, e eles exigem menos pontos do que
na construo de curvas de Bzier cbicas e quadrticas sem eles. Isso porque um dos pontos da curva
de Bezier utilizado simplesmente como um ponto de referncia, o qual ento refletido para criar uma
curva suave.

Voc usa o comando S para desenhar um segmento spline de Bzier cbica suave do ponto atual para
um novo ponto (x, y). O segmento anterior tambm deve ser uma spline Bzier cbica lisa, na qual o
segundo ponto de controle ento reutilizado atravs da reflexo relativa ao ponto atual como primeiro
ponto de controle do segmento. O segundo controle deve ser explicitamente especificado.

Voc usa o comando T para desenhar um segmento spline de Bzier quadrtica suave do ponto atual
para um novo ponto (x, y). O segmento anterior tambm deve ser uma spline Bzier quadrtica suave,
na qual o ponto de controle ento reutilizado atravs da reflexo relativa ao ponto atual.

A imagem a seguir demonstra o processo de reflexo automtico para os dois comandos:

Como voc viu, o elemento <path> pode expressar ambas as formas simples e complexas usando os
comandos L, H, V, Q e C. Os clculos geomtricos envolvidos so bastante complexos, razo pela qual
os programas de desenho vetorial como o Inkscape, Illustrator, SVG-Edit, e Visio so muito teis no
processo de concepo SVG.

Exemplo de arco elptico

Um outro comando <path> frequentemente utilizado o comando arco elptico (A), que permite que
voc rapidamente desenhe subconjuntos de elipses ou elipses que se cruzam. O subcomando arco do
elemento <path> tem a seguinte sintaxe: A rx ry XAR large-arc-flag sweep-flag x y.
O arco comea no ponto atual (que determinado pelo ltimo par de coordenadas (x,y) especificado) e
termina em (x, y), como demonstrado abaixo:
Agora voc tem a escolha de quatro segmentos de arco elpticas: duas pequenas e duas grandes. Estes
segmentos de arco podem ter uma orientao positiva angular (sentido horrio) ou uma orientao
negativa (sentido anti-horrio). A "large-arc-flag" (fl) controla a orientao angular do maior segmento
de arco via fl = 0: pequeno, fl = 1: grande. A "sweep-flag" (fs) controla a orientao angular de forma
anloga, via fs = 0: positivo e fs = 1: negativo.

Nota: Para o caso especial onde as coordenadas de ponto final (x, y) so iguais s coordenadas do ponto
atual, o arco no ser renderizado. Como esse comportamento no intuitivo quando "large-arc-flag"
definido como 1, isso pode ser mudado segundo a especificao SVG 2.0.

Usando essa informao do arco elptico, aqui est o cdigo para criar uma espiral simples:

<svg width="600" height="400" viewBox="0 0 400 300">


<path stroke="darkslategray" stroke-width="6" fill="none" stroke-linecap="round"
d="M50,100
A100,50 0 0 1 250,100
A80,40 0 0 1 90,100
A60,30 0 0 1 210,100
A40,20 0 0 1 130,100
A20,10 0 0 1 170,100" />
</svg>
Tabela 2-2 fornece uma referncia rpida para os comandos e propriedades do <path>.

Instruo Parmetros Comandos


M, m x, y Mover-se para um novo ponto (x, y).
L, l x, y Desenhar uma linha a partir do ponto atual para um novo ponto (x, y).
H, h x Desenhar uma linha horizontal a partir do ponto atual para um novo
ponto (x, ponto-atual y).
V, v y Desenhar uma linha vertical a partir do ponto atual para um novo
ponto (ponto-atual x, y).
A, a rx, ry, Desenhar um arco elptico do ponto atual para um novo ponto (x, y). O
x-axis-rotation, arco pertence a uma elipse que tem raios de RX e RY e uma rotao em
large-arc-flag, relao ao eixo x positiva eixo x de rotao (em graus). Se a "large-arc-
sweep-flag, flag" 0 (zero), ento um pequeno arco (menor que 180 graus)
x, y traado; um valor de 1 resulta em um grande arco (maior que 180
graus) sendo desenhado. Se "sweep-flag" 0, ento o arco desenhado
em uma direo angular negativa (sentido anti-horrio); se for 1, ento
o arco desenhado numa direo angular positiva (sentido horrio).
Q, q x1, y1 Desenhar uma curva Bzier quadrtica a partir do ponto atual para um
x, y novo ponto (x, y) utilizando (x1, y1) como o ponto de controle.
T, t x, y Desenhar um segmento de curva Bzier quadrtica suave a partir do
ponto atual para um novo ponto (x, y). O ponto de controle calculado
automaticamente como o reflexo do ponto de controle do comando
anterior em relao ao ponto atual. Se no houver nenhum comando
anterior, ou se o comando anterior no era um Q, q, T, ou t, o ponto de
controle coincidente com o ponto atual.
C, c x1, y1 Desenhar uma curva Bzier cbica do ponto atual para um novo ponto
x2, y2 (x, y) utilizando (x1, y1) e (x2, y2) como pontos de controle.
x, y
S, s x2, y2 Desenhar um segmento de curva Bzier cbica suave do ponto atual
x, y para um novo ponto (x, y). O primeiro ponto de controle calculado
automaticamente como o reflexo do ponto de controle do comando
anterior em relao ao ponto atual. Se no houver nenhum comando
anterior, ou se o comando anterior no era um C, c, S, ou s, o primeiro
ponto de controle coincidente com o ponto atual, e (x2, y2) o
segundo ponto de controle.

Coordenadas <path> absolutas vs. Relativas

O exemplo seguinte utiliza uma mistura de comandos MoveTo (M), Vertical (V), LineTo (L), Bezir
(Q), HorizontalTo (H), e ClosePath (Z) para gerar uma forma bastante elegante, como mostrado no
lado esquerdo da imagem seguinte. O exemplo direita exige menos poder do crebro espacial para
gerar a mesma forma porque ele usa verses relativas dos comandos (ou seja, comandos em minsculas).
As coordenadas do novo ponto so em relao posio do ponto anterior (40,80).
A partir de botes, cones e UIs de janela, para a construo de grficos e grficos de jogos, h muitos
casos de uso lgicos para o acesso e reutilizao de raster e vetores grficos em SVG.
Vinculando a ambos os dados de imagem internos e externos vale a pena uma rpida meno aqui,
porque um mtodo comum para o acesso e reutilizao SVG.

Referenciando imagens vetoriais e de bitmap

A linguagem SVG fornece o elemento <image>, que pode fazer referncia a outras imagens SVG, bem
como s imagens bitmap PNG e JPEG. A sintaxe para o elemento <image> semelhante ao elemento
<rect> que tem x, y, largura, altura e atributos.
O elemento <image> tem o atributo adicional "xlink:href", que permite que voc especifique o local
da imagem de referncia. Semelhante ao atributo "href" do HTML, o atributo "xlink: href" permite
que a imagem referenciada possa ser armazenada localmente ou na Internet. O cdigo para fazer
referncia a uma imagem bitmap o seguinte:

<image xlink:href="GrandMothersParty-121YO.png" x="340" y="0" width="140" height="160" opacity="0.5"/>

Fazer referncia a outras imagens SVG torna-se fcil e muito til em muitos cenrios de aplicao, como
reutilizar o mesmo smbolo do vetor em uma pgina ou em carregamento dinmico de imagens vetoriais
sob demanda.

O elemento Grupo <g>

O elemento grupo SVG, <g>, timo para agrupar logicamente conjuntos de objetos grficos
relacionados. O grupo faz com que seja fcil adicionar estilos, transformaes, interatividade, e at
mesmo animaes para todo um grupos de objetos.
Os seguintes grupos de cdigos de uma imagem bitmap e um crculo, juntos, em um grupo chamado
ris, so, em seguida, agrupados em conjunto com uma forma de elipse em outro grupo chamado olho.

<g id="eye">
<!-- desenho da elipse -->
<ellipse fill="#a1d9ad" fill-opacity="0.7" fill-rule="nonzero" stroke="#32287d" stroke-width="1" stroke-
opacity="0.5" />
<!-- grupo contendo a ris -->
<g id="iris" cx="50" cy="50" rx="20" ry="14" />
<!-- desenho do crculo -->
<circle fill="black" fill-opacity="1" fill-rule="nonzero" stroke="#32287d" stroke-width="1" stroke-
linecap="butt" stroke-linejoin="bevel" stroke-miterlimit="4" id="path3395" cx="50" cy="50" r="10" />
<!-- referncia a imagem bitmap PNG -->
<image id="bitmapCentralBall" width="5.5%" height="5.5%" x="39px" y="42px" xlink:href="iris-
small.png" alt="NASA Photo of Jupiter" />
</g>
</g>
Com um pouco de criatividade, voc poderia, ento, adicionar um pouco de interatividade em que o
grupo "ris" seguiria o mouse, enquanto o grupo "olho" piscaria de forma aleatria ou em intervalos
definidos.
Voc vai ver outra grande utilidade para <g> durante a discusso das transformaes e interatividade em
SVG no Captulo 4, "movimento e interatividade". Voc pode associar itens juntos em um grupo e, em
seguida, definir transformaes para mover, dimensionar ou girar todos os itens em conjunto mantendo
as relaes espaciais de uma para outra. Atravs do uso de interatividade em SVG, pode-se atribuir, por
exemplo, um evento "onclick" para um grupo inteiro de modo que todos os elementos dentro do
grupo respondam ao evento.

O Elemento <use>

O elemento <use> permite reutilizar elementos existentes e, assim, escrever menos cdigo. Tal como o
elemento <image>, <use> leva x, y, altura, largura e atributos, e faz referncia a outros contedos usando
o atributo "xlink: href".
Como exemplo, voc pode reutilizar o seguinte retngulo:

<!-- Desenho de um retngulo no canto superior direito -->


<rect fill="#ada1d9" fill-opacity="1" fill-rule="nonzero" stroke="#32287d" stroke-width="10" stroke-linecap="butt"
stroke-linejoin="bevel" stroke-miterlimit="4" stroke-opacity="0.4" id="rectangle" width="20" height="20" x="90"
y="-10" />

referenciando-o com o elemento <use>:

<!-- Reusar o primeiro retngulo e mov-lo para uma posio diferente -->
<use x="" y="" xlink:href="#rectangle" />

Criando Padres (patterns)

A linguagem SVG ajuda voc a criar e reutilizar padres facilmente. Os padres so extremamente teis
- na verdade, a grade de fundo encontrada em muitos dos exemplos deste livro apenas um padro
simples que consiste de um nico retngulo de 10 x 10 pixels. O elemento <defs> pode ser usado para
armazenar o contedo que no ser exibido diretamente. Este contedo oculto armazenado pode ento
ser referenciado e exibido por outros elementos SVG, o que o torna ideal para coisas como padres que
contm grficos reutilizveis.
Para criar um padro bsico em SVG, em primeiro lugar ponha um retngulo dentro de um elemento
<pattern>, e depois coloque tudo dentro de um elemento <defs>.
<defs>
<pattern id="Pattern01" width="10" height="10" patternUnits="userSpaceOnUse">
<rect width="10" height="10" fill="#FFFFFF" stroke="#000000" stroke-width="0.1"/>
</pattern>
</defs>

Agora, para usar este padro em qualquer lugar em seu grfico SVG, basta definir o atributo de
preenchimento do seu elemento com o valor do "id" do padro, como este: url (# Pattern01).

<rect id="Background" x="0" y="0" width="100%" height="100%" fill="url(#Pattern01)" stroke-width="0.5"


stroke="#000000" />

Estudo de caso: Projetando um padro reutilizvel

O exemplo nesta seo analisa como escrever o cdigo SVG que gera um padro composto tanto por
vetor como por bitmap.

Adicionando formas bsicas

Baseando-se em seu conhecimento at este ponto, voc vai caminhar atravs de cada etapa do projeto e
do processo de criao.

1. Criar e salvar um arquivo chamado "tile.svg" que contm as seguintes linhas de cdigo:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" width="800" height="600" viewBox="0 0 400 300" preserveAspectRatio="none">
<g id="layer1"></g>
</svg>

2. Com este quadro, voc pode comear a adicionar algumas formas bsicas. O prximo exemplo
mostra um design padro simples. Padres de azulejos so conhecidos matematicamente como mosaicos
de avio.

Para criar esse padro em cdigo SVG, primeiro crie a seguinte linha:

<line stroke="#000000" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4"


stroke-opacity="0.4" stroke-dasharray="1, 6" stroke-dashoffset="0" x1="90" y1="10" x2="10" y2="90"
id="patternLine1" />
Agora, como mencionado anteriormente, voc pode reutilizar a linha. Ao alterar os valores x e y voc
pode girar a linha em 90 graus. Alm disso, para misturar o padro um pouco, voc pode substituir
"stroke-opacity" e outros atributos de estilo que de outra forma seriam herdadas do elemento
referenciado:

<use stroke-opacity="1" transform="rotate(90, 50, 50)" xlink:href="#patternLine1" id="patternLine2" />

3. Em seguida, chame o resto dos elementos que voc deseja incluir no seu padro por exemplo:

<ellipse fill="#a1d9ad" fill-opacity="0.7" fill-rule="nonzero" stroke="#32287d" stroke-width="1" stroke-


opacity="0.5" id="path3389" cx="50" cy="50" rx="30" ry="20" />
<!-- Desenho do retngulo -->
<rect id="patternRect-upperRight" fill="#ada1d9" fill-opacity="1" fill-rule="nonzero" stroke="#32287d" stroke-
width="10" stroke-linecap="butt" stroke-linejoin="bevel" stroke-miterlimit="4" stroke-opacity="0.4" width="20"
height="20" x="90" y="-10" />

<!-- Reutilize o primeiro retngulo e gire-o 90 graus de cada vez. -->


<use id="patternRect-lowerRight" transform="rotate(90, 50, 50)" xlink:href="#patternRect-upperRight"/>
<use id="patternRect-lowerLeft" transform="rotate(180, 50, 50)" xlink:href="#patternRect-upperRight"/>
<use id="patternRect-upperLeft" transform="rotate(270, 50, 50)" xlink:href="#patternRect-upperRight"/>

<!-- Desenhe o crculo. -->


<circle id="path3395" fill="#d9d2a1" fill-opacity="1" fill-rule="nonzero" stroke="#32287d" stroke-width="1"
stroke-linecap="butt" stroke-linejoin="bevel" stroke-miterlimit="4" cx="50" cy="50" r="10" />

<!-- Desenhe o caminho usando coordenadas "relativas" via comandos com letras minsculas. Note que podemos
facilmente passar a usar o elemento "Polyline" mudando o atributo "d" para "points". -->
<path id="patternPath-lowerLeft" fill="none" stroke="#000000" strGoke-width="1px" stroke-linecap="butt" stroke-
linejoin="miter" stroke-opacity="1"
d="m 0,50 10,0 0,20 20,20 0,0 0,0 20,0 0,10" />

<!-- Reutilize o primeiro caminho, rodando-o mais de 90 graus para cada um dos quatro cantos. -->
<use id="patternPath-upperLeft" transform="rotate(90, 50, 50)" xlink:href="#patternPath-lowerLeft" />
<use id="patternPath-upperRight" transform="rotate(180, 50, 50)" xlink:href="#patternPath-LowerLeft" />
<use id="patternPath-lowerRight" transform="rotate(270, 50, 50)" xlink:href="#patternPath-lowerLeft" />

Estes elementos SVG formam a base para o padro que voc ir criar na etapa seguinte. Vocs devem ter
notado o uso do atributo de transformao. Voc pode ver como o retngulo referenciado e as formas de
<path> foram movidas para uma posio diferente atravs de um comando de rotao. O prximo
captulo vai cobrir a utilidade das transformaes em maiores detalhes.

4. Para criar um padro de design mais interessante, ao invs de usar o comando MoveTo (M),
simplesmente altere os valores <path> do elemento para usar um posicionamento relativo da curva
Bezir quadrtica usando o comando "s", e um posicionamento absoluto de uma curva de Bzier cbica,
usando "C". Assim, os dados do caminho tornam-se o seguinte:

d="M 0,50 s 10,0 0,20 C 20,20 0,0 0,0"

5. Adicione uma referncia a uma imagem bitmap do planeta Jpiter e posicione a imagem no centro.
Alm disso, mova os grficos para a origem do sistema de coordenadas, o que equivale a atribuir a (x, y)
o valor de (0,0), para concluir o projeto inicial do azulejo. Agora, o azulejo tem esta aparncia:
6. Por fim, adicione o elemento <pattern> dentro de um elemento <defs> e mova o projeto do mosaico
para dentro do elemento <pattern>.

<defs>
<pattern id="gridPatternWithTessellation" x="20" y="20" width="100" height="100"
patternUnits="userSpaceOnUse">
<!--Insira os elementos aqui. -->
</pattern>
</defs>

Abaixo do <defs>, ento voc simplesmente cria um retngulo, caminho, ou qualquer outra forma SVG
e defina seu valor para ser preenchido com o padro, conforme mostrado no final da lista do cdigo
completo abaixo.

<svg xmlns=" http://www.w3.org/2000/svg" xmlns:xlink=" http://www.w3.org/1999/xlink" id="chapter2-


ShapesPatternsGroupsUse" version="1.1" width="800" height="600" viewBox="0 0 400 300"
preserveAspectRatio="none">
<defs>
<!-- Comeo do exemplo -->
<pattern id="gridPatternWithTessellation" x="20" y="20" width="100" height="100"
patternUnits="userSpaceOnUse">

<!-- Desenha as linhas -->


<line id="patternLine1" stroke="black" stroke-width="1" stroke-linecap="round"
strokelinejoin="round" stroke-miterlimit="4" stroke-opacity="0.4" stroke-dasharray="1, 6"
stroke-dashoffset="0"x1="90" y1="10" x2="10" y2="90" />

<!-- Reutiliza a primeira linha rotacionando-a 90, e atualiza os atributos de estilo.-->


<!-- Para apndice ou wiki-note que, atualmente, a maioria dos navegadores no suportam estilizao de
elementos usando CSS ou atributos SVG -->
<use id="patternLine2" stroke-opacity="1" transform="rotate(90, 50, 50)" xlink:href="#patternLine1" />

<!-- Desenha o retngulo do alto direita. -->


<rect id="patternRect-upperRight" fill="#ada1d9" fill-opacity="1" fill-rule="nonzero" stroke="#32287d"
stroke-width="10" stroke-linecap="butt" stroke-linejoin="bevel" stroke-miterlimit="4" stroke-
opacity="0.4" width="20" height="20" x="90" y="-10" />

<!-- Reutiliza o primeiro elemento retngulo e gira-o 90 graus cada um. -->
<use id="patternRect-lowerRight" transform="rotate(90, 50, 50)" xlink:href="#patternRect-
upperRight" />
<use id="patternRect-lowerLeft" transform="rotate(180, 50, 50)" xlink:href="#patternRect-
upperRight" />
<use id="patternRect-upperLeft" transform="rotate(270, 50, 50)" xlink:href="#patternRect-
upperRight" />

<!-- Grupo do olho. -->


<g id="eye">
<!-- Desenha a elipse. -->
<ellipse fill="#a1d9ad" fill-opacity="0.7" fill-rule="nonzero" stroke="#32287d" stroke-
width="1" stroke-opacity="0.5" cx="50" cy="50" rx="22" ry="14" />

<!-- Grupo contendo a ris do olho -->


<g id="iris">
<elipse id="path3389" cx="50" cy="50" rx="20" ry="14" />
<!-- Desenha o crculo -->
<circle id="path3395" fill="black" fill-opacity="1" fill-rule="nonzero"stroke="#32287d"
stroke-width="1" stroke-linecap="butt" stroke-linejoin="bevel" stroke-miterlimit="4"
cx="50" cy="50" r="10" />
<!-- Referncia a imagem bitmap (PNG) -->
<image id="bitmapCentralBall" width="5.5%" height="5.5%" x="39px" y="42px"
xlink:href="iris-small.png" alt="NASA Photo of Jupiter" />
</g>
</g>
<!-- Desenha o <path> usando coordenadas relativas atravs dos comandos em letras minsculas. Podemos tambm
trocar o elemento <polyline> mudando o "d" por "points" -->
<path id="patternPath-lowerLeft" fill="none" stroke="black" stroke-width="1px" stroke-
linecap="butt" stroke-linejoin="miter" stroke-opacity="1" d="M 0,50 s 10,0 0,20 C 20,20 0,0 0,0" />

<!--Outro <path> interessante-->


MoveTo Polyline-like d="m 0,50 10,0 0,20 20,20 0,0 0,0 20,0 0,10"
Quadratic d="M 0,50 Q 10,0 0,20 S 20,20 0,0"
Smooth Quadratic d="M 0,50 S 10,0 0,20 Q 20,20 0,0"
Cubic d="M 0,50 C 10,0 0,20 20,20 S 0,0 0,0"
Smooth Quadratic & Cubic d="M 0,50 s 10,0 0,20 C 20,20 0,0 0,0" -->

<!-- Reutilize o primeiro <path> rotacione-o 90 para utilizar nos quatro cantos -->
<use id="patternPath-upperLeft" transform="rotate(90, 50, 50)" xlink:href="#patternPath-
lowerLeft"/>
<use id="patternPath-upperRight" transform="rotate(180, 50, 50)" xlink:href="#patternPath-
lowerLeft"/>
<use id="patternPath-lowerRight" transform="rotate(270, 50, 50)" xlink:href="#patternPath-
lowerLeft" />
</pattern>
</g>
<pattern id="gridPattern" width="10" height="10" patternUnits="userSpaceOnUse">
<path d="M10 0 L0 0 L0 10" fill='none' stroke='gray' stroke-width='0.25'/>
</pattern>
</defs>

<g id="layer1">
<!-- grade de fundo -->
<rect id="grid" width="100%" height="100%" x="0" y="0" stroke='gray' stroke-
width='0.25' fill='url(#gridPattern)'/>

<!-- ilustrao da grade -->


<use xlink:href="#coords"/>
<text x="3" y="9" font-size='8'>(0,0)</text>
<!-- Fim do exemplo -->
<rect id="gridWithTessellation" width="300" height="300" x="20" y="20"
fill='url(#gridPatternWithTessellation)' />
</g>
<rect id="gridWithTessellation" x="20" y="20" width="300" height="300"
fill='url(#gridPatternWithTessellation)' />
</svg>

Com apenas estas linhas de cdigo, voc criou uma obra de arte interessante e um padro de azulejos
til que tem todas as vantagens do SVG. Para atender s necessidades de sua empresa, grupo ou
imaginao, voc s precisa editar o lado base para criar um design totalmente diferente para a sua
aplicao. Como h uma imagem bitmap dentro do padro, se os usurios finais fizerem um zoom eles
vero o grfico um pouco pixelado rodeado pelas linhas mais suaves dos grficos vetoriais que no
produzem pixelao. Voc deve considerar a pixelao do bitmap quando o projeto requer impresses de
alta-fidelidade.
Captulo 3

Adicionando texto, estilo, e transformaes

Adicionar texto a SVG bastante simples depois que voc compreender as construes bsicas. A
principal diferena entre texto e os elementos de forma em SVG que o texto est posicionado no canto
inferior esquerdo do primeiro caractere de texto: da linha de base da fonte (assumindo que o sistema de
escrita flui da esquerda para a direita, como o ingls, espanhol e portugus, ao contrrio do rabe ou
hebraico). Textos em SVG podem ser decorados, em forma, e espaados em um grande nmero de
formas, e se voc quiser explor-las de forma mais detalhada, voc pode olhar para a especificao SVG
1.1 para uma infinidade de detalhes. Por exemplo, espaamento entre letras e kerning, que controlam o
espao entre caracteres de texto, so determinados primeiro pelas regras de fonte padro, mas podem ser
substitudos pelo SVG "letter-spacing" e "font-kerning" constantes em
http://lists.w3.org/Archives/Public/www-svg/2012May/0101.html atributos.

Devido aos diferentes motores de renderizao de texto usados por diferentes implementadores, o texto
pode no renderizar exatamente da mesma forma. No entanto, a homogeneidade no processamento
geralmente satisfatria, embora poderia ser melhor.
A verso 2 da especificao SVG ir abordar o que considerado uma das principais limitaes para o
texto na verso atual (1.1) - a incapacidade de formatar o fluxo de texto (por exemplo, em um
retngulo). Para seu benefcio, no entanto, SVG tem a capacidade de definir fontes vetoriais e glifos com
contedo extremamente flexvel. Alguns dos exemplos na http://srufaculty.sru.edu/david.dailey/svg/text/
lhe dar uma boa viso geral do que pode fazer com texto SVG. Tambm recomendo que voc leia o
texto da especificao W3C, em http://www.w3.org/TR/SVG/text.html.
Tambm vale a pena ficar atento a como emerge a especificao SVG 2.0, uma vez que alguns aspectos
da manipulao de texto esto sendo melhoradas, alteradas e outras descartadas, para trazer o
tratamento de SVG em mais conformidade com CSS.

O elemento <text>

O exemplo clssico "Hello World" que se segue mostra como fazer uso do elemento <text>. Note que
o elemento <text> precisa de uma marca de fechamento aps o contedo do texto, como mostrado aqui:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">


<text x="20px" y="55px" font-family="Verdana" font-size="43pt">Hello World!</text>
</svg>

Alguns dos atributos mais teis do elemento <text> x (para definir a posio horizontal), y (para a
posio vertical da linha de base do texto), fill (para determinar a cor do texto ou padro), font-size, e
font-family, embora existam literalmente dezenas de outros atributos de texto que voc pode
experimentar. Como regra geral, o uso de atributos d a voc um controle preciso sobre o layout e
renderizao. Os valores de tamanho e posicionamento podem ser expressos com identificadores de
unidade, que so os mesmos do CSS:. em, ex, px, pt, pc, cm, mm, in. Se voc no especificar uma
famlia de fontes no exterior do elemento <svg> (ou atravs de uma folha de estilo) para todo o
documento, lembre-se de especific-lo sempre para um determinado elemento <text> ou para seu
elemento contentor; caso contrrio, o navegador usar a famlia de fontes que foi definido como o
padro nas opes do navegador.
A seguir, um exemplo mais interessante, usando uma variedade de caractersticas que permitem efeitos
comumente encontrados em software de edio de vetores, tais como gradientes, rotao e alongamento
do contedo textual:

<linearGradient id="g">
<stop offset="0" stop-color="#870"/>
<stop offset=".2" stop-color="#520"/>
<stop offset=".4" stop-color="#000"/>
<stop offset=".6" stop-color="#840"/>
<stop offset=".8" stop-color="#210"/>
<stop offset="1" stop-color="#832"/>
</linearGradient>

<text id="T" fill="none" stroke-width="4" stroke="url(#g)" stroke-opacity="1" font-family="serif "


font-stretch="ultra-expanded" stroke-dasharray="10 5" rotate="-25 -20 -15 -10 -5 0 5 10 15 20"
textLength="90" lengthAdjust="spacingAndGlyphs" font-style="oblique" text-decoration="overline" font-size="50"
x="5" y="65%" font-weight="bold">Decorative</text>

O exemplo acima tem esta aparncia no navegador Opera, embora se voc experiment-lo em outros
navegadores, possa ser surpreendido pela forma inconsistente com que ele pode ser processado:

Existe um pequeno programa chamado Textorizer (http://lapin-bleu.net/software/textorizer/) que pode


criar efeitos artsticos em SVG usando qualquer imagem bitmap (por exemplo, PNG ou JPEG) e
sobrepo-la com o texto de sua escolha. Como voc ver no exemplo de cdigo para a imagem SVG que
se segue, o programa mapeia as cores da imagem de fundo bitmap com a cor de cada palavra no texto
que voc especificar. Se voc, em seguida, remover o elemento <image> a partir do arquivo de sada,
voc acaba com um trabalho de arte interessante composto inteiramente de seu texto:

O elemento <tspan>

O elemento <tspan> permite agrupar e associar caracteres, frases e at pargrafos, enquanto permite
alterar a disposio dos glifos. Por exemplo, supondo que no precisemos mudar a cor e o tamanho de
cada caractere na sentena, poderamos aperfeioar o exemplo anterior, usando <tspan> assim:
<text x='116' y='7.6' font-size='6.1' fill='rgb(200,242,254)'>G
<tspan x='5'>r</tspan>
<tspan x='7'>o</tspan>
<tspan x='9'>w</tspan>
<tspan x='12'>w</tspan>
</text>

Esta reposio dos caracteres individuais ao longo do eixo x em relao ao "pai" do elemento <text>
usa para o valor de x, o atributo x do elemento <tspan>.

Como fazer ajustes com dx e dy

Ambos os elementos, <text> e <tspan> fornecem os atributos dx dy, que podem ser usados para
reposicionar um ou mais caracteres ao longo do eixo x e do eixo y. Isto permite que os efeitos
interessantes, tais como o que faz as palavras dobrarem para cima ou para baixo, ou mesmo fazer subir
uma escada. A imagem seguinte mostra algumas das propriedades mais de comumente usadas de texto
e seus efeitos:

Texto e formas em um caminho: <textPath> e <mpath>

Uma das caractersticas mais interessantes e teis de SVG a capacidade de usar caminhos para o
posicionamento de formas e texto. Como um exemplo, todos os cinco navegadores primrios agora
suportam efeitos de texto, tais como o mostrada na figura a seguir. Este exemplo demonstra como
colocar o texto ao longo de uma curva de Bzier.
<defs>
<path id="curve" d="M 10 100 C 200 30 300 250 350 50" />
</defs>
<text font-family="arial" font-size="16" fill="black">
<textPath xlink:href="#curve">Hello, here is some text lying along a Bzier curve.</textPath>
</text>

O caminho acima definido dentro de um elemento <defs>, que serve para definir o caminho, mas sem
renderiz-lo. Voc pode usar vrias bandeiras, como "StartOffset", para posicionar o texto ao longo do
caminho. O atributo "StartOffset" do elemento <textPath> permite que voc especifique a distncia em
pixels a partir do incio da curva onde o texto vai realmente comear. Quando animado com SMIL (ver
Captulo 4), este atributo faz com que o texto aparea se movendo ao longo da curva a uma velocidade
determinada pelo SMIL.

O elemento <tref>

Outro elemento til o <tref>, que permite a reutilizao de letras e pargrafos inteiros de texto. Voc
pode especificar a referncia para os dados de caracteres de um outro elemento <text> com o elemento
<tref>.

<defs>
<text id="ReferencedText">Dados e caracteres reutilizveis</text>
</defs>
<text font-family="arial" font-size="16" fill="black">
<tref xlink:href="#ReferencedText"/>
</text>

Trabalhando com Cores em SVG

Graas aos esforos de normalizao do W3C, h muitas semelhanas na forma como trabalhamos com
cores em HTML, CSS, SVG e, portanto, algumas das seguintes informaes podem j ser familiares
para voc.

Os valores de cor com nome

SVG suporta 147 cores, com nomes como "white" e "blue", e at mesmo "forestgreen", "tomate" e
"cornsilk". Isto torna mais fcil de lembrar cores especficas.

HSL

Provavelmente voc j ouviu falar da sigla HSL, que significa Matiz, Saturao e Luminosidade (ou
luminncia). Se voc j viu uma roda de cores circular em um programa de desenho, agora imagine isso.
Com esse quadro em mente, a maioria das pessoas pode entender o que HSL. Este mtodo de
especificar cores intuitivo, porque nossas mentes podem razoavelmente compreender rapidamente os
trs conceitos envolvidos:
Lightness (Luminncia): A Luminncia da cor varia de slido (opaco) a invisvel (transparente) (L = 0%
a 100%).
Saturation (Saturao): A saturao das cores variam do preto ao branco brilhante (S = 0 a 360).
Hue (Matiz): simplesmente define o grau ao longo do espectro de cores circular, com o crculo de
rolamento de vermelho (0 graus), para o verde (120 graus), azul (240 graus) (H = 0 a 360).

RGB

RGB (vermelho, verde, azul) provavelmente a abordagem mais comum para a especificao de cores
em SVG, principalmente porque HSL no era uma opo, at recentemente, e a maioria dos programas
de desenho e interfaces IDE usam RGB por padro. A vantagem de usar RGB sobre as cores nomeadas
a capacidade de ajustar rapidamente valores de cor incremental, o que seria difcil fazer com cores
nomeadas, sem uma memria incrvel ou tabela de referncia.
Valores RGB podem ser criados como valores funcionais entre 0 e 255, ou como percentagens, tal como
RGB (255, 0, 0) ou RGB (100%, 0, 0). O RGB tambm pode ser especificado em trs ou seis dgitos
hexadecimais, por exemplo, A2F # e # aa22ff, so iguais.

Criao de gradientes em SVG

No mundo dos grficos, um gradiente simplesmente se refere transio gradual, em alguma direo, de
uma cor para outra, ou de combinaes de tais transies envolvendo mltiplas cores. No sculo 19 o
artista Georges Seurat fez muito para popularizar o trabalho cientfico subjacente mostrando como as
cenas podem ser simuladas por colees de pontos de luz colorida. Os pontos de Seurat so numerosos e
seus tamanhos quase infinitesimal. Traduzido para o mundo das imagens de computador, porm,
implica em tamanhos de arquivos grandes.
Mas se decompor regies no em pontos monocromticos (um processo conhecido como posterization),
mas em regies de transio suave (nomeadamente gradientes), podemos transmitir menos dados e
ainda assim criar imagens realistas de alta qualidade. Empolgante, as instrues para criar gradientes
podem transmitir semntica bem como instrues de renderizao para o navegador, e isso que faz o
SVG passvel de indexao por motores de busca de uma forma que no pode ser facilmente aplicada a
formatos como GIF, JPEG ou PNG.
Se voc estiver interessado no tpico mais amplo de percepo visual e transmisso de informao, que
voc gostaria de ver alguns dos trabalhos de Marvin Minksy (veja
http://courses.media.mit.edu/2004spring/mas966/Minsky%201,974% 20Framework% 20for%
20knowledge.pdf ), ou os artigos em http://quantombone.blogspot.com/2010/08/alm-pixel-wise-
etiquetagem-blocos-world.html e http://srufaculty.sru.edu/david.dailey/engraver.htm em uma viso
mais moderna.

Aplicao de gradientes a um caminho

Vamos comear com o bsico aqui. Este exemplo mostra a definio de um gradiente linear e de um
gradiente radial, os quais so, em seguida, aplicados ao atributo de preenchimento de um caminho:
<path d="M 100 200 200 200 150 100 z" stroke="black" stroke-width="2" fill="url(#g)"/>

<linearGradient id="g">
<stop offset="0" stop-color="white"/>
<stop offset="1" stop-color="black"/>
</linearGradient>

<radialGradient id="g">
<stop offset="0" stop-color="white"/>
<stop offset="1" stop-color="black"/>
</radialGradient>

O gradiente aplicado ao atributo "fill" de um elemento utilizando um URL local: fill = "URL (#g)".
Isto demonstra que um objeto pode ter uma cor ou um gradiente como o seu preenchimento, mas no
ambos.

Note que no gradiente linear acima, dois elementos <stop> foram construdos. Isto significa que o
gradiente tem duas cores aplicadas a ele, uma para cada parada. Estas cores so determinadas pelo
atributo "stop-color". O atributo expresso em nmeros (entre 0 e 1) ou percentagens, e determina
onde o limite de gradiente colocado na direo estabelecida pelo gradiente, a qual definida pelos
atributos do elemento gradiente (X1, X2, Y1, Y2 para o gradiente linear, e CX, CY para o gradiente
radial).

Para o gradiente linear, no exemplo, o branco aplicada na parte mais esquerda do tringulo,
enquanto o preto aplicado parte mais direita. Tons de cinza gradualmente escurecem enquanto nos
movemos para a direita, com um valor de escala de cinza de 128/256, ou 50%, ocorrendo a meio
caminho da imagem, ou ao longo da linha onde x igual a 150.
Para o gradiente radial, o ponto mdio do retngulo delimitador escolhido como o centro. A partir
da, ns aplicamos a nossa primeira parada de cor (zero por cento do caminho em direo aos cantos
da caixa delimitadora). Preto ser aplicado aos quatro cantos do retngulo delimitador, com tons de
cinza fazendo a graduao entre o centro e as extremidades.

O nmero de paradas <stop> em um gradiente no precisa ser limitado a dois. No exemplo abaixo, so
quatro paradas definidas, com os valores de deslocamento especificados em porcentagens. Os retngulos
na figura a seguir tm 200 pixels de largura. Isso significa que o gradiente linear branco a 0 pixels,
preto em 50 pixels, branco em 150 pixels, e preto em 200 pixels.

<stop offset="0" stop-color="white"/>


<stop offset=".25" stop-color="black"/>
<stop offset=".75" stop-color="white"/>
<stop offset="1" stop-color="black"/>
O atributo stop-opacity

Alm de especificar a cor de um <stop> dentro de um gradiente, voc tambm pode especificar a sua
opacidade atravs de um atributo conhecido como "stop-opacity". Assim, voc pode fazer os gradientes
agirem como mscaras diferenciais, permitindo, por exemplo, uma imagem por baixo desvanecer-se
gradualmente. Aqui est um exemplo de como "stop-opacity" funciona:

<stop offset=".8" stop-color="black" stop-opacity="0.5"/>

"stop-opacity" (como a opacidade regular de objetos desenhados) toma valores entre 0 (transparente) e
1,0 (opaco). Aqui esto alguns exemplos do uso de "stop-opacity" com gradientes para permitir que
quantidades diferentes da que est por baixo seja visvel ao longo de um gradiente parcialmente
transparente.

Este exemplo mostra dois gradientes diferentes definidos e utilizados em imagens separadas. Ela cria um
gradiente tricolor por sobreposio de um sobre o outro. Observe o uso do atributo de transformar e
controlar a direo em que o gradiente aplicado. Aqui est o cdigo:

<linearGradient id="r" >


<stop offset="0" stop-color="red"/>
<stop offset="1" stop-color="green"/>
</linearGradient>

<linearGradient id="t" gradientTransform="rotate(90,.5,.5)">


<stop offset="0" stop-color="white" stop-opacity="0"/>
<stop offset="1" stop-color="#208" />
</linearGradient>
<rect x="10" y="10" width="100" height="100" fill="url(#r)" />
<rect x="120" y="10" width="100" height="100" fill="url(#t)" />
<rect x="60" y="120" height="100" width="100" fill="url(#r)"/>
<rect x="60" y="120" height="100" width="100" fill="url(#t)"/>

Este semelhante ao do exemplo anterior, mas utiliza mais do que duas cores no gradiente, bem como o
atributo "stop-opacity":

<linearGradient id="r" >


<stop offset="0" stop-color="red"/>
<stop offset=".5" stop-color="yellow"/>
<stop offset="1" stop-color="green"/>
</linearGradient>

<linearGradient id="t" gradientTransform="rotate(90,.5,.5)">


<stop offset="0" stop-color="#008" />
<stop offset=".4" stop-color="cyan" stop-opacity="0"/>
<stop offset=".6" stop-color="cyan" stop-opacity="0"/>
<stop offset="1" stop-color="#22a" />
</linearGradient>

<linearGradient id="s" gradientTransform="rotate(45,.5,.5)">


<stop offset="0" stop-color="#008" />
<stop offset=".45" stop-color="red" stop-opacity="0"/>
<stop offset=".55" stop-color="green" stop-opacity="0"/>
<stop offset="1" stop-color="#22a" />
</linearGradient>

<rect x="10" y="10" height="100" width="100" fill="url(#r)"/>


<rect x="120" y="10" height="100" width="100" fill="url(#t)"/>
<rect x="230" y="10" height="100" width="100" fill="url(#s)"/>
<rect x="120" y="120" height="100" width="100" fill="url(#r)"/>
<rect x="120" y="120" height="100" width="100" fill="url(#t)"/>
<rect x="120" y="120" height="100" width="100" fill="url(#s)"/>
Neste exemplo, um gradiente simples usado para conferir um brilho ligeiramente assimtrico que se
desvanece nos lados, para simular a aparncia de um cilindro rotativo:

<linearGradient id="cylinder" x1="0" y1="1" x2=".2" y2="0">


<stop offset=".1" stop-color="red"/>
<stop offset=".1" stop-color="white"/>
<stop offset=".2" stop-color="white"/>
<stop offset=".2" stop-color="blue"/>
<stop offset=".3" stop-color="blue"/>
<stop offset=".3" stop-color="white"/>
<stop offset=".4" stop-color="white"/>
<stop offset=".4" stop-color="red"/>
<stop offset=".5" stop-color="red"/>
<stop offset=".5" stop-color="white"/>
<stop offset=".6" stop-color="white"/>
<stop offset=".6" stop-color="blue"/>
<stop offset=".7" stop-color="blue"/>
<stop offset=".7" stop-color="white"/>
<stop offset=".8" stop-color="white"/>
<stop offset=".8" stop-color="red"/>
<stop offset=".9" stop-color="red"/>
<stop offset=".9" stop-color="white"/>
<stop offset="1" stop-color="white"/>
<stop offset="1" stop-color="blue"/>
</linearGradient>

<linearGradient id="gradient1">
<stop offset="0" stop-color="black"/>
<stop offset="0.3" stop-color="white" stop-opacity="0"/>
<stop offset="0.4" stop-color="white" stop-opacity=".8"/>
<stop offset="0.6" stop-color="white" stop-opacity=".0"/>
<stop offset="1" stop-color="black"/>
</linearGradient>

<rect x="10" y="10" height="250" width="55" fill="url(#cylinder)"/>


<rect x="10" y="10" height="250" width="55" fill="url(#gradient1)"/>
O exemplo a seguir mostra como voc pode criar a aparncia de tecelagem atravs de um nmero
de elementos SVG linearmente relacionado com o nmero de "threads". No caso do verde escuro e o
bronzeado, um gradiente aplicado com limites discretos entre opacidade e transparncia para dar a
iluso dele desaparecer atrs do outro. Aqui est o cdigo:

<stop offset=".20" stop-color="black"/>


<stop offset=".21" stop-color="#b83"/>
<stop offset=".29" stop-color="#b83"/>
<stop offset=".30" stop-color="black"/>
<stop offset=".30" stop-color="#b83" stop-opacity="0"/>
<stop offset=".40" stop-color="#b83" stop-opacity="0"/>
<stop offset=".40" stop-color="black"/>

Recorte e Mascaramento com SVG

Como o elemento <mask>, um pouco mais complexo (que discutiremos mais tarde), o elemento
<clipPath> d-lhe um jeito de definir uma coleo de formas que voc pode usar para esculpir uma
determinada figura em formas mais interessantes. Voc pode aplicar um <clipPath> para quaisquer
objetos desenhados em SVG, incluindo grupos de objetos, e o <clipPath> em si pode consistir de muitas
formas. Mscaras so muito parecidas com os <clipPath>, mas mais flexvel.
Alguns dos experimentos com gradientes pode sugerir que voc use o "stop-opacity" de um gradiente
para simular certos tipos de corte ou recorte. Em particular, vamos usar um gradiente radial para
restringir o aparecimento de um mapa de bits para uma regio retangular, elptica.
<radialGradient id="r" fy=".55" >
<stop offset=".3" stop-opacity="0"/>
<stop offset=".8" stop-color="black" />
<stop offset=".9" stop-color="white" />
<stop offset="1" stop-color="brown"/>
</radialGradient>

<image x="15%" width="30%" y="15%" height="30%"


xlink:href="fireenginefromWebsters1911.gif " />
<rect x="15%" y="15%" height="30%" width="30%" fill="url(#r)"/>

Este exemplo serve para ilustrar o poder dos gradientes, mas que deve ser razoavelmente simples de
concluir que o uso de gradientes lineares e radiais (os nicos tipos disponveis em SVG no presente)
para apresentar o recorte de uma imagem por baixo de uma forma arbitrria no fcil.
Voc pode usar o cdigo a seguir para produzir um efeito semelhante com a mesma facilidade, como a
imagem que se segue demonstra:

<clipPath id="CP">
<ellipse cx="29%" cy="26%" rx="10%" ry="8%"/>
</clipPath>
<image y="0" x="10%" width="40%" height="55%" xlink:href='p17.jpg' clip-path="url(#CP)"/>

Como mostra esse exemplo, voc pode colocar elementos, como gradientes, dentro de um <clipPath> e,
em seguida, aplicar o <clipPath> (atravs do seu id) para o objeto ou grupo de objetos a serem cortados.

A seguir, vamos ilustrar um exemplo que diferencia claramente entre o que voc pode realizar
com <clipPath> em oposio aos gradientes. No exemplo a seguir, inserimos em numerosas elipses
o <clipPath>, que mostra que as regies recortadas podem ser complexas.

<clipPath id="CP">
<ellipse cx="19%" cy="25%" rx="2.5%" ry="4%"/>
<ellipse cx="24%" cy="25%" rx="2.5%" ry="4%"/>
<ellipse cx="29%" cy="25%" rx="2.5%" ry="4%"/>
<ellipse cx="34%" cy="25%" rx="2.5%" ry="4%"/>
<ellipse cx="39%" cy="25%" rx="2.5%" ry="4%"/>
</clipPath>

<g clip-path="url(#CP)">
<image y="0" x="10%" width="40%" height="55%" xlink:href='p17.jpg' />
<rect y="0" x="15%" width="10%" height="55%" fill="purple" opacity=".6" />
<rect y="0" x="33%" width="10%" height="55%" fill="yellow" opacity=".8" />
</g>
Note-se que o contedo de um <clipPath> no pode envolver ambos os grupos (<g>) ou usos complexos
(<use>). Um <clipPath> est limitado a objetos e reutilizao de objetos de desenhos simples. Se
quisssemos reutilizar contedo, poderamos faz-lo atravs de um <mask>, como segue:

<mask id="CP">
<g id="U">
<ellipse cx="19%" cy="25%" rx="2.5%" ry="4%" fill="white"/>
<ellipse cx="24%" cy="25%" rx="2.5%" ry="4%" fill="white"/>
<ellipse cx="29%" cy="25%" rx="2.5%" ry="4%" fill="white"/>
<ellipse cx="34%" cy="25%" rx="2.5%" ry="4%" fill="white"/>
<ellipse cx="39%" cy="25%" rx="2.5%" ry="4%" fill="white"/>
</g>
<use xlink:href="#U" transform="translate(0,40)" />
<use xlink:href="#U" transform="translate(0,80)" />
</mask>
<g mask="url(#CP)">
<image y="0" x="10%" width="40%" height="55%" xlink:href='p17.jpg' />
<rect y="0" x="15%" width="10%" height="55%" fill="purple" opacity=".6" />
<rect y="0" x="33%" width="10%" height="55%" fill="yellow" opacity=".8" />
</g>

Enquanto um <clipPath> declara que o contedo est ou dentro dela (e, portanto, visvel) ou fora dela
(e consequentemente, invisvel), uma mscara permite graus de visibilidade varivel, dependendo da
luminosidade dos objetos no interior da mscara.

<defs>
<clipPath id="clipRays">
<rect x="5" y="80" width="100" height="100"/>
<circle cx="170" cy="100" r="50"/>
<polygon points="300 30 350 130 250 130" />
<ellipse cx="425" cy="100" rx="50" ry="40"/>
<rect x="494" y="80" width="100" height="100"/>
</clipPath>

<mask id="maskRays">
<rect x="5" y="80" width="100" height="100" fill="red" />
<circle cx="170" cy="100" r="50" fill="purple" />
<polygon points="300 30 350 130 250 130" fill="white" />
<ellipse cx="425" cy="100" rx="50" ry="40" fill="black" />
<rect x="494" y="80" width="100" height="100" fill="orange" /> </mask>
<g id="rays">
<g id="RaysRight">
<path d="M300,13.51c548.1,268.4,548.1,268.4,548.1,268.4s23.52-35.35,23.52-
35.35-571.7-233-571.7-233" fill="red"/>
<path d="M300,13.31c452.8,307.3,452.8,307.3,452.8,307.3s26.29-29.41,26.29-
29.41-479.1-277.8-479.1-277.8" fill="green"/>
<path d="M300,13.14c365.4,342.9,365.4,342.9,365.4,342.9s28.82-23.98,28.82-
23.98-394.2-318.9-394.2-318.9" fill="blue"/>
<path d="M300,12.97c282.9,376.5,282.9,376.5,282.9,376.5s31.22-18.84,31.22-
18.84-314-357.7-314-357.7" fill="lime"/>
<path d="M300,12.81c203.7,408.8,203.7,408.8,203.7,408.8s33.51-13.91,33.51-
13.91-237.2-394.9-237.2-394.9" fill="purple"/>
<path d="M300,12.66c127.1,440,127.1,440,127.1,440s35.73-9.153,35.73-9.153-
162.9-430.9-162.9-430.9" fill="orange"/>
<path d="M300,12.51c52.68,470.4,52.68,470.4,52.68,470.4s37.89-4.522,37.89-
4.522-90.57-465.8-90.57-465.8" fill="yellow"/>
</g>
<use id="RaysLeft" xlink:href="#RaysRight" transform="translate(600) scale(-1, 1)" />
</g>
</defs>
<!-- Light Ray 1 -->
<use xlink:href="#rays" x="0" y="0" clip-path="url(#clipRays)"/>
<!-- Light Ray 2 -->
<use xlink:href="#rays" x="0" y="0" transform="scale(1 -1) translate(0 -380)" mask="url(#maskRays)"/>

Como voc pode ver, ambos <clipPath> e <mask> podem ter uma variedade de formas. O exemplo
acima mostra como os <clipPath> se comportam como recortadores da imagem, enquanto as mscaras
se comportam mais como filtros de luz.

Note-se que as formas preenchidas na parte inferior da imagem anterior, que tm uma mscara aplicada
para elas, filtram mais cores do que os retngulos superiores. A cor filtrada definida pela cor de
preenchimento das formas que so usadas no interior da mscara. Quando a cor branca usada na
mscara, como no tringulo na parte inferior da imagem, nenhuma cor filtrada. Quando a cor preta
utilizada na mscara, como na elipse invisvel na parte inferior, todas as cores so filtradas, e nenhuma
cor do grfico que foi mascarado exibida no vdeo.

Observao: Voc pode recortar um <clipPath> somente definindo a regra de preenchimento (fill-rule)
para EvenOdd no objeto de recorte, ou utilizando as mscaras.
Aqui est mais uma ilustrao da diferena entre os <clipPaths> e <mask>:

<linearGradient id="gradient1" >


<stop offset="0.0" stop-color="black"/>
<stop offset="1" stop-color="white"/>
</linearGradient>
<mask id="Ma">
<rect x="300" y="300" width="400" height="100" fill="url(#gradient1)"/>
</mask>
<text x="220" y="365" font-family="impact" font-size="52" mask="url(#Ma)" fill="black">
The Masked Text: it o
</text>

Detalhes de transformaes

A linguagem SVG fornece alguns mtodos teis para reposicionar objetos individuais ou grupos inteiros
de objetos atravs destes simples comandos <transform>: translate, scale, rotate, skewX, and skewY.

O Comando "translate"

Um dos comandos de transformao mais teis "translate", o que lhe permite reposicionar contedo
simplesmente especificando as novas coordenadas (x,y) neste formato:
transform = "translate (50,10)".
Este comando simples ir deslocar objetos grficos 50 unidades ao longo do eixo-X e 10 unidades ao
longo do eixo-Y. Isso efetivamente estabelece um novo sistema de coordenadas para o objeto ou grupo
ao qual a transformao aplicada, e muitas vezes este faz com que seja simples de aplicar outras
transformaes, tais como a inclinao, rotao e dimensionamento.

O Comando "Scale"

A sintaxe para o comando "scale" parece com isso: transform = "scale (2)".
O comando "scale" redimensiona os elementos grficos e aplicado tendo como referncia a origem do
sistema de coordenadas (0,0). Isto significa que, quando o tamanho de uma forma que tem valores de x
e y positivos est dobrada, a canto superior esquerdo, bem como o resto do grfico expandido
horizontalmente ao longo do eixo-X e verticalmente ao longo do eixo-Y. H maneiras de centralizar o
grfico antes de aplicar o comando "scale", como voc ver exemplos mais tarde.
O exemplo seguinte mostra os efeitos dos comandos "Scale" e "Translate":
Note que a ordem em que os comandos de transformao so aplicados afetam o resultado final. Por
exemplo, se voc usar o comando "translate" antes de aplicar o "scale", o resultado ser geralmente
bastante diferente da sua aplicao na ordem oposta, porque a origem do sistema de coordenadas muitas
vezes no centrada no grfico j transformado. Em muitos dos casos, mais fcil aplicar primeiro o
comando "translate" para centrar o grfico na origem, e depois aplicar outras transformaes.

Desviando: Os comandos skewX e skewY

Usando os comandos "skewX" e "skewY", voc pode distorcer formas horizontalmente ou


verticalmente. Por exemplo, o comando <transform = "skewX (25)"> vai puxar os grficos 25 unidades
ao longo do eixo horizontal relativamente origem ou canto superior esquerdo do grfico, que produz
um efeito distorcido.

O comando rotate

Voc pode girar imagens de vetor e bitmaps usando o comando de rotao (rotate). O seguinte
comando "rotate" ir girar um objeto 50 graus no sentido horrio padro:
transform = "rotate (50)".
importante notar que o comando "rotate" na verdade, leva at trs parmetros: degrees, cx,
e cy Onde cx e cy (por padro, o ponto [0,0]) so o centro sobre o qual a rotao vai acontecer.

Exemplo de Transformaes SVG: Passo a passo

Todos os comandos de transformao podem ser usados em combinao com a opacidade e outros
efeitos de estilo. Por exemplo, voc pode reutilizar uma forma ou imagem via elemento <use>,
redimension-la usando o comando "scale", e, em seguida, reposicion-la para exibir abaixo a imagem
original. Adicionando o comando "skewX" e fazendo o grfico ligeiramente opaco resulta em uma
reflexo. O exerccio seguinte mostra como fazer isso:
1. Desenhando as formas SVG que voc deseja trabalhar:

<line id="water" x1="-50" y1="110" x2="100%" y2="110" stroke="blue" stroke-width="1" stroke-opacity="0.7" />
<g id="scene">
<circle id="sun" r="50" cx="30" cy="30" fill="orange" stroke="grey" stroke-width="1" />
<circle id="venusInTransit" r="5" cx="15" cy="20" fill="black" stroke="grey" stroke-width="1" />
</g>

2. Adicione outro grupo (um elemento <use>) dentro do grupo atual, e adicione os comandos de
transformao (transform) "skewX", "skewY" e "scale" para o novo grupo.
<use xlink:href="#scene" mask="url(#hazeIca)" transform="scale(1 -1) translate(30 -210) skewX(-20) skewY(5)"/>

A imagem seguinte mostra o resultado:

Como voc pode ver, isso gira o grfico ao longo do eixo-x e, em seguida, tambm ao longo do eixo-y.
O comando "translate", em seguida, reposiciona o objeto de volta para o local correto no sistema de
coordenadas de modo que a imagem apresentada abaixo a imagem original.

O Comando Matrix

O comando "matrix" (matriz) mais complexo e requer mais energia mental para se fazer uso, mas
permite um meio mais conciso e eficiente de especificar transformaes precisas em um objeto. O
formato deste comando provavelmente ir lembr-lo das aulas de Matemtica. O comando tem a matriz
de formato (a, b, c, d, e, f ), que especifica uma matriz de transformao matemtica que se parece com
isso: [abcdef ]. Este comando usado principalmente por programas de edio de SVG que usam
funes matemticas para controlar e aplicar as transformaes.
A melhor maneira de entender como isso funciona observar os efeitos dos comandos em um editor
tais como o Inkscape. Voc pode encontrar mais detalhes sobre esse comando na especificao SVG, em
http: // www.w3.org / TR / SVG / coords.html # TransformMatrixDefined.
Adicionando estilo usando CSS

Nos captulos anteriores, voc viu como adicionar estilo usando os atributos SVG de apresentao para
modificar muitas das propriedades de forma, texto, e bitmap.

Assim como em HTML, ambos, classes e atributos de estilo, tambm podem ser usados para adicionar
estilo em SVG. Contudo, h muitas vantagens em usar a classe em vez de atributo de estilo, porque o
atributo de classe pode assumir valores a partir de uma folha de estilo que, na prtica requer menos
alteraes no DOM.
A maioria dos atributos de apresentao SVG esto disponveis para ns em folhas de estilo CSS. Por
exemplo, um retngulo com atributos de preenchimento de cor (fill) e opacidade de trao (stroke-
opacity) podem ser definidos em CSS. Usar uma folha de estilo em SVG muito semelhante a
utilizao em HTML5. Voc pode definir regras CSS in-line usando o elemento <style>. Neste prximo
exemplo, vrios tipos de seletores CSS so usados para segmentar barras especficas de um grfico de
barras.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= http://www.w3.org/1999/xlink height="170"


width="450">
<style type="text/css">
svg {
font: 12px sans-serif;
shape-rendering: crispEdges;
}
text {
fill:white;
text-anchor:end;
font-weight:bold;
}
g.bar rect {
fill: green;
}
g > #LookAtMe {
fill: steelblue;
}
rect#LookAtMe {
fill: steelblue;
}
rect.custom {
fill: orange;}
</style>
<g transform="translate(0, 4.5)" class="bar">
<rect height="18" width="145.8" fill="papayawhip"></rect>
<text text-anchor="end" fill="white" dy=".35em" dx="-6" y="9" x="145.8">39</text>
<text text-anchor="end" dy=".35em" dx="-6" y="9" x="0">A</text>
</g>
<g transform="translate(0, 27)" class="bar">
<rect height="18" width="31.5" style="fill:blue"/>
<text text-anchor="end" fill="white" dy=".35em" dx="-6" y="9" x="31.5">12</text>
<text text-anchor="end" dy=".35em" dx="-6" y="9" x="0">B</text>
</g>
<g transform="translate(0, 49.6)" class="bar">
<rect id="LookAtMe" height="18" width="91.3" fill="steelblue"/>
<text text-anchor="end" fill="white" dy=".35em" dx="-6" y="9" x="91.3">26</text>
<text text-anchor="end" dy=".35em" dx="-6" y="9" x="0">C</text>
</g>
<g transform="translate(0, 72)" class="bar">
<rect class="custom" height="18" width="211.4" fill="steelblue"/>
<text text-anchor="end" fill="white" dy=".35em" dx="-6" y="9" x="211.4">54</text>
<text text-anchor="end" dy=".35em" dx="-6" y="9" x="0">D</text>
</g>

Uma coisa importante notar aqui como os estilos de folhas de estilo CSS substituem o atributo de
preenchimento do primeiro retngulo. Alm disso, observe como o atributo de estilo no segundo
retngulo substitui a regra de preenchimento na folha de estilo CSS.
Alternativamente, folhas de estilo podem ser linkadas a um arquivo CSS externo, assim como acontece
em HTML5. A principal diferena do HTML a sintaxe XML mais rigorosas que necessria para
documentos SVG:
<?xml-stylesheet href="bookStyles.css" type="text/css"?>

Usando "media queries" para melhorar a usabilidade

H muitos exemplos do uso de consultas de mdia (Media Querie) CSS3 (veja


http://www.w3.org/TR/css3-mediaqueries/) para melhorar a usabilidade do contedo HTML5. O SVG
pode aproveitar essa mesma capacidade. Uma das prticas mais comuns ajustar automaticamente a
disposio com base no tipo de dispositivo ou a resoluo da tela que o usurio final est usando. Neste
exemplo, as alteraes de layout de pgina web so feitas para tentar ajustar os elementos mais
importantes ao tamanho da pgina.

Por exemplo, usando o seguinte cdigo de consulta de mdia CSS, uma srie de alteraes no
documento ocorrer automaticamente, dependendo da resoluo da tela do usurio final:

@media screen and (max-width: 351px) {


#pageContent {
opacity: 0.3;
}
#backgroundGradient, #backgroundGridWithPattern {
display: none;
}
#svgLogo01 {
display: none;
}
}
Ou seja, quando a largura da tela do dispositivo do usurio final for inferior a 351 pixels, acontece o
seguinte:
O grfico grande logotipo escondido.
O gradiente de fundo e grade ficam ocultos.
A opacidade do fundo ajustada para 0,3.

Capacidades adicionais do CSS3

A linguagem CSS3 mais recente oferece vrios novos recursos que podem ser usados com SVG,
incluindo transformaes 2D e efeitos de transio. Voc pode encontrar mais informaes sobre isso no
site Saiba SVG, em http://learnsvg.com/CSS3/. Os grupos de trabalho CSS e SVG tm trabalhado na
consolidao das duas abordagens. Entre as caractersticas previstas de CSS3 so as habilidades para lidar
com filtros SVG, animao, gradientes, e transformaes atravs do CSS.

Vector Graphics, Smbolos, e Bibliotecas de botes

Talvez, porque o formato SVG um formato aberto, em oposio a um proprietrio (por exemplo,
Flash), muitos projetos de esprito pblico como a "Wikipedia" e "Inkscape" tenham tomado um gosto
a ele. Da mesma forma, muitos dos usurios da Wikipedia e Inkscape tm levado a redistribuir seu
trabalho artstico de uma forma que so abertamente licenciados para reuso. Mais e mais bibliotecas
grficas e sites de desenvolvedores esto usando a licena "Creative Commons Public Domain", que d
aos usurios finais direitos completos para reutilizar "...o trabalho, at com fins comerciais, sem pedir
permisso."Os detalhes desta licena pode ser encontrada em
http://creativecommons.org/publicdomain/zero/1.0/.

O grupo de usurios Inkscape, juntamente com outros, contribuiu com muitos bons exemplos para o
"Open Clip Library", em http://openclipart.org/Wikimedia~~number=pluralCommons . Sob os
auspcios da "Wikimedia Foundation" (que supervisiona Wikipedia), "Wikimedia Commons" uma
coleo de material, frequentemente usado pelos autores na Wikipedia, que acredita-se ser reutilizvel,
ou por causa de estar no domnio pblico (sem copyright restantes) ou por causa de acordos de
licenciamento abertos (como Creative Commons).

A pgina Wikimedia Commons principal pode ser visitado em http://commons.wikimedia.org/wiki/


Pgina principal. No entanto, para procurar apenas imagens SVG na Wikimedia, voc pode ir para
http://commons.wikimedia.org/wiki/Categoria: SVG (que categoriza grande parte do contedo SVG
l), ou para o IAN Biblioteca de smbolos (http://ian.umces.edu/symbols/) ou o Projeto do substantivo
(http://thenounproject.com/).

Acessibilidade

Ao contrrio de muitos outros formatos de imagem, e mais visivelmente, os formatos bitmap usados na
web, tais como JPEG, GIF e PNG, o SVG intrinsecamente acessvel aos leitores de tela, pois XML e
composto por ASCII e Unicode. No entanto, a sua capacidade de ir mais longe do que isso vasta. Um
autor que preocupado com acessibilidade (como todos ns deveramos ser) pode anotar cada elemento
desenhado com seus prprios descritores, o que significa que, em teoria, ambos os leitores de tela e
motores de busca poderiam separar as vrias partes de uma composio visual e traduzir estes elementos,
bem como das suas relaes geomtricas significando que os dados poderiam ser usados como parte de
uma consulta, representado em informao ttil, ou extrado numa variedade de formas teis.

Embora a anlise semntica de uma imagem de bitmap requeira inteligncia artificial do dispositivo de
processamento, para SVG, ele s requer um acordo entre os autores e os fabricantes de navegadores para
que essa acessibilidade acontea. At agora, o Grupo de Trabalho SVG e o Grupo de Interesse SVG tm
dado muita ateno ao tpico, e acredita-se que a promessa SVG para a acessibilidade muito forte.

Elementos semnticos e caractersticas

A maioria dos leitores vai estar ciente de elementos HTML5, ento isso provavelmente um bom lugar
para comear. Em HTML5, vrios novos elementos semnticos importantes foram adicionados,
incluindo <nav>, <section>, <article>, <aside>, <header>, <footer>, e at mesmo <adress>. A forma
como se desenrola em semntica HTML5 que estes novos elementos tm significados definidos. Por
exemplo, o elemento <section> projetado para manter elementos de seccionamento para que os
navegadores modernos sejam capazes de perceber a hierarquia dentro de sees e subsees em uma
pginas web, quando buscarem informaes.

O projeto semntico melhorado faz com que o trabalho dos desenvolvedores e at mesmo programas de
IDE de desenvolvimento web sejam muito mais fceis, porque toda a lgica da semntica construda
dentro da linguagem e dos navegadores (browsers).
Como um exemplo baseado na web, a demo Notepad Semntica no site do Internet Explorer Test Drive
(http://ie.microsoft.com/testdrive/html5/semanticnotepad/default.html) mostra quo til so as novas
tags de HTML5 com relao semntica, ou cdigo que projetado para ser consciente de sua prpria
estrutura.
Em SVG, a semntica funciona da mesma maneira, mas os elementos SVG tm um jeito diferente de
construir significados. Por exemplo, para alm dos elementos de forma, voc pode usar metadados e
elementos de microdados como ttulo, desc (descrio), RDF, atributos de microdados e dados.

Observao Voc pode encontrar mais detalhes sobre metadados na especificao SVG 1.1 aqui:
http://www.w3.org/TR/SVG/metadata.html.

Uma distino importante entre a acessibilidade em SVG e HTML que o domnio fundamental da
semntica do HTML um texto, enquanto que a do SVG so grficos. No entanto, ambos tm, at
agora, a maior parte da sua acessibilidade no domnio textual. O que significa que, por exemplo, para
um retngulo vermelho ser lido em outras modalidades sensoriais que no a visual intrigante, embora
forma e geometria, que so um grande foco do SVG, claramente tenham dimenses tteis, bem como,
possam ser transfigurado com relativa facilidade (em teoria) em uma modalidade, como o Braille, de
maneira que se estendam a todo conceito de acessibilidade. Texto (a letra "T" em HTML)
historicamente com base numa forma auditiva (a fala), assim o pensamento das pessoas sobre o que
significa a acessibilidade no ambiente grfico ainda bastante incipiente.

Os recursos a seguir tm mais informaes sobre os temas de SVG e acessibilidade:


Recursos de acessibilidade do W3C SVG: (http://www.w3.org/TR/SVG-access/)

SVG Guia de Contedo Acessibilidade (2010)


(http://www.w3.org/TR/SVG/access.html#SVG~~number=pluralAccessibilityGuidelines)

W3C Recommendation: The <title> and <desc> elements (2008) (http://www.w3.org/TR/


SVGTiny12/struct.html#TitleAndDescriptionElements)

SVG Interest Group (http://www.w3.org/Graphics/SVG/IG/wiki/Accessibility_Activity)

Estudo de caso: uma interface web SVG simples

Neste ltimo exemplo, voc vai puxar tudo que voc aprendeu at agora juntos em uma simples mas
poderosa interface web SVG que pode ser usada por dispositivos minsculos, por dispositivos mveis, e
em navegadores de desktop.

1. Crie um retngulo com cantos arredondados, que servir como uma rea de fundo para conter todos
os outros grficos. Defina a altura e a largura do retngulo para valores percentuais, de modo que o
fundo redimensione conforme a tela do usurio expande ou se contrai.

2. Em seguida, adicione uma referncia para o logotipo oficial SVG usando o elemento <image>. Voc
pode encontrar o logo SVG aqui: http://www.w3.org/2009/08/svg-logos.html. Alm disso, adicione
uma referncia a uma imagem bitmap e defina suas posies x e y de modo que ela seja centrada
horizontal e verticalmente no meio da tela, mesmo quando o navegador redimensionado.

3. Em seguida, adicionar o texto que est centrado na horizontal, mas abaixo das duas imagens. Seu
SVG deve estar agora semelhante seguinte imagem:

<!-- Camada de contedo -->


<g id="layer3">
<!-- Adiciona background para o contedo primrio -->
<rect id="pageContent" width="90%" height="85%" x="5%" y="5%" opacity="0.9" rx="50"
ry="50" stroke="gray" stroke-width='0.25' fill='#333' fill-opacity="0.5"/>
<!-- Referncia ao logo oficial SVG -->
<image id="svgLogo01" width="150px" height="150px" x="70px" y="50px" xlink:href="svg-logo-v.svg"
alt="SVG Logo" />
<!-- Referncia a imagem bitmap (PNG) -->
<image id="bitmapCentralBall" width="25%" height="25%" x="38%" y="37.5%" xlink:href="iris-
small.png" alt="NASA Photo of Jupiter" />
<g id="textForTargettedDevices">
<text id="textTiny" x="50%" y="80%" fill="black" font-family="tahoma, serif " text-
anchor="middle">Text for tiny devices.</text>
</g></g>

4. Para apimentar a interface do usurio, adicione o padro de background criado no captulo anterior.
Em cima disso, adicione um gradiente linear alinhado de cima para baixo, como mostrado aqui:

5. Em seguida, adicione uma outra referncia ao logotipo SVG e posicione-a em direo ao canto
superior direito da pgina. Tambm adicione mais dois elementos <text> e d a cada um deles uma
identificao nica de modo que o cdigo se parece com o seguinte.

<text id="textBasic" display="none" x="50%" y="80%" fill="orange" font-family="Tahoma, serif " text-
anchor="middle">Text for larger mobile devices.</text>
<text id="TextDesktop" display="none" x="50%" y="80%" fill="orange" font-family="Tahoma, serif " text-
anchor="middle">Text for desktops and wide display devices.</text>

6. Por fim, adicione lgica para as consultas de mdia (media queries) na folha de estilo para que o
layout e a exibio dos elementos da pgina mudem de acordo com o tamanho da tela do usurio final.

<style type="text/css">
@media screen and (min-width: 551px) {
#svgLogo02 {
display: inline;
}
#textDesktop {
display: inline;
}
}
@media screen and (max-width: 550px) and (min-width: 351px) {
#textBasic {
display: inline;
}
}
@media screen and (max-width: 351px) {
#pageContent {
opacity: 0.3;
}
#backgroundGradient, #backgroundGridWithPattern {
display: none;
}
}
@media screen and (max-width: 350px) and (min-width: 211px) {
#textTiny {
display: inline;
}
/* Ainda no suportado #textTiny:before {content: "texto dinmico inserido aqui...";}
*/
}
@media screen and (max-width: 211px) {
#svgLogo01 {
display: none;
}
}
</style>

Voc acabou de criar um slido incio de uma interface de aplicativo da web usando o poder do SVG e
CSS para apoiar uma variedade de dispositivos de usurio final e tamanhos de tela. Este exemplo
demonstra como pode ser CSS utilizado para controlar o contedo do grfico SVG com base em vrios
parmetros, tais como a largura e altura da rea de visualizao. O CSS pode ser muito til para
controlar o estilo e contedo das impresses tambm. Se voc chegou at aqui, bom trabalho!
Captulo 4

Movimento e interatividade

Embora o SVG possa ser um formato de imagem esttica, adequado para ilustraes, ele foi projetado
desde o seu incio para ser interativo e dinmico. Existem duas abordagens muito importantes e
radicalmente diferentes para este dinamismo: animao declarativa e scripting. Este captulo apresenta o
primeiro modelo de animao declarativa que usada por SVG, e depois introduz o scripting.
O Scripting ser mais fcil para aqueles leitores que j tm alguma experincia de programao;
Portanto, o tratamento aqui prossegue suavemente. No entanto, para tirar o mximo proveito de
scripting SVG, voc vai precisar de algum conhecimento de programao web bsico.

Animao declarativa com SVG

Animao SVG, como frequentemente chamada, refere-se s construes declarativas emprestadas de


outro padro W3C: Sincronized Multimedia Integration Language (SMIL). Basicamente, o princpio
traz animao declarativa (como acontece com os conceitos de programao declarativa) onde o
autor diz ao dispositivo de visualizao (tela de computador, impressora, telefone celular, etc.) como o
resultado final deve ser, e deixa os detalhes de implementao para o software cliente. Por exemplo, um
programador ou desenvolvedor pode descrever algo como um crculo e, em seguida, deixar o dispositivo
implement-lo com o melhor de sua capacidade. Antes de entrar nos aspectos prticos deste tpico,
precisamos explicar vrias noes importantes:

Por animao declarativa, queremos dizer animao realizada utilizando marcaes em vez de
script

O termo SMIL evoca significados diferentes para pblicos diferentes. Alguns usam-no para se referir ao
subconjunto de SMIL incorporado e, em seguida, expandido dentro do SVG. Outros usam para se
referir ao contexto muito mais amplo de SMIL dentro do grupo de trabalho SMIL do W3C. O ltimo
o mais correto, embora a ambiguidade por vezes leve a disputas nas discusses sobre a utilizao de
SMIL dentro de outros padres W3C. O termo "animao SVG" mais freqentemente usado hoje em
dia para referir-se a "animao declarativa em SVG"; No entanto, SVG/SMIL pode ser um termo
melhor para se referir a isto, porque o SVG tambm permite a manipulao atravs de CSS, e existe o
interesse de vrios grupos em trazer pelo menos um subconjunto do poder do SVG/SMIL para o CSS
para tambm poder ser aproveitado pelo HTML.

Todos os principais navegadores, exceto o Internet Explorer, implementaram animao declarativa em


SVG. Um bom nmero de implementaes em telefones celulares tambm oferecem suporte para
animao SVG e algumas delas no suportam JavaScript, deixando a animao SVG como o nico
caminho para os desenvolvedores executarem animaes nessas plataformas.

Para trabalhar com o seguinte material, voc precisar de um navegador que trate-o bem. Opera e o
Plug-in ASV para o Internet Explorer so as melhores implementaes para a animao SVG, seguidos
pelo Firefox 4 (ou superior). O Chrome ligeiramente frente do Safari no momento da redao deste
texto. Voc pode facilmente descobrir se o seu navegador (browser) suporta SVG. Verifique se o seguinte
exemplo trabalha no seu browser. Este exemplo adiciona uma elipse contendo dois elementos-filhos
<animate> para o modelo padro SVG:
<svg xmlns=" http://www.w3.org/2000/svg" xmlns:xlink= http://www.w3.org/1999/xlink width="100%"
height="100%">
<ellipse id="E" cx="90" cy="90" rx="30" ry="40" fill="#448">
<animate attributeName="rx" dur="5s" values="20;90;20" repeatCount="indefinite"/>
<animate attributeName="ry" dur="5s" values="30;60;30" repeatCount="indefinite"/>
</ellipse>
</svg>

Alternativamente, voc pode apontar seu navegador para o mesmo exemplo aqui: http://faculty.sru.edu/
david.dailey/SVG/animoval0.svg. O navegador deve exibir uma elipse oscilante, o tamanho dos quais
muda periodicamente (com uma proporo que muda tambm) ao longo de cinco segundos de
intervalo.

Nota: Se o exemplo anterior no funcionar para voc, mude o navegador e continue experimentando
com esta seo at encontrar um que funcione.

As idiossincrasias de suporte ao navegador so uma questo de tempo, porque Safari, Chrome, Firefox e
os demais comearam seu apoio ao SMIL muito recentemente. As melhorias no ano passado foram
dramticas.

Quase todos os atributos de objetos SVG podem ser animados com a animao declarativa. Isto implica
que a animao estende-se de forma muito ampla atravs da tecnologia de maneiras que voc nem
sempre consegue pensar. Verifique http://srufaculty.sru.edu/david.dailey/svg/#SMIL e
http://srufaculty.sru.edu/david.dailey/SVG/Newstuff/Newlist.htm para uma variedade de ilustraes.

Nem todas as animaes podem ser feitas de forma declarativa (pelo menos no ainda) em SVG. A
forma de Script ainda muito mais poderosa para criar efeitos complexos. Mais tarde, no captulo, voc
ver alguns exemplos que no podem ser criados usando os mtodos de animao declarativas sozinho.

A animao declarativa fcil de usar e aparece (com base em vrios anos de evidncias anedticas) para
reduzir consideravelmente o tempo de desenvolvimento.

Comeando

Vamos comear mais uma vez com o exemplo descrito brevemente acima (e visvel em
http://granite.sru.edu/~ddailey/SVG/animoval2.svg):

<ellipse id="E" cx="90" cy="90" rx="30" ry="40" fill="#448">


<animate attributeName="rx" dur="5s" values="20;90;20" repeatCount="indefinite"/>
<animate attributeName="ry" dur="5s" values="30;60;30" repeatCount="indefinite"/>
</ellipse>

Dentro da elipse h dois elementos <animate>. Um controla a largura, e o outro controla a altura da
elipse durante a animao. Os atributos neste exemplo controla o seguinte:

eamNubtir : seleciona qual atributo do objeto ser animado.


ur D : determina quanto tempo a animao vai durar (por padro especificado em segundos).
uesla V : lista delimitada por ponto e vrgula de valores de atributo. So muitas vezes numrico, mas
no precisam ser. Neste caso, h trs valores, e os valores inicial e final so os mesmos. Isto significa que
a animao ir iniciar e parar com o mesmo valor.
tunCoeapR : Um valor "idefinite" a escolha correta para animaes que faro um loop contnuo.
Alternativamente, voc pode colocar um nmero inteiro positivo especificando o nmero de vezes
que a animao tem de repetir.

O grfico a seguir mostra a animao em vrios momentos: quando t prximo de 0, quando t igual a
1,25 e quando t igual a 2,5.

S para expor um pouco mais de conceitos bsicos, aqui est outro exemplo que duplica a elipse a partir
de cima e desloca a sua posio um pouco. Em seguida, ele varia o atributo de valores da segunda elipse
para que, enquanto uma elipse se expande a outra se contraia. Ele tambm adiciona um retngulo (com
cantos arredondados) e aplica uma certa transparncia para maior divertimento. Voc pode ver este
exemplo em http://granito.sru.edu/~ddailey/SVG/animoval1.svg:

<rect x="100" y="85" rx="12" height="30" width="150" fill="purple" stroke="black" stroke-width="3"/>

<ellipse cx="100" cy="100" rx="30" ry="40" fill="#448" opacity=".75"stroke="black" stroke-width="3">


<animate attributeName="rx" type="rotate" dur="5s" values="10;70;10" repeatCount="indefinite"/>
<animate attributeName="ry" type="rotate" dur="5s" values="30;60;30" repeatCount="indefinite"/>
</ellipse>

<ellipse cx="250" cy="100" rx="30" ry="40" fill="#448" opacity=".75" stroke="black" stroke-width="3">


<animate attributeName="rx" type="rotate" dur="5s" values="70;10;70" repeatCount="indefinite"/>
<animate attributeName="ry" type="rotate" dur="5s" values="60;30;60" repeatCount="indefinite"/>
</ellipse>
Nos dois exemplos anteriores, o momento associado com os atributos foi ajustado para cinco segundos.
No prximo exemplo (visvel no http://granite.sru.edu/~ddailey/svg/animoval2.svg), voc vai explorar o
que acontece quando voc variar o intervalo para diferentes atributos. Aqui est o cdigo:

<rect x="100" y="85" rx="12" height="30" width="150" fill="purple" stroke="black" stroke-width="3" >
<animate attributeName="width" dur="3s" values="150;100;150" repeatCount="indefinite"/>
</rect>

<ellipse id="E" cx="100" cy="100" rx="30" ry="40" fill="#448" opacity=".75" stroke="black" stroke-width="6"
stroke-dasharray="8,4">
<animate attributeName="rx" dur="3s" values="10;70;10" repeatCount="indefinite"/>
<animate attributeName="ry" dur="5s" values="30;60;30" repeatCount="indefinite"/>
</ellipse>

<ellipse cx="250" cy="100" rx="30" ry="40" fill="#448" opacity=".75" stroke="black" stroke-width="6" stroke-
dasharray="8,4">
<animate attributeName="rx" dur="5s" values="70;10;70" repeatCount="indefinite"/>
<animate attributeName="ry" dur="3s" values="60;30;60" repeatCount="indefinite"/>
<animate attributeName="cx" dur="3s" values="250;200;250" repeatCount="indefinite"/>
</ellipse>

Este exemplo adiciona um atributo de "stroke-dasharray" para as elipses e permite que a posio do
centro da segunda elipse e a largura do retngulo variem (em sincronia um com o outro). Isto
demonstra que dessincronizao e sincronizao podem produzir efeitos muito fascinantes. Embora este
exemplo parea rodar o objeto, isto , simplesmente porque a circunferncia da elipse vai mudando
(em rx e ry). Alm disso, como as matrizes de trao so alocados em termos de unidades absolutas
(larguras de pixel), o nmero de segmentos de traos necessrios para cobrir a elipse tambm varia.

Voc tambm pode experimentar a iluso de rotao animando o atributo "dash-offset". O exemplo em
http://granite.sru.edu/~ddailey/svg/animoval3.svg apresenta o que parece duas engrenagens girando em
direces opostas.

Acontece que h uma maneira melhor de rodar objetos do que animando o "stroke-dasharray". Voc
pode usar o elemento <animateTransform> para alterar a escala, posio, ou a rotao de um objeto.
Observe esta extenso elegante do exemplo anterior, no qual o <animateTransform> usado. Voc pode
v-lo em http://granite.sru.edu/~ddailey/svg/animoval4.svg, mas aqui voc vai examinar um caso mais
simples (http://granite.sru.edu/~ddailey/SVG/animoval5BW.svg) em mais detalhes:

<ellipse id="One" cx="200" cy="100" rx="30" ry="40" fill="#555">


<animate attributeName="rx" type="rotate" dur="5s" values="50;20;50" repeatCount="indefinite"/>
<animate attributeName="ry" type="rotate" dur="5s" values="10;60;10" repeatCount="indefinite"/>
</ellipse>

<use id="Two" xlink:href="#One" fill-opacity=".35" stroke="#d06" stroke-width="3">


<animateTransform attributeName="transform" type="rotate" dur="5s" from="0 200 100" to="360 200
100" repeatCount="indefinite"/>
</use>

<use xlink:href="#One" transform="translate(100,0)" />


<use xlink:href="#Two" transform="translate(-100,0)" />
Este exemplo comea com uma elipse de base ("One") de cor cinza escuro (# 555) e anima os seus raios
x e y. Em seguida, reutiliza a elipse trs vezes: uma vez no mesmo local ("Two"), uma vez para a
esquerda, e uma vez para a direita. Este exemplo permite que voc veja que as duas elipses cinza oscilam
apenas na vertical e horizontalmente. No entanto, ambas as elipses avermelhadas tm uma animao
aplicada atravs de um <animateTransform>, um filho do elemento, <use> de modo que eles podem ser
rodados tambm. Isso serve para demonstrar que a rotao adiciona uma nova propriedade para as
elipses. Note-se que por causa da freqncias de oscilao, o oval avermelhado coincide precisamente
com as cinzas umas quatro vezes em cada cinco segundos do ciclo de que voc pode ver a animao,
fazendo uma pausa, como mostrado em http://granite.sru.edu/~ddailey/SVG/animoval5BWpause.svg .

Aqui est um exemplo mais aventureiros usando elipses similares em que ambas oscilam e giram como
uma parte de um "clip-path" aplicado a uma imagem que , em seguida, transformado em um padro
de azulejos. Este atualmente funciona melhor em Firefox 4, Opera e Internet Explorer com ASV. Voc
pode v-lo em http://granite.sru.edu/~ddailey/SVG/animoval4a.svg .

O SVG tambm tem um elemento <animateColor>, destinado a mudar gradualmente de cor ao longo
do tempo; Contudo, ele foi reprovado. Em vez disso, SVG fornece a capacidade de animar valores no
numricos, utilizando um elemento <animate> com nomes de cores. Assim, voc pode usar um cdigo
como o seguinte para variar o preenchimento da elipse cinza acima, simultaneamente com alguns de
seus outros atributos (voc pode ver um exemplo em
http://granite.sru.edu/~ddailey/svg/animoval5.svg ):

<ellipse id="One" cx="200" cy="100" rx="30" ry="40" fill="#555">


<animate attributeName="rx" type="rotate" dur="5s" values="50;20;50" repeatCount="indefinite"/>
<animate attributeName="ry" type="rotate" dur="5s" values="10;60;10" repeatCount="indefinite"/>
<animate attributeName="fill" type="rotate" dur="5s" repeatCount="indefinite"
values="red;plum;yellowgreen;red" />
</ellipse>

Movimento ao longo de um caminho

Agora vamos brincar um pouco mais com o posicionamento destas elipses usando <animateMotion>
para fazer elas seguirem uma curva. Voc pode ver este exemplo em
http://granite.sru.edu/~ddailey/svg/animoval7.svg.
<path id="curve" stroke="black" stroke-width="3" opacity=".75" d="M 0,200 C 100,200 0, 100, 100,100 C
200,100 100,200 200,200 C 300,200 200, 100, 300,100 C 400,100 300,200 400,200 C 500,200 400, 100,
500,100 C 600,100 500,200 600,200 z" >
</path>

<ellipse id="One" cx="0" cy="0" rx="20" ry="10" fill="inherit" opacity=".75" stroke="black" stroke-width="2">
<animateMotion dur="10s" rotate="auto" repeatCount="indefinite">
<mpath xlink:href="#curve"/>
</animateMotion>
</ellipse>

Este exemplo desenha trs montes idnticos (cada um 200 pixels direita do anterior). O caminho
fechado pelo subcomando z. Em primeiro lugar, importante salientar que o locus da elipse
especificado para estar na curva ao definir seu centro, (cx, cy), para (0,0). Note tambm que a elipse leva
sua orientao a partir da curva em si, devido chamada da rotao com o atributo "auto"
(rotate="auto"). Alm disso, sendo a distncia percorrida pelo movimento da elipse maior ao longo dos
montes do que ao longo da linha reta, e sua velocidade aparente permanecer constante, leva menos
tempo para atravessar a linha do que para atravessar os montes.

O elemento <animateMotion> permite mover o contedo SVG ao longo de um determinado caminho.


Se voc tem animaes criadas anteriormente usando programao ou scripts, voc pode apreciar a
elegncia da soluo declarativa que <animateMotion> fornece. A quantidade de cdigo que se poupa
louvvel.

Interpolao Multivalores

O ltimo tipo de animao demonstrada aqui a interpolao de valores mltiplos. Neste exemplo, os
valores de atributos no so simplesmente valores escalares, mas colees de valores. Para us-lo, voc
configura uma interpolao em dois caminhos. A nica restrio que as vias devem ter o mesmo
nmero de coordenadas e os mesmos tipos de subcomando (tais como L, Q, C, ou A) para a animao
funcionar.
Considere o seguinte exemplo (visvel em http://granite.sru.edu/~ddailey/svg/animoval8.svg), que
anima dois vrtices de um caminho:

<path id="curve" stroke="black" fill="yellowgreen" stroke-width="3" fill-opacity=".5" >


<animate attributeName="d" dur="3s" values=" M 100,0 0,100 70,50 130,150 200,100 z;
M 100,0 0,100 70,150 130, 50 200,100 z; M 100,0 0,100 70,50 130,150 200,100 z"
repeatCount="indefinite"/>
</path>

A chave para entender este exemplo observar que o caminho da forma, d, governado por trs valores
(separados um do outro por um ponto e vrgula e formatados em linhas separadas para facilitar a
leitura).

O primeiro e o ltimo desses valores de coordenadas so os mesmos, e cada valor tem exatamente cinco
pontos. O Pentgono est animado por "morphing" repetidamente entre as duas formas mostradas no
lado direito da ilustrao. Alm disso, atravs do exame dos primeiro, segundo, e ltimo pontos do
pentgono, voc pode ver que ns mantivemos trs dos vrtices inalterados. Apenas os pontos onde x
igual a 70 e 130 respectivamente, so alterados. Como um desses vrtices se move para baixo na pgina,
a partir de (70, 50) para (70, 150), o outro move-se mesma distncia. Os valores iniciais e meio do
caminho so mostrados na parte direita da animao.
Outros exemplos que envolvem transio entre caminhos so mostrados nas seguintes imagens -
naturalmente, ns fornecemos URLs para que voc possa ver as verses ao vivo.

Interagindo com Animao

Animaes SVG podem ser iniciadas ou interrompidas atravs eventos gerados pelo usurio, como
cliques e rolamentos do mouse. possvel acionar a animao SVG atravs de script, e, inversamente,
utilizar os scripts para concluir a animao enquanto ela est rodando. Vamos comear com um
exemplo simples e trabalhar a partir da com scripts at a prxima seo.
Neste exemplo (visvel na http://granite.sru.edu/~ddailey/svg/animstart0.svg), uma elipse instruda
para se mover ao longo de uma trajetria curva, tal como nos exemplos anteriores. A diferena, porm,
que a animao no comea at que um objeto (G) seja clicado.

<path id="curve" stroke="black" fill="none" stroke-width="3" fill-opacity=".5" d="M 0,100 C 100,150 100,50
200,50 C 300,50 300,150 400,100" />
<ellipse cx="0" cy="0" rx="16" ry="8" fill="orange" opacity=".85" stroke="black" stroke-width="2">
<animateMotion dur="3s" rotate="auto" repeatCount="2" begin="G.click">
<mpath xlink:href="#curve"/>
</animateMotion>
</ellipse>
<g id="G">
<ellipse cx="200" cy="90" rx="33" ry="15" fill="yellow" stroke="black" stroke-width="2" />
<text x="175" y="101" font-size="31" fill="black" font-family="arial">GO</text>
</g>

Aqui est como ele funciona. Em primeiro lugar, o elemento <animate> contm o atributo begin =
"G.click". Significa que a ao especificada pela animao comear exatamente quando um objeto com
o id = G for clicado. Em segundo lugar, o objecto G na verdade um grupo contendo uma elipse e um
texto. A razo para agrup-los que, em ltima instncia, o desenvolvedor no pode ter certeza se o
usurio vai clicar no objeto oval ou no texto. Agrupando-os, o desenvolvedor garante que quando
qualquer um for clicado resulta na ativao da animao. Em terceiro lugar, a animao instruda para
executar exatamente duas vezes, usando o atributo repeatCount = "2".

Um aborrecimento menor (que , na verdade, dois pequenos aborrecimentos diferentes que acontecem
olhar como um) que, quando a animao no estiver em execuo, parte da elipse visvel no canto da
pgina. Isto acontece porque a elipse tem o seu conjunto centride para a coordenada (0,0), que
necessrio para que a elipse permanea centrada na curva ao longo da animao. Felizmente, existem
maneiras de contornar este problema, como voc ver no prximo exemplo (visvel em
http://granite.sru.edu/~ddailey/svg/animstart0a.svg ).
Para modificar o cdigo anterior, de modo que a elipse no pisque no final do ciclo, simplesmente
substitua a primeira elipse e seus filhos pelo seguinte cdigo:

<ellipse id="One" cx="0" cy="0" rx="16" ry="8" fill="orange" opacity="0" stroke="black" stroke-width="2">
<set attributeName="opacity" to=".75" begin="G.click" />
<animateMotion id="A" dur="3s" rotate="auto" repeatCount="2" begin="G.click" fill="freeze">
<mpath xlink:href="#curve"/>
</animateMotion>
</ellipse>

Este exemplo utiliza dois novos aspectos da animao SVG: o elemento <set> e o valor do atributo de
preenchimento = "freeze". Eles realizam dois efeitos bastante diferentes.
O elemento <set> permite que voc altere o valor de um atributo com base em um evento (quer gerada
pelo utilizador ou pela passagem do tempo). Inicialmente, a elipse invisvel (opacidade = "0"); No
entanto, quando G clicado, o elemento <set> torna a elipse visvel, alterando o valor de opacidade.
No final desta animao, o preenchimento = atributo "freeze" especifica que a elipse permanecer nos
ltimos valores especificados, ou seja, no final da curva.
Pode-se em vez disso fazer a elipse desaparecer no final da animao (como no exemplo em
http://granite.sru.edu/~ddailey/svg/animstart0b.svg), basta colocar dois elementos <set> dentro do
elemento <elipse>, assim:

<ellipse id="One" cx="0" cy="0" rx="16" ry="8" fill="orange" opacity="0" stroke="black" stroke-width="2">
<set attributeName="opacity" to=".75" begin="G.click" />
<set attributeName="opacity" to="0" begin="A.end" />
<animateMotion id="A" dur="3s" rotate="auto" repeatCount="2" begin="G.click">
<mpath xlink:href="#curve"/>
</animateMotion>
</ellipse>

Ns vamos dar um ltimo exemplo, uma extenso do acima que emprega mais alguns conceitos para
ilustrar um pouco do poder adicional de animao declarativa. Voc pode v-lo em
http://granite.sru.edu/~ddailey/SVG/animstart1.svg .

Inicialmente, para fins estticos somente, ns estabelecemos trs curvas, com dois <path> reutilizando o
primeiro com diferentes valores para o atributo de preenchimento. Em seguida, faremos boto amarelo:

<g id="G">
<set attributeName="opacity" to="0" begin="G.click" />
<set attributeName="opacity" to="1" begin="AM.end" />
<ellipse cx="205" cy="30" rx="33" ry="15" fill="yellow" stroke="black" stroke-width="2">
<set attributeName="fill" to="green" begin="G.mouseover" />
<set attributeName="fill" to="yellow" begin="G.mouseout" />
</ellipse>
<text x="180"y="41" font-size="31" fill="black" font-family="arial"pointer-events="none">GO</text></g>
Como nos exemplos anteriores, neste se identifica um grupo que contm uma elipse e um texto.
Contudo, h algumas diferenas:

O grupo feito de modo a desaparecer quando clicado e reaparecer quando o <animateMotion>


(#AM) terminar.

A elipse feita para alterar as cores de verde para amarelo, ou o contrrio, medida que o mouse se
move sobre ela ou a deixa. Isso para sinalizar para o usurio que o boto ao vivo e ativo. A escrita
direta do comportamento no objeto que est sendo animado, produz como resultado um cdigo mais
compreensvel, mais fcil de escrever, e mais fcil de manter do que o cdigo que est em outro lugar,
seja no script ou em uma folha de estilo. Ele tambm resulta em um DOM escrito mais facilmente.

Ao objeto de texto dentro do grupo dado o atributo de "pointer-events = none". Isso porque
caso contrrio, o navegador ir detectar que o mouse entrou no objeto de texto, o que ir desencadear
um evento "mouseout" na elipse.

Em seguida, tanto como no exemplo anterior, a elipse criada e orientada a seguir uma das curvas, duas
vezes, levando 3 segundos cada travessia:

<ellipse id="One" cx="0" cy="0" rx="16" ry="8" fill="orange" opacity="0" stroke="black" stroke-width="2">
<set attributeName="opacity" to=".75" begin="G.click+3" />
<set attributeName="opacity" to="0" begin="AM.end" />
<animateMotion id="AM" dur="3s" rotate="auto" repeatCount="2" begin="G.click+3">
<mpath xlink:href="#curve"/>
</animateMotion>
</ellipse>

A diferena aqui que, em vez de ter a elipse aparecendo exatamente quando o boto clicado, ela s se
torna visvel trs segundos depois do clique (begin = "G.click + 3").

<text x="180" y="40" font-size="35" fill="black" font-family="arial" display="none">


<set attributeName="display" to="block" begin="G.click" />
<set attributeName="display" to="none" begin="G.click+1" />
// 3
</text>
<text x="180" y="40" font-size="35" fill="black" font-family="arial" display="none">
<set attributeName="display" to="block" begin="G.click+1" />
<set attributeName="display" to="none" begin="G.click+2" />
// 2
</text>
<text x="180" y="40" font-size="35" fill="black" font-family="arial" display="none">
<set attributeName="display" to="block" begin="G.click+2" />
<set attributeName="display" to="none" begin="G.click+3" />
// 1
</text>

Este conjunto de objetos de texto simula uma contagem regressiva de -3 segundos a -1 segundo. A
contagem regressiva comea quando G clicado, mas, em seguida, depois de cada segundo, revela um
novo nmero e esconde o nmero antigo.
O exemplo poderia ter facilmente usado o atributo visibilidade (visibility), alternando seu valor de
"escondido" (hidden) para "visvel" (visible) e vice-versa; no entanto, fazer isso faz com que o objeto
invisvel ainda ocupe espao na tela. Quando isso no desejvel, use o atributo "display" (alternando
entre "block" e "none") para remover essa preocupao.

Programao SVG

Enquanto a animao SVG, seguindo um modelo declarativo, agradavelmente fcil, o modelo


"scripting"(programao) ainda mais poderoso, mas tambm normalmente requer mais trabalho e
especializao. nossa esperana que esta seo seja compreensvel para programadores e no-
programadores da mesma forma; No entanto, no-programadores devem estar cientes de que a
habilidade de programao normalmente leva meses ou anos para cultivar. Leia o documento do W3C
"Um Primer SVG para navegadores de hoje",
(http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#why_script), vamos direto ao assunto:

Sem programao em SVG no podemos:


Criar um novo objeto sempre que o usurio clica com o mouse;
Construir objetos com valores aleatrios para os seus atributos;
Permitir objetos para ter seus atributos modificados (nontrivially) por usurios;
Permitir que objetos em movimento tenham seus sentidos ou velocidades ajustadas
(nontrivially) pelo usurio;
Detectar a distncia entre objetos na tela em movimento;
Criar uma renderizao em 3D de um cilindro no espao;
Construir algo que age como um objeto <select> em HTML;
Simular o movimento de exrcitos de gafanhotos sobre uma torta de merengue infinita.

Agora, enquanto nem todos os desenvolvedores SVG compartilham os interesses acima com igual
entusiasmo, isso pode dar-lhes uma ideia da gama de possibilidades que o script permite. Tambm vale a
pena mencionar que entre as propostas de adies SVG2
(http://www.w3.org/Graphics/SVG/WG/wiki/SVG2_Requirements_Mailing_List_Feedback) so
sugestes que possam permitir o acesso declarativo para valores aleatrios, deteco de coliso, e recursos
3D avanados.

Introduo ao JavaScript e SVG

Para comear nossa discusso, o primeiro exemplo


(http://granite.sru.edu/~ddailey/svg/B/scriptstart1.svg) um tipo de caso mais simples: um programa
"Ol mundo" no qual o clique de um boto resulta em um simples script de resposta.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">


<script><![CDATA[
function Here(){
alert("hello")
}
]]></script>
<text id="Text" x="87" y="100" font-size="26" fill="black">Click</text>
<rect id="Rect" onclick="Here()" x="75" y="76" height="30" width="80" stroke="black" stroke-
width="2" fill="green" opacity=".5" rx="10"/>
</svg>
O clique no no boto resulta na abertura de uma caixa de alerta, que contm a mensagem "Hello".

Queremos assinalar vrias coisas sobre esse cdigo.

O JavaScript incorporado no SVG geralmente reside dentro de uma tag <script>. Porque SVG
realmente XML, voc deve usar: "<script> <! [CDATA [" para comear uma marca de script, e escrever:
"]]> </script>" para terminar a marca de script. Voc define funes de JavaScript e variveis dentro
dessas tags.

Embora o texto seja em parte visvel graas ao atributo opacidade (opacity) definido no retngulo, um
usurio no pode clicar nele. Para colocar o texto na frente em vez disso, e torn-lo sensvel a eventos,
voc pode agrupar os dois objectos, colocando-os dentro de um elemento <g>, primeiro o retngulo, em
seguida, o texto (como nos exemplos anteriores na seo "Interagir com Animao"), e, em seguida,
registrar o clique em evento sobre o grupo, em vez de somente no retngulo.

Quando o usurio clica no retngulo, o evento chama a funo JavaScript "Here()". Funes so usadas
para definir blocos de instrues que podem ser reutilizados por chamar a funo novamente.

Os comandos, neste caso, apenas um: alert ('hello') - dentro das chaves ({e}) so as instrues JavaScript
do programa que ser executado quando a funo for ativada.

O resultado lquido do exemplo acima que quando o boto verde clicado, a palavra "hello" aparece
em uma caixa de alerta.

Caixas de alerta no so consideradas um bom design de interface do usurio; elas so usadas


principalmente para depurao por programadores.

Os exemplos que se seguem todos comeam com este prottipo bsico e vo adicionando coisas
conforme necessrio. Quando escrever o script, voc pode querer comear com um modelo de script
simples (como o fornecido em http://srufaculty.sru.edu/david.dailey/svg/simpleTemplate.svg), porque
nem toda a sintaxe facilmente memorizvel.

Embora o exemplo acima realize muito pouco, serve ao propsito de mostrar como ativar uma funo
JavaScript a partir de um clique do mouse dentro de um documento SVG, e destinado a funcionar
unicamente como uma introduo suave do tipo de programa "Hello World" normalmente encontrado
em textos de programao introdutria. Programao um tema grande (to grande quanto a
matemtica, de fato, uma vez que detm a teoria da computao dentro dela), ento este livro pode na
melhor das hipteses fornecer apenas um vislumbre do que voc pode fazer com SVG e script
trabalhando juntos.

Usando Script para encontrar um objeto e alterar seus atributos

O Script oferece ao autor SVG vrias oportunidades para manipular objetos no SVG DOM. Primeiro,
porm, preciso saber como encontrar um objeto no DOM. H pelo menos dois jeitos diferentes mas
eficazes de encontrar um objeto para que voc possa manipul-lo.

Exemplo 1

Comeamos com o exemplo simples acima (http://granite.sru.edu/~ddailey/svg/B/scriptstart1.SVG) e


alteramos a declarao de alerta ('hello') de modo que, em vez disso, o cdigo recupere o objeto
chamado "rect" e, em seguida, modifique-o:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">


<script><![CDATA[
function Here () {
var R = document.getElementById("Rect");
R.setAttributeNS(null, "fill", "red");
}
]]></script>
<text id="Text" x="87" y="100" font-size="26" fill="black">Click</text>
<rect id="Rect" onclick="Here()" x="75" y="76" height="30"width="80" stroke="black" stroke-width="2"
fill="green" opacity=".5" rx="10"/>
</svg>

Quando um elemento definido em um documento SVG construdo e inserido no DOM, chamado


um n. O DOM tem uma estrutura de rvore - cientistas da computao chamam os ns de "folhas". O
elemento <rect> um n que foi dado um identificador usando o atributo id: id = "Rect".

Voc usa o mtodo getElementById () para recuperar um n especfico no documento, bem como o
mtodo retorna uma referncia que voc pode armazenar em uma varivel para uso futuro. No cdigo
acima, temos declarado a varivel "R" e temos que lhe atribudo o n de referncia retornado pelo
mtodo. Pense em "R" como um "alias" para "Rect". No entanto, lembre que a varivel "R" uma
referncia para o n "Rect" apenas dentro do corpo da funo (mbito), porque temos "R" declarada
como uma varivel local. Se quisssemos ser capaz de reutiliz-la fora da funo, ou dentro de outras
funes, seria necessrio declar-la como uma varivel global, logo no incio do script, e poderamos
tambm us-la no corpo da funo sem a palavra-chave "var":

<script><![CDATA[
var R;
function Here () {
R = document.getElementById("Rect");
...
}

Ns declaramos a varivel "R" global, e atribumos um valor a ela no corpo da funo. Enquanto no
atribuirmos um novo valor a essa varivel, ele vai se referir ao n "Rect" durante todo o programa.
Quando a funo "Here()" ativada pelo evento de clique, o n "R" ter o valor de seu atributo de
preenchimento modificado para vermelho. Note-se a utilizao do mtodo "setAttributeNS()", em vez
do mais genrico "setAttribute()"; embora este ltimo funcione igualmente bem, neste caso particular,
isto no verdade para mtodos que tm uma declinao XML quando utilizado em documentos
usando vrios "namespace", por exemplo HTML e SVG. Por isso, essencial para adquirir o hbito de
usar a gramtica apropriada.

Exemplo 2

Aqui est uma abordagem mais geral que iria trabalhar para qualquer item do documento para o qual
voc deseja mudar a cor de preenchimento. Voc pode ver este exemplo em
http://granite.sru.edu/~ddailey/svg/B/changeAttr2.svg.
O exemplo comea o mesmo que antes, ento as primeiras linhas so omitidas aqui:

function Here (evt) {


var R = evt.target;
R.setAttributeNS(null, "fill", "red");
}
]]></script>

<text id="Text" x="67" y="100" font-size="26" fill="black">Click</text>


<rect onclick="Here(evt)" x="55" y="76" height="30" width="80" stroke="black" stroke-width="2" fill="blue"
opacity=".5" rx="10"/>
<g transform="translate(100,0)">
<text id="Text" x="87" y="100" font-size="26" fill="black">Click</text>
<rect onclick="Here(evt)" x="75" y="76" height="30" width="80" stroke="black" stroke-width="2"
fill="green" opacity=".5" rx="10"/>
</g>

Observe o seguinte neste exemplo:

Cada um dos dois botes, quando clicado, envia um pequeno presente (conhecido como um
parmetro) para a funo "Here()". Este parmetro o evento (EVT), que um objeto que contm
informaes sobre o que aconteceu.

O cdigo "evt.target" uma maneira de se referir coisa que recebeu o evento. Nesse caso, "evt.target"
refere-se a qualquer retngulo, que o usurio clicou.

Depois de saber o que foi clicado, voc faz "R" alterar os atributos da mesma maneira que no exemplo
anterior.

Exemplo 3

Observe que um objeto no precisa ter um determinado atributo especificamente definido de antemo
para que voc adicione e altere esse atributo no cdigo (veja o exemplo em
http://granite.sru.edu/~ddailey/SVG/B/changeAttr3.svg, na qual o "dasharray" ajustado pelo script
ainda que o elemento original no contivesse tal atributo para comear). Isto possvel porque na
realidade a maioria dos atributos so atribudos ao elemento com um valor inicial (padro) que, no caso
do "dasharray" por exemplo, definido como "none".
function Here (evt) {
var R = evt.target;
if (evt.type == "mouseover") {
R.setAttributeNS(null, "stroke-dasharray", "4,8");
R.setAttributeNS(null, "stroke-width", "10");
R.setAttributeNS(null, "fill", "green");
}
else if (evt.type == "mouseout") {
R.setAttributeNS(null, "stroke-dasharray", null);
R.setAttributeNS(null, "stroke-width", "2");
R.setAttributeNS(null, "fill", "blue");
}
}
]]>
</script>
<text id="Text" x="67" y="100" font-size="26" fill="black">Click</text>
<rect onmouseover="Here(evt)" onmouseout="Here(evt)" x="55" y="76" height="30" width="80" stroke="black"
stroke-width="2" fill="blue" opacity=".5" rx="10"/>

Observe o seguinte neste exemplo:

O retngulo tem tanto um evento "onmouseover" e "onmouseout" definido. Ambos disparam a mesma
Funo: Here().
O cdigo usa o tipo do evento (mouseover ou mouseout) para determinar qual bloco de cdigo (dentro
das chaves) ir executar.
O cdigo ajusta vrios atributos durante a chamada: stroke-width, stroke-dasharray e fill.
Quando o usurio move o mouse para fora do retngulo, o evento acionado e a funo chamada
novamente restaurando os atributos para os valores originais.
Voc poderia facilmente adicionar outro bloco de cdigo, usando outra instruo "else if" para acionar
uma funo ou alterao de valores de atributo quando o usurio clica o mouse.

Exemplo 4

Como voc poderia esperar, voc pode fazer isso muito bem usando o elemento <set> disponvel em
animao SMIL, , como ilustrado aqui (ver tambm o exemplo em
http://granite.sru.edu/~ddailey/svg/B/changeAttr4.svg ):

<text id="Text" x="67" y="100" font-size="26" fill="black">Click</text>


<rect x="55" y="76" height="30" width="80" stroke="black" stroke-width="2" fill="blue" opacity=".5" rx="10">
<set attributeName="fill" begin="mouseover" to="green"/>
<set attributeName="stroke-width" begin="mouseover" to="10"/>
<set attributeName="stroke-dasharray" begin="mouseover" to="4,8"/>
<set attributeName="fill" begin="mouseout" to="blue"/>
<set attributeName="stroke-width" begin="mouseout" to="2"/>
<set attributeName="stroke-dasharray" begin="mouseout" to="none"/>
</rect>

Observe o seguinte neste exemplo:

Os navegadores Chrome e Safari no lidam corretamente com o boto "rollover" do mouse; eles s vezes
fazem confuso com os comandos.
Opera e Firefox discordam sobre o nmero de atributos esquerda no DOM aps o processo
executado, como mostra este exemplo.

Esta tcnica funciona em conflito com a abordagem popular de tentar separar o contedo, a
apresentao e comportamento (em marcao, estilos e roteiro, respectivamente). Ainda assim, h algo
bom de ter todos os aspectos de um objeto bem ali com ele. Tambm no claro, em uma linguagem
grfica como SVG que a distino entre os trs necessria.

As questes "cross-browser" associadas abordagem SMIL, independentemente de sua elegncia, pode


recomendar a abordagem com script em vez disso.

Exemplo 5

Sobre o tema da animao, aqui est um exemplo de animar as coisas usando JavaScript (ver http: //
granite.sru.edu/~ddailey/svg/B/changeAttr5.svg). Aqui esto as peas-chave do script:

if (evt.type == "mouseover") {
R.setAttributeNS(null, "stroke", "green");
R.setAttributeNS(null, "fill", "green");
running = true;
animate();
}
var w = 2;
var dir = 1;
function animate () {
if (!running) return;
w = w + dir;
R.setAttributeNS(null, "stroke-width", w);
if ( w > 5 || w < 1) dir =- dir;
setTimeout("animate()", 50);
}

Observe o seguinte neste exemplo:

Se o script parece complicado, perceba que ele apenas uma maneira de programao "no-declarativa".
Em "mouseover", o cdigo chama a funo "animate()", que repetidamente altera a largura do traado.

A funo "animate()" usa o comando JavaScript, "setTimeout()", para repetidamente reiniciar-se e


redesenhar a tela a cada 50 milissegundos.

O valor da varivel "w" aumenta a cada 50 milissegundos at atingir 5, e ento diminui.

Voc poderia obter um efeito semelhante com bastante facilidade usando a declarao <animate> (o que
provavelmente seria mais compreensvel para os autores de web prospectivos).

Exemplo 6

Este um exemplo que muda o texto dentro de um n de texto. Isso algo que as pessoas muitas vezes
querem fazer nesta etapa do seu aprendizado, mas verifica-se que a abordagem conceitual um pouco
diferente do que o que temos discutido at agora. As palavras dentro de um n de texto so, na verdade,
no atributos do n de texto, mas o contedo do seu n filho. Voc vai aprender mais sobre a distino
entre ns pai e filho mais adiante neste captulo, na seo "O SVG DOM." Voc pode ver o exemplo
rodando a http://granite.sru.edu/~ddailey/svg/B/changeAttr6.svg.

<script><![CDATA[
function Here (evt) {
var R = evt.target;
var T = document.getElementById("Text");
if (evt.type == "mouseover") {
R.setAttributeNS(null, "fill", "green");
T.textContent = "please";
T.setAttributeNS(null, "font-size","20");
}
else if (evt.type == "mouseout") {
R.setAttributeNS(null, "fill", "blue");
T.textContent = "Click";
T.setAttributeNS(null, "font-size", "26");
}
}
]]></script>
<text id="Text" x="67" y="100" font-size="26" fill="black">Click</text>
<rect onmouseover="Here(evt)" onmouseout="Here(evt)" x="55" y="76" height="30" width="80" stroke="black"
stroke-width="2" fill="blue" fill-opacity=".5" rx="10"/>

Observe o seguinte neste exemplo:

Como antes, o cdigo altera a cor do elemento <rect>. Mas desta vez ele tambm ajusta o tamanho da
fonte do elemento <text> chamado "Text", para que ele se encaixe em seu boto um pouco melhor. O
cdigo para fazer as duas coisas utiliza as mesmas tcnicas que nos exemplos anteriores.

O contedo do n de texto est dentro de um n considerado um filho do n de texto. Como tal, o


valor desse n no um atributo, ento voc pode definir seu "textContent". Porque o n interior o
primeiro filho do n de texto, voc pode alterar o contedo, em vez de "firstChild" use o cdigo
T.firstChild.nodeValue = "please."

O cdigo "T.textContent" no funciona no Adobe plug-in (o que significa que ele no vai trabalhar
com Internet Explorer 8 ou abaixo). Se o suporte para os navegadores importa para voc, ento voc
pode usar o cdigo "T.firstChild.nodeValue" = "please", que funciona em todos os navegadores.

Adicionando novo contedo para um documento SVG

Existem duas funes para adicionar novo contedo a um documento SVG: "createElementNS()" e
"cloneNode()". Seus efeitos so semelhantes, mas os seus casos de uso so um pouco diferentes. Antes de
entrar nos detalhes de cada um, em geral, voc usa as seguintes etapas para os dois mtodos:

1. Crie o elemento, usando o "createElementNS()" ou "cloneNode()".


2. Estabelea suas propriedades (normalmente usando "setAttribute").
3. Insira o objeto no documento SVG.

Ento, vamos usar um script para criar um novo elemento. (Este exemplo mostrado em
http://granite.sru.edu/~ddailey/SVG/B/addNodes1.svg.)

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >


<script><![CDATA[
xmlns=" http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink"
function add (evt) {
var C = document.createElementNS(xmlns, "circle");
C.setAttributeNS(null, "r", 30);
C.setAttributeNS(null, "cx", evt.clientX);
C.setAttributeNS(null, "cy", evt.clientY);
C.setAttributeNS(null, "opacity", .5);
C.setAttributeNS(null, "fill", "red");
document.documentElement.appendChild(C);
}
]]></script>

<rect width="100%" height="100%" fill="white" onclick="add(evt)"/>


<text id="Text" x="67" y="90" font-size="17" font-family="arial" fill="black">Clique em qualquer lugar para
adicionar algo</text>
<rect x="55" y="70" height="30" width="285" onclick="add(evt)" stroke="black" stroke-width="2" fill="blue"
opacity=".5" rx="10" />
</svg>

Neste exemplo, observe o seguinte:

onclick = "add (evt)" foi adicionado a ambos, o retngulo de fundo e o prprio boto.
"evt" o evento clique. "evt.clientX" e "evt.clientY" referem-se posio X e Y do prprio clique.
Clicar em um crculo que tenha sido adicionado no resulta em um novo crculo sendo adicionado.
"document.documentElement" refere-se tela de desenho do SVG - ele corresponde
aproximadamente a tag <body> em HTML. Este o recipiente no qual voc est adicionando cada
novo crculo, e o mesmo recipiente em que existe o texto e o retngulo.

Em vez de onclick = "add (evt)" da indicao acima, adicione uma declarao como a seguinte para o
<script> no incio do script (fora da funo):
document.documentElement.addEventListener("click", function (evt) {add(evt);}, false);

Depois de fazer isso, os cliques sero permitidos em todos os lugares, inclusive sobre os crculos recm-
adicionados.

Nota: A declarao DOM nvel 0 "document.documentElement.setAttribute (onclick, add (evt))"


realiza a mesma coisa, mas improvvel para atender as demandas das modernas aplicaes.

O prximo exemplo mostra que voc pode usar ambos os mtodos declarativos e scripts juntos no
mesmo documento (na verdade, voc pode usar a animao com script e declarativa juntos, e tambm
combin-las de forma que interajam umas com as outras). Considere o seguinte (veja o exemplo em
http://granite.sru.edu/~ddailey/svg/B/addNodes2.svg):
<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >
<script><![CDATA[
var xmlns = "http://www.w3.org/2000/svg";
var xlink = "http://www.w3.org/1999/xlink";
function add () {
var C = document.createElementNS(xmlns, "circle");
C.setAttributeNS(null, "r", 50);
var x = 20 + Math.random() * 300;
var y = 20 + Math.random() * 150;
C.setAttributeNS(null, "cx", x);
C.setAttributeNS(null, "cy", y);
C.setAttributeNS(null, "opacity", .5);
C.setAttributeNS(null, "fill", Color());
document.getElementById("underlayer").appendChild(C);
}
function Color () {
var R = parseInt(Math.random() * 255);
var G = parseInt(Math.random() * 255);
var B = parseInt(Math.random() * 255);
return "rgb(" + R + "," + G + "," + B + ")";
}
]]></script>

<rect width="100%" height="100%" fill="white"/>


<g id="underlayer" />
<text id="Text" x="67" y="90" font-size="17" font-family="arial" fill="black">Clique aqui para
adicionar um elemento</text>
<rect x="55" y="70" height="30" width="250" onclick="add()" stroke="black" stroke- width="2"
fill="blue" opacity=".5" rx="10">
<set attributeName="fill" begin="mouseover" to="green"/>
<set attributeName="stroke-width" begin="mouseover" to="5"/>
<set attributeName="fill" begin="mouseout" to="blue"/>
<set attributeName="stroke-width" begin="mouseout" to="2"/>
</rect>
</svg>

A partir deste cdigo, voc pode observar o seguinte:

Apenas o boto (que consiste em texto sob a <rect>) ativa a funo add().

Para impedir que o boto seja coberto com crculos (e, portanto, torne-se indisponvel para cliques do
mouse), um grupo nomeado como"underlayer" criado; ele comea sem qualquer contedo, mas o
contedo adicionado mais tarde. Esta camada exibida antes do boto na marcao, por isso
encontra-se sob o boto e, portanto, no pode interferir com os eventos do mouse sobre ele. Se fosse em
cima do boto ele iria receber os cliques do mouse.)

Algumas tcnicas declarativas so empregadas (ou seja, <set>, como discutido anteriormente neste
captulo), para dar ao boto um efeito de sobreposio. Se voc quer evitar tcnicas declarativas, voc
pode facilmente fazer isso com o script usando "setAttribute()", como desencadeada pelos eventos
"mouseover" e "mouseout".

Para diverso, cada novo crculo aparece numa localizao aleatria no retngulo, mudando os valores de
X e Y de (20,20) para (320,170).
Ns adicionamos uma cor aleatria para cada crculo, construindo de forma independente valores
aleatrios para cada um dos valores de R, G, B.

Clonagem de Nodes

A clonagem de um objeto existente, em vez de construir um novo, pode salvar de ter que escrever um
monte de cdigo. Vamos mostrar-lhe dois exemplos disso. Aqui est o primeiro:

<script><![CDATA[
function add (evt) {
var C = evt.target;
var N = C.cloneNode(false);
N.setAttributeNS(null, "x", Math.random() * 300);
N.setAttributeNS(null, "y", Math.random() * 200);
document.documentElement.appendChild(N);
}
]]></script>

<text font-size="17" font-family="arial" y="40" x="20" fill="black">Click na forma azul</text>


<rect x="55" y="50" height="50" width="85" stroke="#503" onmousedown="add(evt)" stroke-width="3" fill="blue"
fill-opacity=".5" rx="20" stroke-dasharray="9,5,2,5"/>

Neste exemplo relativamente simples (visvel emhttp://granite.sru.edu/~ddailey/svg/B/addNodes30.svg),


o <rect> est armado para chamar a funo "add ()" sempre que for clicado. A primeira funo encontra
o n em si (ou seja, o <rect>) e seus clones. O valor do parmetro "false" significa que ele no copia
qualquer n filho que possa encontrar dentro do retngulo. Isso deixa a maior parte do objeto de 11
valores de atributo intacto, mas dois deles, responsvel pelo seu posicionamento (X e Y) foram alterados.

No prximo exemplo (visvel em http://granite.sru.edu/~ddailey/svg/B/addNodes3.svg), as vantagens


da clonagem so ainda mais claras. Infelizmente, isso no funciona no Internet Explorer 9 ou Safari
ainda, por causa dos nodes SMIL dinmicas. Mas ele no funciona com as verses atuais do Chrome,
Firefox, Opera, e Internet Explorer com ASV.

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink">


<script><![CDATA[
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
function add (evt) {
var C = evt.currentTarget;
var N = C.cloneNode(true);
N.setAttributeNS(null, "fill", Color());
var s = (4 * Math.random() + 1);
N.firstChild.setAttributeNS(null, "dur", s);
document.documentElement.appendChild(N);
}
function Color () {
var R = parseInt(Math.random() * 255);
var G = parseInt(Math.random() * 255);
var B = parseInt(Math.random() * 255);
return "rgb(" + R + "," + G + "," + B + ")";
}]]></script>
<g onmousedown="add(evt)" fill="blue">
<animateTransform attributeName="transform" type="rotate" dur="5s"
values="0,100,100;360,100,100" repeatCount="indefinite"/>
<text x="67" y="70" font-size="17" font-family="arial" fill="black">Clique aqui</text>
<rect x="55" y="50" height="30" width="90" stroke="black" stroke-width="2" fill="inherit"
opacity=".5" rx="10" />
</g>
</svg>

Observe o seguinte neste cdigo:

O texto e o retngulo so colocados dentro de um grupo que est sendo rodado por um
<animateTransform>. o elemento do grupo que, na verdade, envia o evento para a funo.

Acontece que o alvo do evento, neste caso, na verdade o retngulo ou o texto, e no o grupo. Para
identificar e clonar o grupo, ns precisamos usar "evt.currentTarget", o objeto no qual o evento foi
registrado, em vez de "evt.target", que o objeto que desencadeia o evento.

O parmetro passado para o mtodo "cloneNode()" est definido para "true". Isto significa que os seus
nodes-filhos - ou seja, o <animateTransform>, o <texto>, e <rect> so todos clonados, juntamente com
o grupo. Em seguida, modificamos o preenchimento do grupo para uma cor aleatria, e este herdado
pelo <rect>.

Finalmente, para separar os vrios botes um do outro, encontramos o primeiro filho do grupo, ou seja,
o <animateTransform> - e modificamos a sua durao (DUR) para uma quantidade de tempo aleatria.

Note que o <animateTransform> no separado por qualquer espao em branco do elemento <g> e que
so, de fato, digitados na mesma linha de texto. Isto importante, porque o "firstChild" do grupo, de
outra forma, na verdade, um n de texto que consiste no espao em branco.

Avaliando Nodes (getAttribute)

Assim como "setAttributeNS ()" permite que voc altere os valores de atributos, o mtodo
"getAttributeNS ()" fornece uma maneira para recuperar o valor atual de algum atributo de um dado
n. Como exemplo, para obter as coordenadas "x" do centro de um crculo com id = "C", voc pode
usar uma sintaxe como esta:
var myCircle = document.getElementById("C");
var value = myCircle.getAttributeNS(null, "cx") ;

O exemplo a seguir (em http://granite.sru.edu/~ddailey/svg/B/DOMplay0.svg) usa "getAttributeNS ()"


para encontrar os valores de tamanho para um objeto especfico, e ento os usa para construir objetos
ligeiramente menores.

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >


<script><![CDATA[
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
function add (evt) {
var C = evt.target;
var N = C.cloneNode(true);
var rx = C.getAttributeNS(null, "rx");
var ry = C.getAttributeNS(null, "ry");
var cy = C.getAttributeNS(null, "cy");
// N.setAttributeNS(null, "cy", cy - 5);
// above line doesn't work because this value
// is overridden by animation
N.setAttributeNS(null, "rx", rx - 10);
N.setAttributeNS(null, "ry", ry - 5);
N.setAttributeNS(null, "transform", "translate(0," + (62 - ry) + ")");
document.documentElement.appendChild(N);
}
]]>
</script>

<radialGradient id="r1" cx="50%" cy="90%" r="34%" fy="80%" spreadMethod="reflect"


gradientUnits="objectBoundingBox"> <stop offset=".1" stop-color="black" stop-opacity="0"/>
<stop offset=".8" stop-color="orange"/>
<stop offset=".9" stop-color="white" stop-opacity="0"/>
<stop offset="1" stop-color="grey"/>
</radialGradient>
<text font-size="23" font-family="serif " x="20" y="40" fill="black">Click no oval</text>
<ellipse ry="60" rx="110" fill="url(#r1)" stroke="black" onmousedown="add(evt)" stroke-width="2">
<animate attributeName="cx" type="translate" dur="9s" values="5%;90%;5%"
repeatCount="indefinite"/> <animate attributeName="cy" type="translate" dur="13s"
values="5%;90%;5%" repeatCount="indefinite"/>
</ellipse>
</svg>

Neste exemplo, voc deve observar o seguinte:

A posio da elipse foi animada com diferentes periodicidades para a sua posio horizontal (cx)
(cy) e movimentos verticais. Porque 9 13 = 117, a animao vai repetir a cada 117 segundos.

A elipse foi preenchida com um gradiente radial refletido, apenas por diverso.

O atributo "onmousedown" usado na elipse, porque mais fcil pressionar o mouse para baixo para
em um objeto em movimento.

O evento "mousedown" chama a funo "add()", que reconhece o evento que o ativou, e do mesmo
modo, o alvo do evento: a elipse que foi clicada (pode haver mais de um alvo).

O verdadeiro valor passado para o "cloneNode()" significa que o mtodo de clonagem do alvo (a elipse)
ir incluir seus filhos.

O mtodo "getAttributeNS()" chamado para encontrar o tamanho da elipse clicada, para reunir os
valores para que o cdigo possa criar um menor. Tal como acontece com "setAttribute" e
"setAttributeNS", se estivermos trabalhando apenas no namespace SVG, poderamos usar o
"getAttribute()", mais simples e salvarmos a ns mesmos da necessidade de especificar o valor de
atributo "null".

A nova elipse colocada para baixo apenas um pouco de onde estava seu antecessor. Como o valor "cy"
controlado pela animao, atribuir um valor atravs de script no far efeito.
O cdigo usa uma transformao em vez de mover o centro de cada nova elipse um pouco mais para
baixo (por causa das razes mencionadas no ponto anterior).

Como o nmero de elipses aumenta, voc vai ver a animao abrandar consideravelmente.

Se voc fosse usar um sistema centralizado <animateTransform> para o grupo de elipses, seria mais
difcil fazer variar as frequncias de ciclo horizontal e vertical de forma independente.

Os ltimos trs pontos so abordados tanto neste exemplo muito semelhante (visvel em
http://granito.sru.edu/~ddailey/SVG/B/DOMplay0b.svg). As diferenas no cdigo so brevemente aqui
consideradas.

function add (evt) {


var C = evt.target;
var N = C.cloneNode(false);
var rx = C.getAttributeNS(null, "rx");
var ry = C.getAttributeNS(null, "ry");
var cy = parseInt(C.getAttributeNS(null, "cy"));
N.setAttributeNS(null, "cy", cy + 5);
N.setAttributeNS(null, "rx", rx - 10);
N.setAttributeNS(null, "ry", ry - 5);
C.parentNode.appendChild(N);
}

O novo n adicionado "parentNode" - o grupo que contm o objeto que foi clicado. Isto fornece
um primeiro vislumbre do tema da prxima seo, "SVG DOM."

No exemplo anterior, "cy" no poderia ser utilizado porque era animado. Agora, no.

A funo "parseInt()" converte o valor da cadeia armazenada em "cy" para um inteiro. A operao de
subtrao no caso anterior no tinha necessidade de fazer isso, porque a subtrao lana
automaticamente o resultado em aritmtica de inteiros. Aqui, se voc no usar "parseInt", voc vai ter
um erro "no um nmero"(NaN), pelo menos em alguns navegadores.

Este exemplo introduz apenas um novo conceito, a propriedade "parentNode", mas forneceu uma
chance para explorar algumas das ideias anteriores com um pouco mais de detalhes.

SVG DOM

Para aqueles que ainda no tenham programado com o DOM em HTML ou XML, este tema pode ser
bastante complexo. Enquanto voc l este captulo, ns encorajamos voc a passar uma semana ou duas
a jogar com alguns destes exemplos e outros em sites dos autores (por exemplo, ver
http://srufaculty.sru.edu/david.dailey/SVG/createElementBrowser.html). Se voc ainda no um
programador, voc pode querer ignorar esta seo.

Para recapitular, as duas listas a seguir mostram temas que j foram e os que no foram abordados neste
captulo. Uma vez que voc se familiarizar com todos esses conceitos, voc ser capaz de fazer qualquer
coisa na SVG DOM.
Estes so os temas que ns j abordamos:

setAttributeNS ()
getAttributeNS ()
getElementById ()
createElementNS ()
appendChild ()
cloneNode ()
firstChild

E aqui esto os tpicos que discutiremos nas sees finais do captulo:

previousSibling ()
nextSibling ()
getElementsByTagNameNS ()
parentNode ()
removeChild ()
createTextNode ()

Primeiro, voc vai descobrir a utilidade de um outro mtodo de um objeto DOM, chamado
"getElementsByTagNameNS()". Aqueles familiarizados com HTML DOM j deve ter notado que
alguns navegadores (mas no todos) consideraram o espao em branco (que inclui caracteres de espao,
tabulaes e retornos de carro), que se encontram entre as tags, como ns separados no DOM.

Tentando modificar o terceiro filho de um n, por exemplo, pode ter como alvo em um navegador um
n "#text" e em outro um n "<stop>". Felizmente, para qualquer dado elemento SVG (em outras
palavras, um n no DOM), voc pode pedir todos os seus filhos de um determinado tipo de mtodo de
uso dos "getElementsByTagNameNS()". Aqui est um exemplo (veja em
http://granite.sru.edu/~ddailey/SVG/B/DOMplay3.svg).

A principal coisa a notar que "getElementsByTagNameNS()" retorna uma coleo de ns, mas que
no pode ser tratada como uma matriz regular. Ou seja, seus elementos devem ser tratados usando esta
sintaxe especial: "getElementsByTagNameNS (namespace, nome).item(n)", em vez da notao de
matriz regular [n].

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink">


<script><![CDATA[
xmlns = http://www.w3.org/2000/svg;
xlink = "http://www.w3.org/1999/xlink";
var count = 0;
var letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"];
var letco = 0;
function add (evt) {
var C = evt.currentTarget; // C.nodeName is g
var N = C.cloneNode(true);
var x = Math.random() * 700 + 5;
var y = Math.random() * 400 + 5;
N.setAttributeNS(null, "transform", "translate(" + x + "," + y + ")");
var TspansN = N.getElementsByTagNameNS(xmlns, "tspan");
var TspansC = C.getElementsByTagNameNS(xmlns, "tspan");
if (TspansC.item(1).textContent == "Me") {
N.setAttributeNS(null, "fill", Color());
TspansN.item(1).textContent = letters[letco ++% letters.length];
} else {
N.setAttributeNS(null, "fill", C.getAttributeNS(null, "fill"));
TspansN.item(1).textContent = TspansN.item(1).textContent;
}
TspansN.item(2).textContent = count++;
document.documentElement.appendChild(N);
}
function Color () {
return "rgb(" + parseInt(Math.random() * 255) + "," + parseInt(Math.random() * 255) + "," +
parseInt(Math.random() * 255) + ")";
}
]]></script>
<g onmousedown="add(evt)" fill="orange" transform="translate(300,200)">
<rect height="30" width="80" fill="inherit" rx="10" stroke="black" stroke-width="2" fill-
opacity=".7" />
<text font-size="17" font-family="serif " transform="translate(6,20)" fill="black">
<tspan>Clique </tspan><tspan>Aqui</tspan><tspan></tspan>
</text>
</g>
</svg>

Aqui esto algumas notas sobre o cdigo anterior:

O manipulador de eventos adicionado ao grupo para que todo o grupo (<texto>, <rect>, e trs
elementos<tspan>) possam ser clonados.

Quisemos dar a cada novo boto sua prpria identidade, mas preservando ao mesmo tempo um pouco
de semelhana com o boto que foi usado para cri-lo.

Para cada boto novo dado um novo local (baseado em uma traduo envolvendo deslocamentos
aleatrios horizontais e verticais). Em todos os outros aspectos, ele herda os outros atributos do seu
antepassado.

Se o primeiro boto clicado, o novo boto recebe um novo nmero e uma nova cor aleatria.

Se um boto clicado, ao novo boto dado uma parte do nome e cor do boto recm-clicado.

O texto contm trs elementos <tspan>, cada um dos quais so recuperados como uma parte da coleo
atravs do "getElementsByTagNameNS()". Dois elementos desta coleo so modificados para mudar o
texto dentro do grupo do boto, com base, em um caso, no texto encontrado dentro do boto ativado.

Outro exemplo em que a utilizao de "getElementsByTagNameNS()" bem motivado e talvez um


pouco menos artificial (embora ele use animao SMIL) pode ser visto no
http://granite.sru.edu/~ddailey/SVG/B/DOMplay2.svg.

Remoo de contedo

Aqui est um exemplo mais simples (visvel em


http://granite.sru.edu/~ddailey/svg/B/makeAndTake0.svg) que mostra o uso de "removeChild()" para
excluir o contedo de um documento SVG:
<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >
<script><![CDATA[
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
var lastOne;
Root=document.documentElement;
function Color () {
var R = parseInt(Math.random() * 255);
var G = parseInt(Math.random() * 255);
var B = parseInt(Math.random() * 255);
return "rgb(" + R + "," + G + "," + B + ")";
}
function add (evt) {
var C = document.getElementById("C");
var NC = C.cloneNode(false);
NC.setAttributeNS(null, "cx", evt.clientX);
NC.setAttributeNS(null, "cy", evt.clientY);
NC.setAttributeNS(null, "fill", Color()); NC.removeAttribute("id");
Root.appendChild(NC);
}
function remove (evt) { Root.removeChild(evt.target); }
]]></script>
<defs>
<circle r="20" fill-opacity=".5" id="C" onclick="remove(evt)" stroke="black" stroke-width="2" stroke-
dasharray="8,4" />
</defs>
<rect width="100%" height="100%" fill="white" onclick="add(evt)"/>
<rect x="25" y="30" height="50" width="235" stroke="#800" stroke-width="2" fill="grey"
opacity=".65">
</rect>
<text x="37" y="50" font-size="12" font-family="arial" fill="#800">Clique no espao em branco para adicionar
algum elemento</text>
<text x="59" y="70" font-size="12" font-family="arial" fill="#800">Clique em algum elemento para exclu-lo</text>
</svg>

Este exemplo requer apenas alguns comentrios:

Em vez de digitar "document.documentElement" sempre que voc desejar inserir ou remover coisas
do SVG DOM, comum usar a varivel "Root" (ou SVGRoot) para se referir a essa entidade.
Depois de encontrar o crculo invisvel (escondido dentro do elemento <defs>), todos os seus atributos,
incluindo o atributo "onclick", so clonados. Sua cor e posio so determinados dinamicamente.

Cada crculo, como clonado, tem o manipulador de eventos embutido para chamar a funo de
remoo.

O novo centro de cada centro (cx, cy) retirado das coordenadas do clique do mouse (evt.clientX,
evt.clientY).

A funo "remove()" usa o evento para determinar qual objeto foi clicado. Esse objeto o alvo do
evento clique ento removido da raiz usando "Root.removeChild()".

H um problema com este script: todos os crculos clonados compartilham o mesmo "id". Abordamos
que pelo uso do mtodo "removeAttributeNS()" do objeto. Alternativamente, voc pode dar a cada
elemento uma identificao exclusiva (como, por exemplo, a contagem de cliques do mouse e o
dobramento desse nmero para o id), ou voc simplesmente no daria ao crculo um id em primeiro
lugar, e em vez disso acess-lo-ia atravs de outras tcnicas do DOM, tais como
"getElementsByTagNameNS()".

O prximo exemplo contm um boto que recolore a mais recente adio a um desenho. Em vez de
mostrar o cdigo de todo o documento, vamos apresentar os trechos de cdigo relevantes. Olhe para a
fonte do exemplo (visvel em http://granite.sru.edu/~ddailey/svg/B/makeAndTake1.svg) se voc precisar
examina-lo mais de perto. Alteraes do exemplo anterior esto ilustradas em negrito.

Root = document.documentElement;
var lastOne = Root;
function add (evt) {
var C = document.getElementById("C");
var NC = C.cloneNode(false);
NC.setAttributeNS(null"cx", evt.clientX);
NC.setAttributeNS(null "cy", evt.clientY);
NC.setAttributeNS(null "fill", Color());
Root.appendChild(NC);
lastOne = NC;
}
function colorit(){
if (lastOne.nodeName != "circle") return;
lastOne.setAttributeNS(null, "fill", Color());
}
function remove (evt) {
lastOne = evt.target.previousSibling;
Root.removeChild(evt.target);
}
]]></script>

<defs>
<!--aqui seria o material que idntico ao ltimo exemplo-->
<text x="50" y="100" font-size="12" font-family="arial" fill="black">Clique aqui para mudar a cor final</text>
<rect x="40" y="80" height="30" width="200" onclick="colorit()" stroke="blue" stroke-width="2" fill="red"
opacity=".35" rx="10"></rect>

Aqui, a adio principal uma funo chamada "Colorit ()" que encontra o ltimo crculo adicionado e
muda a sua cor. No entanto, isso traz as seguintes questes:

Voc precisa de um boto para ativar a funo "Colorit ()".

Voc precisa manter o controle de qual crculo foi adicionado por ltimo. Assim, o cdigo contm
uma varivel chamada "LastOne" que fica definida para apontar para o ltimo crculo criado.

Agora suponha que algum remove o ltimo crculo. Nesse caso, a varivel "LastOne" apontaria
para um objeto inexistente. Assim, quando um objeto removido, a varivel fica apontada para o
crculo adicionado anteriormente. Isto feito atravs da recuperao de "previousSibling" do item e
clicando, atribu-la a "LastOne".

Finalmente, suponha que todos os crculos foram excludos. Nesse caso, "LastOne" ir apontar para a
raiz ou para o ltimo elemento no DOM - que no vai ser um crculo! Portanto, o teste para verificar
se os pontos "LastOne" para um crculo permite a mudana de cor para acontecer de forma segura.

A seguir, vamos expandir esse exemplo com mais uma caracterstica: para permitir que o texto (neste
caso, um dgito numrico) para ser colocado fisicamente dentro de um dos crculos depois de ter sido
criado. Isso realmente exige um pouco mais de reformulao do modelo conceitual empregada e um
pouco mais de cdigo. Vamos incluir apenas as partes que se alteram (em negrito). O exemplo pode ser
visto em http://granite.sru.edu/~ddailey/svg/B/makeAndTake2.svg.

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >

<script><![CDATA[
var xmlns = "http://www.w3.org/2000/svg";
var xlink = "http://www.w3.org/1999/xlink";
var Root = document.documentElement;
var lastOne = Root;
function Color () {
var R = parseInt(Math.random() * 255);
var G = parseInt(Math.random() * 255);
var B = parseInt(Math.random() * 255);
return "rgb(" + R + "," + G + "," + B + ")";
}
function add (evt) {
var G = document.getElementById("C");
var NG = G.cloneNode("true");
var C = NG.firstChild;
C.setAttributeNS(null, "cx", evt.clientX);
C.setAttributeNS(null, "cy", evt.clientY);
C.setAttributeNS(null, "fill", Color());
Root.appendChild(NG);
lastOne = C;
}
function content () {
if (lastOne.nodeName != "circle") return;
var x = lastOne.getAttributeNS(null, "cx");
var y = lastOne.getAttributeNS(null, "cy");
var T = document.createElementNS(xmlns, "text");
Msg = document.createTextNode(Math.floor(Math.random() * 10));
T.appendChild(Msg);
T.setAttributeNS(null, "x", x - 10);
T.setAttributeNS(null, "y", parseInt(y) + 10);
T.setAttributeNS(null, "font-size", 36);
T.setAttributeNS(null, "fill", "black");
lastOne.parentNode.appendChild(T);
lastOne = lastOne.parentNode.previousSibling.firstChild;
}
function colorit () {
if (lastOne.nodeName != "circle") return;
lastOne.setAttributeNS(null, "fill", Color());
}
function remove (evt) {
lastOne = evt.currentTarget.previousSibling.firstChild;
Root.removeChild(evt.currentTarget);
}
]]></script>
<defs>
<g id="C" onclick="remove(evt)">
<circle r="20" fill-opacity=".5" stroke="black" stroke-width="2" stroke-dasharray="8,4"/>
</g>
</defs>
<rect width="100%" height="100%" fill="white" onclick="add(evt)"/>
<rect x="15" y="20" height="50" width="235" stroke="#800" stroke-width="2" fill="grey" opacity=".65"/>
<text x="27" y="40" font-size="12" font-family="arial" fill="#800">Clique no espao em branco para adicionar um
objeto</text>
<text x="49" y="60" font-size="12" font-family="arial" fill="#800">Clique em um objeto para exclu-lo</text>
<text x="40" y="100" font-size="12" font-family="arial" fill="black">Clique aqui para adicionar contedo</text>
<rect x="30" y="80" height="30" width="200" onclick="content()" stroke="black" stroke-width="2" fill="blue"
opacity=".35" rx="10"/>
<text x="40" y="140" font-size="12" font-family="arial" fill="black">Clique aqui para mudar a cor do ltimo objeto
adicionado</text>
<rect x="30" y="120" height="30" width="200" onclick="colorit()" stroke="blue" stroke-width="2" fill="red"
opacity=".35" rx="10"/>
</svg>

Eis o que acontece no cdigo anterior:


Um novo boto azul criado que acrescenta contedo (um dgito aleatrio entre 0 e 9) para o
ltimo n.

Para permitir que o contedo seja uma parte do n, o n a ser clonado, "C", transformado em um
grupo contendo o crculo. Dessa forma, quando o contedo est para ser adicionado, pode ser
adicionado ao grupo. Quando for a hora de remover o contedo, todo o grupo pode ser excludo.

A operao de clonagem agora precisa lembrar que "C" um grupo, em vez de um crculo. Isto significa
que, para mudar atributos do crculo dentro do grupo, voc tem que ter o "firstChild" do grupo.

A operao de clonagem usa o parmetro "true", porque a "child" do grupo (o crculo) necessrio.

Ao novo grupo acrescentado raiz (Root) e a varivel "LastOne" deixada apontando para o crculo,
por isso pode ser facilmente acessada quando o usurio decide mudar cores (em paralelo com o exemplo
anterior).

A primeira funo "content()" verifica se pontos "lastOne" foram atribudos a um crculo. Caso
contrrio, a funo encerrada.

Se "lastOne" um crculo, em seguida, o cdigo descobre suas coordenadas, porque essas sero
necessrias para posicionar o texto.

Um novo n SVG do tipo texto criado.

Em seguida, uma coisa bastante estranha acontece: para definir o "textContent" do novo n, voc tem
que criar um "textNode" dentro dele. Este o texto propriamente dito - os caracteres que aparecem em
<text> por exemplo - para <text> eod Ntxnc </ text>. Voc pode fazer isso em SVG usando a
mtodo "createTextNode (string)", em que a cadeia contm o contedo do texto.

O mtodo "parseInt ()" mais uma vez aplicado coordenada y antes de fazer a adio de modo
que a operao de adio no confundida com uma operao de concatenao.

Neste ponto, o cdigo pode anexar o n de texto e seu contedo - nopara o n referenciado por
"lastOne", que voc vai se lembrar, um <crculo> - mas em vez disso, para o grupo ao qual "lastOne"
pertence. Esse grupo "lastOne.parentNode".

Finalmente, porque no se substitui (tipicamente) o contedo desse n de texto novamente, o "lastOne"


ser redirecionado para apontar para o crculo dentro do grupo anterior no documento. (Isto no uma
tcnica infalvel, porque o contedo dos ns anteriores pode ter sido de dados textuais j, mas isso
bom o suficiente para agora. Voc poderia fortalecer este exemplo, verificando para ver se o n anterior
tem uma "child" de texto ou no, e, em seguida, continuar a partir da).

Medies

Esta seo aborda os temas "getBBox ()", "getTotalLength ()", "getPointAtLength ()" e "viewBox",
porque todos so teis na criao de scripts quando voc precisa de elementos de posicionamento mais
precisos.

Voc pode usar o mtodo "getBBox ()", que representa a "get bounding box". Ele acha as coordenadas
do menor retngulo mais pequeno (em paralelo com as bordas da janela de navegador) que contm a
geometria de uma dada forma.

Dada uma forma, como uma estrela roxa de 7 pontas, assim:

<path onclick="displayBB(evt)" fill = "#837fc0" id = "P9" stroke = "black" stroke-width = "1"


d="M 96 110.5 Q 191 132 96 154 1 176 77.5 115 154 54 111.5 142 69 230 69 132.5 69 35 111.5
123 154 211 77.5 150 1 89 96 110.5 z" />

Voc pode usar getBBox() como segue:

O JavaScript usada aqui (ver http://granite.sru.edu/~ddailey/svg/BBox0M.svg) que encontra a caixa


delimitadora se parece com isso:

function displayBB (evt) {


var P = evt.target;
var BB = P.getBBox();
var msg1 = "This " + P.nodeName + " has upperleft corner at (" + BB.x + "," + BB.y + ")";
var msg2 = "and it has width and height of " + BB.width + " and " + BB.height;
buildBox(BB);
alert(msg1 + "\n" + msg2);
}
Nota: Atravs de um evento de clique, o caminho ativa a funo "displayBB ()". Ento "evt.target"
utilizado para identificar o prprio caminho. BB.x, BB.y, BB.width e BB.height so as quatro medies
cruciais da caixa delimitadora. O exemplo finalmente s chama uma pequena funo que constri uma
retngulo vermelho nessas coordenadas.

Armados com essa informao, vamos considerar um problema de embalagem clssica: como encaixar
um monte de objetos "starlike" juntos em uma caixa. Suponha que voc tenha algumas estrelas SVG
como estas:

Alm disso, suponha que, embora a duplicando e espalhando-os, voc no quer que os objetos se
sobreponham, como mostrado nesta sada de um pequeno script que produz esses resultados por
aplicao de transformaes aleatrias:

Seria melhor ter um pouco de espao sobrando do que ter todos os objetos em cima de um outro. O
problema de embalagem clssico minimizar a quantidade de espao deixado - em outras palavras,
limitar a rea necessria para a embalagem menor rea possvel.

Uma hiptese simplificadora que empacotadores muitas vezes fazem, envolver cada item em um
retngulo bem grande (com preenchimento para impedir a ruptura!) E, em seguida, encaixar os
retngulos juntos dentro de um retngulo maior - que a tela neste caso. (Alternativamente, devido a
estas formas serem irregulares apenas o suficiente para embal-los verdadeiramente firmes, rotacion-los
e ajust-os de modo que o espao entre eles seja minimizado, pode ser uma soluo de embalagem mais
econmica do que uma retangular.) Alm disso, assumimos (j que isto SVG) que voc pode
redimensionar as estrelas para caber nas caixas. Isso como getBBox () pode vir a calhar.

A imagem anterior foi gerada pela seguinte programa JavaScript incorporado em SVG (visvel em
http://granite.sru.edu/~ddailey/svg/B/BBox2.svg). Atualmente, este exemplo funciona em todos os
browsers exceto no Firefox (que tem um bug conhecido relacionado tentativa de medir algo que no
est sendo renderizado).
Este exemplo envolve um pouco de lgebra e alguma programao, por isso pode parecer um pouco
difcil - mas vamos dar uma descrio geral da essncia do programa. Ns definimos a seguinte listagem
dentro da tabela abaixo para indicar o comentrio lado a lado com a lista de programas. O objetivo
que voc seja capaz de ver o fluxo do programa e as descries simultaneamente.

Cdigo Descrio
<svg xmlns="http://www.w3.org/2000/svg" O incio padro declarando "namespaces",
width="100%" e, em seguida, a funo "startup ()" chamada
xmlns:xlink="http://www.w3.org/1999/xlink"
onload="startup()">
imediatamente. Ela comea o programa e chama
<script><![CDATA[ os grficos.
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
Root = document.documentElement;
var Nacross = 12; //n de caixas na horizontal O cdigo de ladrilhos 12 estrelas de largura e 7 de
var Ndown = 7; //n de caixas na vertical altura. Estas variveis so globais definidas no
incio do programa para que um programador
possa encontrar e mud-las facilmente.
function Color () { Esta a nesna funo mesma "Color ()"
var R = parseInt(Math.random() * 255); apresentada antes.
var G = parseInt(Math.random() * 255);
var B = parseInt(Math.random() * 255);
return "rgb(" + R + "," + G + "," + B + ")";
}
function startup () { Medimos a tela usando getBBox () e
var Stars = document.getElementsByTagNameNS(xmlns, determinamos o tamanho das caixas.
"path");
var R = document.getElementById("R");
var BB = R.getBBox();
var littleBoxw = BB.width / Nacross;
var littleBoxh = BB.height / Ndown;
for (var i = 0; i < Nacross; i++) { Nestes dois loops encaixados, o lao externo
for (var j = 0; j < Ndown; j++) { controlado pela varivel "i" e funciona na
horizontal, enquanto que o loop interior funciona
na vertical. Voc poderia inverter esta ordem, sem
dificuldade.
var R = document.createElementNS(xmlns, "rect"); O cdigo cria um pequeno retngulo cuja altura e
R.setAttributeNS(null, "width", littleBoxw); largura so uma frao apropriada do tamanho da
R.setAttributeNS(null, "height", littleBoxh);
R.setAttributeNS(null, "x", littleBoxw*i);
tela disponvel. A posio de partida
R.setAttributeNS(null, "y", littleBoxh*j); determinada por mltiplos dos valores das
R.setAttributeNS(null, "fill", Color()); variveis "i" e "j".
R.setAttributeNS(null, "stroke", "black");
R.setAttributeNS(null, "stroke-width", 1);
R.setAttributeNS(null, "fill-opacity", .80);
Root.appendChild(R);
var rS = Math.floor(Stars.length * Math.random()); Este cdigo escolhe uma estrela ao acaso entre o
var SC = Stars.item(rS); nmero total de "paths" no documento. Em
SBB = SC.getBBox();
seguida, ele mede a estrela selecionada.
var StarClone = SC.cloneNode("false"); Aqui, o cdigo clona a estrela selecionada
var scale = "scale(" + littleBoxw / SBB.width + "," + aleatoriamente e executa alguma lgebra
littleBoxh / SBB.height +")";
var trans = "translate(" + (littleBoxw * i -BB.x *
desagradvel para redimensionar e mover a estrela
(littleBoxw / SBB.width)) + "," + (littleBoxh * j - SBB.y de sua caixa delimitadora e localizao originais
* para a clula reservada para ela na grade.
(littleBoxh / SBB.height)) + ")";
StarClone.setAttributeNS(null, "transform", trans +
scale) ;
StarClone.setAttributeNS(null, "fill-rule", "evenodd"); Este cdigo altera a cor e a regra de preenchimento
StarClone.setAttributeNS(null, "fill", Color()); da estrela para torn-la mais interessante.
Root.appendChild(StarClone);
}}}
]]></script>
<defs> Os caminhos Bezier reais so colocados dentro de
<path fill="#63f721" d="M 114.5 290.5 Q 213 280 um elemento <defs> para que eles sejam definido,
114.5 270 Q 16 260 110.5 290.5 Q 205 321 119 271.5
Q 33 222 106.5 288.5 Q 180 355 121.5 274.5 Q 63
mas no desenhados. Dessa forma, eles esto
194 103.5 285 Q 144 376 123.5 278.5 Q 103 181 103 disponveis para script. Os <paths> estrela atuais
280.5 Q 103 380 123.5 282.5 Q 144 185 104 276 Q 64 foram primeiro desenhados utilizando a
367 122 286.5 Q 180 206 106.5 272.5 Q 33 339 119 ferramenta de estrelas em um programa de
289.5 Q 205 240 110.5 270.5 Q 16 301 114.5 290.5 z" desenho. Ento as formas foram suavizadas e o
id="P18" stroke="black" stroke-width="1"/> cdigo fonte resultante foi copiado.
<path fill="#837fc0" d="M 96 110.5 Q 191 132 96 154
Q 1 176 77.5 115 Q 154 54 111.5 142 Q 69 230 69
132.5 Q 69 35 111.5 123 Q 154 211 77.5 150 Q 1 89
96 110.5 z" id="P9" stroke="black" stroke-width="1"/>
<path fill="#6fcf96" d="M 347 442 Q 408 393 347
344.5 Q 286 296 252 366.5 Q 218 437 294.5 454.5 Q
371 472 371 393.5 Q 371 315 294.5 332.5 Q 218 350
252 420.5 Q 286 491 347 442 z" id="P47"
stroke="black" stroke-width="1"/>
<path fill="#d17943" d="M 239 313.5 Q 329 284 239
255 Q 149 226 204.5 303 Q 260 380 260 284.5 Q 260
189 204.5 266 Q 149 343 239 313.5 z" id="P3"
stroke="black" stroke-width="1"/>
<path fill="#3b63db" d="M 193.5 112 Q 290 129
193.5 146.5 Q 97 164 182 114.5 Q 267 65 204 140.5
Q 141 216 174.5 123.5 Q 208 31 208 129.5 Q 208 228
174 135.5 Q 140 43 203.5 118.5 Q 267 194 182 144.5
Q 97 95 193.5 112 z" id="P1" stroke="black" stroke-
width="1"/>
<path fill="#c44c80" d="M 374 192.5 Q 459 157 374
122 Q 289 87 324.5 172 Q 360 257 395 172 Q 430 87
344.5 122.5 Q 259 158 344.5 193 Q 430 228 394.5
142.5 Q 359 57 324 142.5 Q 289 228 374 192.5 z"
id="P6" stroke="black" strokewidth=" 1"/>
</defs>
<rect id="R" x="0" y="0" width="100%" O <rect> R adicionado para que se possa medir a
height="100%" tela.
fill="#ddd"/>
</svg>

Antes de passar para "getTotalLength ()" e "getPointAtLength ()", vamos mostrar mais uma aplicao de
uma caixa delimitadora para definir o cenrio para o que se segue. A seguir um script que desenha uma
caixa delimitadora em torno de uma curva Bzier simples.

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink=" http://www.w3.org/1999/xlink"


onload="initialize()">
<script><![CDATA[
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
Root = document.documentElement;
function initialize () {
//algumas variveis globais
B = document.getElementById("B");
BB = B.getBBox();
R = document.getElementById("R");
}
function measure () {
var Rnew = R.cloneNode(false);
Rnew.setAttributeNS(null, "x", BB.x);
Rnew.setAttributeNS(null, "y", BB.y);
Rnew.setAttributeNS(null, "width", BB.width);
Rnew.setAttributeNS(null, "height", BB.height);
Rnew.setAttributeNS(null, "fill", B.getAttributeNS(null, "stroke"));
Rnew.setAttributeNS(null, "pointer-events", "none");
Root.appendChild(Rnew);
}
function hilight (evt) {
var P = evt.currentTarget;
var Ps = P.childNodes.item(3);
if (evt.type == "mouseover") Ps.setAttributeNS(null, "stroke", "red");
else Ps.setAttributeNS(null, "stroke", "black");
}
]]></script>
<path d="M 30 120 C -30 250 350 20 420 70" id="B" stroke="#008" fill="none" stroke-width="30"/>
<g id="H" onmouseover="hilight(evt)" onmouseout="hilight(evt)" onclick="measure()" transform="translate(170,
-50)">
<rect id="R" x="100" y="160" height="37" width="115" fill="#888" stroke-width="2" stroke="black"
fill-opacity=".3"/>
<text x="120" y="190" font-size="30" width="115" fill="#bbb" stroke-width="1"
stroke="black">Click</text>
</g>
</svg>

As seguintes observaes so relevantes para este exemplo:

Este exemplo funciona corretamente no Internet Explorer 9, Firefox, Opera e Internet Explorer com
ASV. Chrome e Safari, como est escrito, em ambos calcula mal a caixa delimitadora do objeto, vezes
at dramaticamente.

Percebendo que nos exemplos a seguir voc pode ter que clicar no boto "Clique" muitas vezes, ns
movemos vrias variveis globais para uma funo de inicializao. Diferentes programadores tm
estilos diferentes, e alguns preferem passar o dia em uma piscina de lodo a usar variveis globais. No
entanto, neste caso, ns no queremos ter que digitar novamente o DOM cada vez que o boto for
clicado e reatribuir valores s coisas, tais como curva de B. Outra abordagem faz todo o sentido: definir
uma referncia a um n (que a melhor coisa a fazer quando um n destinado para a manipulao).
Quanto questo de variveis globais, tambm uma boa prtica para proteger uma varivel com um
espao de nomes (namespace) em vez disso. Isto pode ser usado para evitar colises quando for trabalhar
com vrios mdulos diferentes (arquivos externos, bibliotecas, etc.).

Alm disso, voc no pode criar uma referncia a um objeto que ainda no existe. por isso que a
funo "initialize ()" chamada a partir do evento "onload" associado com o elemento <svg> em si.

Antes do boto ser clicado, a caixa delimitadora da curva B recuperada. Essas informaes sobre a
caixa delimitadora usado para construir um novo retngulo.

O novo retngulo leva sua cor de preenchimento da cor do traado da curva em si. Isso vai se provar til
no prximo exemplo, em que as diferentes curvas iro produzir retngulos de cores diferentes.

Observe que a caixa delimitadora <rect> construda no leva em conta a largura do traado. Isso pode
parecer contra-intuitivo, e o Grupo de Trabalho SVG est considerando alternativas para futuras verses
da especificao.

O novo retngulo tem um "pointer-events" definido como "none", que significa que o boto ainda
acessvel a eventos de mouse, mesmo que o retngulo esteja na parte de cima dele. Isso permite que voc
possa ver tanto o efeito de rolagem no texto do boto como usar os botes para criar mais retngulos.
Uma alternativa a esta abordagem seria a de alterar a ordem de empilhamento dos elementos no DOM,
excluindo o boto e, em seguida, adicionando-o de volta, portanto, colocando-o no topo novamente.

Nota: til salientar que "appendChild ()" remove um elemento e acrescenta-o parte superior do
documento ou de uma camada.

O exemplo indica que uma caixa delimitadora mede o estado inicial da animao de um caminho. Isto
verdade independentemente de, se a animao est sendo executada antes ou aps a medio da caixa
delimitadora.

Pontos em uma curva

Esta seo apresenta mais dois mtodos aliadas: "getTotalLength ()" e "getPointAtLength ()", que
podem ser utilizados para calcular as posies ao longo de curvas complexas; tais clculos poderiam
desafiar simples aritmtica. O exemplo mostrado tambm fornece uma boa lio de manipulao
DOM, porque envolve repetidamente, preencher um grupo com objetos e, em seguida, exclu-los todos
novamente. Voc tambm ver uma combinao da animao SMIL e JavaScript neste exemplo, com
cada tipo usado para o que ele faz melhor: SMIL para animar a oscilao de uma curva Bzier (o que
difcil de interpolar por meio de script) e JavaScript para acessar o DOM. O exemplo, mostrado com a
discusso intercalada.

var animate = false


function startup (evt) {
bunch = document.getElementById("bunch");
E = document.getElementById("E");
}
Col = new Array("red", "magenta", "blue", "cyan", "green", "yellow", "orange");

A varivel booleana "animate" usada para iniciar e parar a animao. Quando ela falsa, a animao
ser interrompida. Um dos botes ir ligar e desligar, alterando o valor dessa varivel. Um "array" de
cores, "Col", definido, em que "Col [0]" torna-se "vermelho", "Col [1]" torna-se "magenta", e assim
por diante, de modo que o cdigo pode atribuir cores de forma determinstica em vez de forma
aleatria.

function populate (n) {


if ((n > maxn) || (n < minn)) {
incr =- incr;
maxn = 60;
}
var v = n + incr;
var p = "M 10 150 C 200 "+(5*n)+" 350 "+(300-5*n)+" 450 100";
var B = document.getElementById("B");
B.setAttributeNS(null, "d", p);
var l = B.getTotalLength();
if (bunch.childNodes.length > 0) DOs(bunch);
for (i = 0; i < n + 1; i ++) {
P = B.getPointAtLength(l * i / n)
px = Math.ceil(P.x)
py = Math.ceil(P.y)
Enew = E.cloneNode(false)
Enew.setAttributeNS(null, "cx", px);
Enew.setAttributeNS(null, "cy", py);
Enew.setAttributeNS(null, "fill", Col[i%Col.length]);
bunch.appendChild(Enew);
}
if (animate) window.setTimeout("populate(" + v + ")", 10)
}
if (animate) window.setTimeout("populate("+v+")",10)
}

A funo "populate()" chama a si mesmo de forma recursiva e atualiza a tela a cada 10 milissegundos.
Isto porque o JavaScript no vai redesenhar a tela enquanto as funes ainda esto em processamento.
Usar este mecanismo recursivo de chamada em HTML um truque bastante normal. Cada vez que a
animao executada, o cdigo exclui todas as elipses existentes e introduz "n" novas elipses (em que n
aumenta por um perodo de tempo e, em seguida diminui). Cada nova elipse posicionada 1/n do
caminho ao longo da curva mais longe do que a precedente. A posio da curva atualizada tambm, s
por diverso.

function Dos (s) {


num = s.childNodes.length;
for (i = s.childNodes.length; i > 0; i--){
s.removeChild(s.childNodes.item(i - 1));
}
}

Ao apagar objetos, certifique-se que voc no tente excluir ns inexistentes.

//]]></script>
<defs>
<ellipse id="E" rx="10" ry="6" opacity=".75" stroke="black" stroke-width="2">
<animateMotion dur="2s" rotate="auto" repeatCount="indefinite" begin="H.click">
<mpath xlink:href="#B"/>
</animateMotion>
</ellipse>
</defs>

Uma outra verso faz algo semelhante, mas no emprega SMIL.

<g>
<path d="M 10 150 C 200 80 350 300 450 100" id="B" stroke="black" fill="none" stroke-width="4"/>
<g id="bunch"></g>
</g>
<g id="G" onmouseover="hilight(evt)" onmouseout="hilight(evt)" onclick="animate=false;populate(n=n+incr)"
transform="translate(60,-170)">
<rect x="90" y="393" height="47" width="115" fill="#bbb" stroke-width="2" stroke="black" />
<path fill = "#663e16" id = "P6" stroke = "black" stroke-width = "1" transform="translate(93,393)
scale(.10,.09)" d =[..... dados de caminho muito longo que consiste em letras manuscritas....]/>
<g id="H" onmouseover="hilight(evt)" onmouseout="hilight(evt)"
onclick="animate=animate;populate(7)">
<rect x="150" y="283" height="47" width="115" fill="#bbb" stroke-width="2" stroke="black" />
<text x="155" y="325" font-size="47" width="115" fill="#bbb" stroke-width="2"
stroke="black">Click</text>
</g>
</svg>
Um boto adiciona ns manualmente ao caminho, e o outro comea e pra a animao. Outra verso
mostra que, pelo menos em alguns navegadores as posies dos objetos em um determinado momento
na animao podem ser acessadas, desde que artefatos so deixados em suas posies iniciais.

ViewBox

O tema de medir as coisas, adequado para discutir a "viewBox", que na verdade um atributo do
prprio elemento SVG. O tema no est diretamente relacionado com scripting, mas permite
determinar exatamente como sero os grandes desenhos.

Um breve comentrio sobre as coordenadas relativas em SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >


<rect width="100%" height="100%" fill="#acf "/>
<ellipse rx="14%" ry="10%" cx="50%" cy="50%" fill="#79f "/>
<text font-size="45" textLength="150" lengthAdjust="spacingAndGlyphs" font-family="arial" font-
weight="bold" x="44%" y="53%" >TEXT</text>
<path stroke="#207" stroke-width="2" d="M 460 220 C 560 320 660 320 760 220 z" fill="none"/>
</svg>

Este cdigo sucede muito bem em centrar a elipse na tela; No entanto, note que o caminho e o texto
esto centrados apenas em determinados tamanhos de tela. Neste cdigo, que tentou centralizar o texto
apontando-o um pouco esquerda do centro da tela, e ns tambm tentamos esticar o texto, de modo
que a sua largura em pixels permanea constante (atravs da utilizao de textLength = "150" e
lengthAdjust = "spacingAndGlyphs" - cdigo atualmente suportado em todos os navegadores, exceto o
Firefox). Contudo, o caminho desenhado em coordenadas absolutas, por isso, os resultados variam
consideravelmente em funo do tamanho da tela.

O exemplo a seguir fornece uma maneira de garantir que o texto e os grficos mantenham relaes
semelhantes entre si, independentemente do tamanho da tela ou relao de aspecto:

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink"


viewBox="0 0 100 100" preserveAspectRatio="none">
<rect width="100" height="100" fill="#acf "/>
<ellipse rx="10" ry="12" cx="50" cy="50" fill="#79f "/>
<text font-size="4" textLength="20" lengthAdjust="spacingAndGlyphs" font-family="arial" font-
weight="bold" x="40" y="52" >TEXT</text>
<path stroke="#207" stroke-width=".5" d="M 35 46 C 45 60 55 60 65 46 z" fill="none" />
</svg>

A principal diferena aqui, fora algumas coordenadas retrabalhadas o uso do atributo "viewBox" no
prprio elemento <svg>. Ele funciona, declarando que todos os valores geomtricos, incluindo os
tamanhos de fonte e coordenadas do caminho, sero reformulados como coordenadas - Neste caso,
relativo a um retngulo com 100 unidades de largura por 100 unidades de altura. O atributo
"preserveAspectRatio" definido como "none" porque as unidades horizontais e verticais, de outra
forma, seriam ajustadas para o mesmo tamanho, o que significa que, por exemplo, o <rect> preencheria
apenas o centro da tela em uma tela tpica de navegador que mais larga do que alta. Como mostrado
na ilustrao seguinte, isto permite a textos, paths, elipses e retngulos manter a mesma posio e
tamanho em relao ao outro.

Claramente, esta abordagem pode no ser ideal se voc estiver interessado em preservar as propores de
aspecto em coisas como crculos ou preservar a legibilidade do texto, que muitas vezes projetada para a
legibilidade com um valor fixo de proporo da tela. No entanto, as vantagens deste mtodo d ao
designer um poderoso conjunto de ferramentas.

Mensagens entre SMIL e Script

Nesta seo vamos discutir duas tcnicas (um atributo SMIL e um mtodo JavaScript) que so teis em
aproveitar o poder de ambos, SMIL e JavaScript:

beginElement usado para ativar SMIL a partir do JavaScript.

onend usado para executar uma funo JavaScript aps a concluso de uma animao SMIL. Esta
seo ser bastante breve, composto por dois simples exemplos que ilustram os grandes princpios,
seguido por uma ilustrao mais complexa do princpio.

A partir de SMIL para Script

O cdigo a seguir ilustra a maneira tpica de invocar JavaScript do SMIL:


<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
<script><![CDATA[
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
function stuff (evt) {
O = evt.target.parentNode;
O.setAttributeNS(null, "fill", "red");
}
]]></script>
<ellipse fill="lightgreen" cx="40" cy="100" rx="22" ry="14" stroke="#804" stroke-width="5">
<animate attributeName="cx" dur="3s" onend="stuff(evt)" values="40;400;40"/>
</ellipse>
</svg>

Ele inclui um elemento<animate> que termina depois de trs segundos. Quando a animao termina, o
evento final disparado, que ativa a funo "stuff()", passando o evento como um parmetro. O alvo do
evento recebido pela funo de fato o prprio elemento <animate>. Tendo recuperado o elemento
<animate>, agora voc pode usar o script para entrar no DOM e encontrar o seu pai, a elipse. Essa elipse
, em seguida, colorida de vermelha.

Voc pode obter essa funcionalidade muito facilmente atravs de SMIL sozinho, usando um <set> com
algo como uma declarao de incio = "idOfTheAnimate.end". No entanto, este exemplo demonstra
que um papel muitas vezes muito til na construo de animaes complexas.

De Script para SMIL

Este exemplo utiliza um clique do mouse em um objeto para enviar um parmetro para o script que
identifica quais (de possivelmente muitas) animaes a desencadear.

<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" >


<script><![CDATA[
xmlns = http://www.w3.org/2000/svg;
xlink = "http://www.w3.org/1999/xlink";
function start (id) {
document.getElementById(id).beginElement();
}
]]></script>
<ellipse fill="blue" onclick="start('A')" cx="40" cy="140" rx="22" ry="14">
<animate id="A" attributeName="cx" dur="3s" begin="indefinite" values="40;400;40"/>
</ellipse></svg>

A declarao de chave envolve "beginElement ()", um mtodo aplicado a qualquer animao


identificada ou objeto definido. Ela utilizada para disparar a animao em si, ou seja, para provocar a
mudana nos valores de atributos especificados pela animao ou mudana.

Como antes, voc pode obter os mesmos resultados com bastante facilidade com <set> em vez de
confiar em script. Mas voc pode querer usar a tcnica de script para selecionar um objeto de forma
aleatria e que variem determinados atributos antes de lanar a sua animao.

Em seguida, voc ver uma combinao destes dois mtodos (SMIL-para-script e um script-para-SMIL)
que produz uma animao moderadamente divertida: um em que um objeto segue uma curva e, em
seguida, se transforma em uma forma diferente, se a sua trajectria de voo for completa.
<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
<script><![CDATA[
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
function start (evt) {
var T = evt.target;
var TP = T.parentNode;
var rn = Math.floor(Math.random() * 6) + 3;
var d = "M 40 0 ";
for (var I = 0; I < 2 * rn - 1; i++) {
if (i % 2 == 0) d + = "Q ";
var rx = Math.random() * 100 - 50;
var ry = Math.random() * 100 - 50;
d += rx + " " + ry + " ";
}
TP.setAttributeNS(null, "d", d + "80 40 z");
TP.setAttributeNS(null, "fill", Color());
T.beginElement();
}
function Color () {
// a mesma funo usada antes para criar a cor aleatria
}
]]></script>
<path fill = "none" id = "P1" stroke = "black" stroke-width = "1" opacity = "0.5"
d = "M 325 158 Q 293 107 260.5 166.5 Q 228 226 181.5 256 Q 135 286 227.5 255.5 Q 320 225 350.5 263 Q
381 301 402 290 Q 423 279 412 234 Q 401 189 448.5 193.5 Q 496 198 523.5 251.5 Q 551 305 538 192 Q 525
79 460 89 Q 395 99 376 154 Q 357 209 325 158 z" />
<path id="PQ" fill="blue" stroke="black" stroke-width="2" d="M -50,-50 50,-50 50,50 -50,50 z" fill-
rule="evenodd" >
<animateMotion dur="2s" rotate="auto" onend="start(evt)" begin="0;indefinite" fill="freeze">
<mpath xlink:href="#P1" />
</animateMotion></path>
</svg>

Observe o seguinte sobre este exemplo:


begin = "0; indefinite" em <animateMotion> permite a animao tanto para comear assim que o
carregamentos de pgina (no tempo zero) e ser inicializado pelo script, usando a instruo
"T.beginElement ()".

A forma de viagem (inicialmente um quadrado) instrudo, atravs do <animateMotion>, para viajar


em torno do caminho uma vez a cada dois segundos.

fill = "freeze" em <animateMotion> assegura que a forma de viagem permanece no final do caminho em
vez de reverter para a sua posio inicial no final de um ciclo. Se isso no acontecesse, voc veria uma
forma cintilante momentaneamente no canto superior esquerdo da tela.

Quando um circuito do caminho completo, a funo "start ()" chamada.

Um caminho construdo de forma aleatria. Um ponto de partida inicial em (40,0) e um ponto final
em (80,40) so fornecidos. A parte restante dos pontos (entre trs e oito deles) so inseridos no
caminho, com todos os outros pontos a ser um ponto de controle de uma curva quadrtica. Isto permite
uma coleo relativamente interessante de formas curvilneas que combinam componentes e com arestas
vivas. Variando a complexidade das formas pela modificao do nmero de pontos, permite uma
variedade ainda maior.

Com algum esforo considervel, esta animao poderia ser feito sem SMIL, mas no poderia ser feita
sem script. O SMIL lida com a rotao automtica, bem como a travessia de uma spline cbica bastante
complexa que seria um pouco complicado sem algum conhecimento em matemtica e geometria.

Passando mensagens entre HTML e SVG

Este no apenas um tema grande e complexo, mas tambm uma diverso. Nesta seo, vamos fornecer
apenas o bsico para voc comear, mas se voc precisar, voc pode olhar para "Um Primer SVG para
navegadores de hoje."

Maneiras de colocar SVG in HTML

Existem cinco maneiras de colocar contedo SVG em um documento HTML:


voc pode usar <embed>, <object>, <iframe> ou <img>, ou voc pode faz-lo em linha (em HTML5).
Todos so aceitveis de acordo com as normas, tanto para HTML5 como para SVG. O mtodo <img>,
por vrias razes, no permitir script para ser executado, mas os outros sim. O suporte em linha
tambm tem, neste momento, algumas inconsistncias bastante grandes em plataforma cruzada. O
mtodo <iframe> tem, de acordo com nossas experincias, vrias inconsistncias cross-browser no acesso
ao SVG DOM. O mtodo <Embed> tem problemas com o contedo fallback para navegadores que no
suportam SVG, e <object> tem alguns problemas de segurana associados com o script rodando atravs
do plug-in Adobe. Atualmente, a tcnica recomendada usar <object>, embora tambm vamos
apresentar um exemplo de suporte a SVG em linha porque intercalar cdigo SVG embutido em HTML
a tendncia atual.

O contrrio: Colocar HTML em SVG

Para as pessoas centradas em HTML, natural pensar em colocar SVG no HTML. Por outro lado, os
conceitos de comunicao abrangidos pelo HTML talvez nem to adaptvel nem to ampla quanto o
do SVG, por isso, para fazer justia, oportuno mencionar que se pode ir por outro caminho,
utilizando o elemento <ForeignObject> de dentro do SVG para incorporar o HTML. Isto tem a
vantagem de que os filtros poderosos, mscaras, caminhos de recorte e animao de SVG podem ser
exercidos sobre o indigesto HTML. Felizmente, a maioria dos navegadores tm implementaes, pelo
menos parciais de <foreignObject>, como o exemplo a seguir (que funciona no Opera, Firefox, Chrome
e Safari) demonstra. Este exemplo carrega um documento HTML em SVG usando o <ForeignObject>
e, em seguida, gira-o. Os links na pgina de trabalho, texto permanecem selecionveis e as barras de
rolagem HTML ainda funcionam. Alguns autores tm ido to longe como a utilizao de filtros SVG
(discutido na prxima captulo) para remodelar temas de cores de documentos HTML de uma forma
que pode ajudar a sua legibilidade para pessoas com certos tipos de daltonismo.
Usando <object> para incorporar SVG in HTML

Vamos comear com algo que funciona muito bem em todos os lugares, uma espcie de caso mais
simples:

<!doctype html>
<html>
<body>
<object type="image/svg+xml" data="simplest.svg">
<!-- contedo aqui -->
<p>Desculpe! Seu navegador no suporta SVG!
Por favor, use um navegador mais moderno.</p>
</object>
</body>
</html>

importante observar trs coisas:

Como desta escrita, a declarao doctype HTML5 <! Doctype html> necessria para o Internet
Explorer 9 poder alternar no modo de peculiaridades para que ele possa ver o SVG no HTML.

Se voc estiver usando o Adobe plug-in com verses mais antigas do Internet Explorer, voc deve usar
<embed> em vez de <object> - este funciona em todos os navegadores modernos, mas no tem a
vantagem de suportar uma declarao para abordar os navegadores que no suportam SVG.
Alternativamente, voc poderia usar o conselho no "w" usar <param> dentro de <object> para resolver
as idiossincrasias.

Dentro da tag <object>, voc pode incluir uma mensagem mais extensa que instrui o visitante sobre
qual verso do seu prprio software apoiaria SVG, ou sugerir solues alternativas (tais como a obteno
do Adobe plug-in para verses mais antigas do Internet Explorer).
GetSVGDocument ()

Aqui est um exemplo um pouco mais complexo que permite, a partir do HTML, interrogar
propriedades sobre um documento SVG embutido. Voc faz isso usando o mtodo "getSVGDocument
()" em associao com os objetos HTML <object>, <embed> ou <iframe>.

<!doctype html>
<html>
<script>
function peruse () {
var D = document.getElementById("O");
var SVGDoc = D.getSVGDocument();
var SVGRoot = SVGDoc.documentElement;
var who = SVGRoot.firstChild.nextSibling;
var whoName = "<" + who.nodeName;
var whoHow = who.attributes.item(0);
var whoNow = whoHow.nodeName;
var whoWhat = whoHow.nodeValue + ">";
alert(whoName + " " + whoNow + "=" + whoWhat);
}
</script>
<body>
<button onclick="peruse()">open</button><br>
<object id="O" type="image/svg+xml" data="simplest.svg">
<p>Sorry! Your browser does not support SVG!
Please use a modern browser.</p>
</object>
</body>
</html>
<svg xmlns="http://www.w3.org/2000/svg">
<circle r="50"/>
</svg>

Trs conceitos-chave so importantes aqui:

Para a tag <object> foi dado um "id", que usado para que a tag e o DOM dentro do SVG possa ser
recuperado a partir do DOM HTML usando "getElementById ()".

O mtodo "getSVGDocument ()" recupera o documento SVG em si mesmo. Se voc fosse inserir uma
declarao "alert (SVG doc.nodeName)" apenas aps a definio SVG Doc, voc veria que o
"nodeName" seria "#document".

"SVGDoc.documentElement ()" recupera o SVG DOM em si mesmo. Uma insero "alert


(SVGRoot.nodeName)" revelaria "SVG", e a partir da que voc pode atravessar a hierarquia de ns
do documento SVG.

Agora, vamos estender os conceitos um pouco. No exemplo mostrado abaixo, uma tabela HTML
contm um grupo de palavras. Qualquer palavra, quando clicada, cria um novo n de texto SVG
contendo essa palavra, posicionado em algum local aleatrio dentro do documento SVG.

<!doctype HTML>
<HTML>
<head>
<style>
div.u {float:top; height:30%}
div.d {float:bottom; height:70%}
td {text-align:center;font-family:impact;width:15%;background:#eee}
</style>
<script>
function init () {
var Ds = document.getElementsByTagName("td");
for (var i in Ds) Ds[i].onclick = function () {add(this);};
var D = document.getElementById("E");
SVGDoc = D.getSVGDocument();
SVGRoot = SVGDoc.documentElement;
svgns = "http://www.w3.org/2000/svg";
}
function add (o) {
var word = o.firstChild.nodeValue;
var T = SVGDoc.createElementNS(svgns, "text");
var MsgNode = SVGDoc.createTextNode(word);
var fontratio = 0.05;
var adj = (1 - fontratio);
x = Math.random() * .9 - 2 * fontratio;
y = Math.random() * .5;
T.setAttributeNS(null, "x", x);
T.setAttributeNS(null, "y", y);
T.setAttributeNS(null, "font-size", fontratio);
T.setAttributeNS(null, "font-family", "serif ");
T.appendChild(MsgNode);
SVGRoot.appendChild(T);
}
</script>
</head>
<body>
<div align="center" class="u">
<table border=1>
<tr><td>artichoke</td><td>balustrade</td>
<td>cantaloupe</td><td>dandelion</td></tr>
<tr><td>elephant</td><td>familiar</td>
<td>groundhog</td><td>Hydrophlorone</td></tr>
</table>
Clique em qualquer palavra acima
</div><hr>
<div class="d">
<object onload="init()" id="E" type="image/svg+xml" data="simplerect.svg" height="100%" width="100%">
<p>Seu navegador no suporta SVG</p>
</object>
</div>
</body></html>

Observe o seguinte sobre este exemplo:

Cada clula da tabela, quando clicada, envia a si mesmo (um objeto) como um parmetro para a funo
"add ()".
A funo "add ()" recebe a clula da tabela, determina o texto que est dentro dela, e ento constri um
n de texto SVG cujo contedo igual ao contedo da clula da tabela.
O novo n SVG inserido no DOM SVG numa localizao aleatria (tendo em conta o tamanho do
ecr e o tamanho do tipo de letra empregue).

Esse prximo exemplo demonstra uma ida e volta de HTML para SVG e o contrrio tambm. Aqui est
um novo material a partir do script em HTML:

function respond (evt) {


var w = evt.target.firstChild.nodeValue;
document.getElementById(w).style.background = "red";
}
O documento SVG utilizado o seguinte:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1" preserveAspectRatio="none"


onload="init()">
<script><![CDATA[
function init () {
Root = document.documentElement;
Root.addEventListener("click", top.respond, false);
}
]]></script>
<rect x="0" y="0" width="100%" height="100%" fill="#ddd"/>
</svg>

Observe o seguinte neste exemplo:

Este exemplo faz uma pequena alterao no SVG a partir do exemplo anterior, ele adiciona uma funo
"init ()" que executada quando o documento carrega. Esta funo faz com que cada objeto fique
sensvel ao clique do mouse.

O objeto clicado aciona uma funo no topo, ou seja, o recipiente HTML. Se o SVG no for dentro de
um recipiente de algum tipo, em seguida, clicar no objeto ir lanar uma exceo. (Por favor, perceber
que este cdigo foi mantido simples para ilustrar as questes mais importantes).

O mtodo "addEventListener ()" usado para atribuir o evento para os objetos no SVG DOM. O
"Root.setAttribute" ( "onclick", "top.respond") teria feito o mesmo trabalho.

No HTML, desta vez, em vez de apenas adicionar um manipulador de eventos a cada <td> da tabela,
ns tambm damos a cada um um "id" igual ao texto dentro dele. Isto permite que o texto em SVG seja
capaz de encontrar o seu pai.

O evento clique dentro do documento SVG envia o evento de volta para o HTML, onde as
propriedades do objeto que instigou o evento so ento analisadas e utilizadas para relacionar-se com o
objeto desse nome em HTML. Especificamente, o texto SVG corresponder a um item em HTML. O
boto que inicialmente conduziu ao desenvolvimento de um n , assim, identificado.

Programadores experientes iro reconhecer que existem muitas outras maneiras de realizar a mesma
coisa. No entanto, este exemplo fornece uma ilustrao crucial de como acessar scripts HTML de
eventos e scripts em SVG.
SVG embutido em HTML5

O padro HTML5 ainda em evoluo tem uma exigncia de manter uma estreita integrao entre
HTML e SVG. Isto significa vrias coisas, mas entre a mais importante que o HTML permite a direta
insero de cdigo SVG em HTML, intercalado, por assim dizer, entre tags HTML, "inline". O
modelo "inline" ainda no est implementada de forma consistente em todos os navegadores. H uma
discusso em andamento sobre as maneiras que HTML e SVG podem compartilhar animaes, filtros e
fontes, e possivelmente at mesmo coexistir dentro do mesmo "namespace". No entanto, vai demorar
alguns anos antes que estas decises sejam finalizadas e amplamente implementadas pelos navegadores.
O que segue so alguns exemplos que parecem funcionar de maneira bastante consistente mesmo no
presente. No exemplo a seguir, clicando em um boto em HTML ou um crculo em SVG, altera um
atributo da sua contraparte no outro meio Ambiente.

<!DOCTYPE HTML>
<html>
<script>
function f () {
document.getElementById("C").setAttributeNS(null, "fill", "orange");
}
function g () {
document.getElementById("I").setAttribute("value","hello");
}
</script>
<body>
<svg width="300" height="250" xmlns="http://www.w3.org/2000/svg">
<circle id="C" cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="lightgreen" onclick="g()"/>
<text x="65" y="54" font-size="16" font-family="arial" pointer-events="none">
click here
</text>
</svg>
<input id="I" type="button" onclick="f()" value="Clique aqui">
</body>
</html>

No prximo exemplo, um exemplo anteriormente utilizado para demonstrar os princpios mais simples
do script SVG dobrado em um recipiente HTML simples para mostrar como os DOM combinados
podem realmente trabalhar a seu favor.

<!DOCTYPE HTML>
<html>
<script>
function startup () {
S = document.getElementById("SVG");
for (i in S.childNodes) S.childNodes[i].onclick = removeIt;
}
xmlns = "http://www.w3.org/2000/svg";
xlink = "http://www.w3.org/1999/xlink";
function removeIt (e) {
T = e.target;
if (T.nodeName == "rect") add(e.clientX, e.clientY);
else T.parentNode.removeChild(T);
}
function add (x,y) {
var C = document.createElementNS(xmlns, "circle");
C.setAttributeNS(null, "r", 50);
C.setAttributeNS(null, "cx", x);
C.setAttributeNS(null, "cy", y);
C.onclick = removeIt;
S.appendChild(C);
}
</script>
<p onclick="removeIt()">Al aqui!</p>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" xmlns:xlink= http://www.w3.org/1999/xlink id="SVG"
onload="startup()">
<rect width="100%" height="100%" fill="white" />
<circle r="50" />
<text font-size="12" x="50" y="20" onclick="removeIt()">Clique em algo para removr</text>
<text font-size="12" x="50" y="80">Clique em nada para adicionar</text>
</svg>
</html>

As oportunidades para fazer SVG com movimento e interatividade so ricas e multifacetadas. Com o
SMIL, o no-programador tem disponvel um vocabulrio expressivo que permite que praticamente
qualquer coleo de atributos seja animado com o mnimo de cdigo e facilidade conceitual. E para o
programador, ou mesmo o novato, mtodos DOM permitem que voc use JavaScript para construir
interfaces sofisticadas.
As nicas limitaes so, no caso de SMIL, o fato de que as implementaes ainda no esto totalmente
padronizadas, e no caso da escrita, a complexidade do cdigo. Nos captulos 6 e 7, voc ver maneiras
de chegar a um acordo com algumas das questes relacionadas com a complexidade do cdigo.
Captulo 5 Filtros SVG

O tpico de filtros complexo. Existem muitos tipos de filtros de complexidade varivel. Voc pode
encadear filtros em um conjunto de formas bastante complexas, armazenar resultados intermedirios em
locais temporrios, e combinar estes resultados temporrios em conjunto, utilizando uma variedade de
mtodos de mistura e composio. Em vez de pensar em filtros individuais, ou mesmo cadeias de filtros,
pense em um fluxograma de filtros ligados entre si numa rede.

Como no Adobe Photoshop, onde voc pode sobrepor camadas diferentes ao aplicar diferentes filtros
para cada um, e, em seguida, extrair os canais de cores a partir dessas camadas e calcular as diferenas
entre a camada resultante, voc pode fazer esse tipo de trabalho em SVG. A diferena que, em SVG
pode faz-lo por meio de programao e dinamicamente em uma pgina da web por meio de script ou
animao.

Outra coisa importante a entender que como algumas das coisas maravilhosas desenvolvidas dentro do
SVG comeam a se propagar para fora, os proponentes do HTML5 esto comeando a reconhecer o
quo maravilhoso o SVG, e comearam a tomar emprestado, muitas das boas ideias, incluindo
gradientes, "clip-path", grficos do lado cliente (por exemplo, usando o elemento <canvas>), animao,
fontes e filtros. Em alguns casos, isso funciona relativamente bem, e em outros casos (como com fontes
da web e animao), no to claro se as especificaes SVG sero preservadas, nem, na verdade, se seu
poder expressivo ser preservado. Assim, enquanto HTML5 e CSS3 ainda esto em fluxo, prematuro
dizer se isso tudo vai dar certo; mas basta dizer que a aprendizagem sobre filtros dentro do SVG deve
criar caminhos neurais que tero alguma probabilidade de resistir mesmo aps o quadro conceitual ter
sido alterado.

O elemento bsico <filter>

O elemento <filter> aplicado a outro objeto tanto como um "clip-path" ou gradiente aplicado, ou
seja, atravs de um atributo definido dentro do objeto ao qual ser aplicado o filtro. O atributo algo
como isto: filter = "url (#filtername)". O elemento <filter> em si deve ter um ou mais filtros primitivos
dentro dele; essas operaes primitivas sero realizadas na ordem em que so definidas, de cima para
baixo.

Aqui est um exemplo da sintaxe do elemento <filter>:

<filter id="F">
<anyParticularPrimitive1>
<anyParticularPrimitive2>
...
<anyParticularPrimitiveN>
</filter>
<anyParticularSVGObjectOrGroup filter="url(#F)"/>

O captulo comea com alguns exemplos usando a mais simples das primitivas de filtro,
<feColorMatrix> e <feGaussianBlur>, para dar uma ilustrao dos tipos de coisas que voc pode realizar.
As primitivas bsicas

Na especificao SVG, a discusso sobre as primitivas de filtro enumera 16 diferentes primitivas de


filtros ordenados alfabeticamente. Como o assunto complexo, este livro vai tentar trazer um pouco
mais de organizao para o assunto, embora claramente a especificao fornea consideravelmente mais
detalhe (mas menos exemplos). O tratamento comea com essas primitivas que borram, distorcem ou
alteram as cores de contedo relativamente simples ao qual aplicado o filtro.

<FeGaussianBlur>

Talvez o mais simples dos filtros primitivos SVG. Quando colocada simplesmente, permite desfocar
uma imagem. Este tratamento adaptado da cartilha do W3C, simplesmente porque eu acho que a
melhor maneira de abrir o tpico de filtros SVG.
O parmetro associado com <feGaussianBlur> o desvio padro (desvioPadro). Ele controla a
distncia a partir do qual ir ser permitido pixels vizinhos para influenciar um dado pixel, e, portanto,
a quantidade de desfoque. Primeiro, voc configura um filtro com um <feGaussianBlur> dentro:

<filter id="A">
<feGaussianBlur stdDeviation="1" />
</filter>
Ento voc aplica o filtro ao elemento:
<rect x="42%" y="10%" width="16%" height="25%" fill="white" filter="url(#A)"/>

A seguir mostramos o efeito de aumentar o valor de "stdDeviation" em duas imagens diferentes em um


fundo preto:

<image x="42%" y="10%" width="16%" height="25%" filter="url(#A)" xlink:href="p0.jpg"/>

Observe que o objeto turvo se expande para alm de seus limites originais e que os valores fora do seu
limite so considerados transparentes, de modo que todo o fundo actual (neste caso, monocromtico
preto) sero visveis no interior das bordas da imagem em si. Para restringir a imagem de modo que no
faa sangrar alm dos seus limites, voc pode definir o x, y, altura e largura atributos do prprio filtro (A
maneira mais fcil), ou utilizar outra primitiva de filtro, <feOffset> (discutido mais adiante neste
captulo).
O que se segue um exemplo de restringir a extenso de um filtro para o tamanho da imagem de
origem:

<filter id="A" x="0%" y="0%" width="100%" height="100%">


<feGaussianBlur stdDeviation="25"/>
</filter>

Tambm vale a pena notar que, se <feGaussianBlur> tem dois parmetros, ao invs de um, para o seu
atributo "stdDeviation", em seguida, o primeiro ir representar borro horizontal, enquanto o segundo
ir representar borro vertical. A declarao
<feGaussianBlur id="fGB" stdDeviation="25, 0" />
vai borrar o objeto apenas horizontalmente de forma que, para um retngulo monocromtico, pode se
assemelhar a um gradiente linear com trs pontos equidistantes.

<feColorMatrix>

O filtro primitivo <feColorMatrix> permite reconfigurar as cores de uma imagem. No caso mais
simples, voc pode us-lo para remover a saturao de uma imagem, ou seja, transform-lo de cor em
tons de cinza. No exemplo a seguir, uma imagem mapa de bits no filtrada exibida ao lado de uma
verso filtrada da mesma imagem:
<filter id="F">
<feColorMatrix type="saturate" values="0" />
</filter>
<image id="I" x="0" y="0" width="200" height="200" preserveAspectRatio="none" xlink:href="p17.jpg" />
<use xlink:href="#I" filter="url(#F)" transform="translate(200,0)" />

O filtro constitudo por uma operao <feColorMatrix>. Como um gradiente, padro, clip-path, ou
mscara, um filtro depois aplicado a outro elemento SVG, neste caso, um <use> - para que ento
possamos ver o que o objeto parece antes e depois de aplicar o filtro. Neste caso particular, a imagem
dessaturada de modo que , com efeito, convertida para uma imagem em tons de cinza. Note-se que
animar os valores de atributo deste exemplo muito fcil de fazer.

Atualmente no SVG1.1, a gama de valores de 0 a 1, mas parece que se permitir uma gama mais
ampla de valores, no futuro. Observe que, com pouco cdigo (reutiliza e reflete a imagem filtrada e no
filtrada abaixo dos originais, dentro de um padro), voc pode conseguir efeitos interessantes usando
apenas uma imagem bitmap e uma pequena quantidade de cdigo:

<filter id="F">
<feColorMatrix type="saturate" values="0" />
</filter>
<pattern id="Pix" patternUnits="userSpaceOnUse" width="200" height="200" >
<g id="g" transform="scale(.5)">
<image x="0" y="0" width="200" height="200" preserveAspectRatio="none" xlink:href="p17.jpg" />
<image x="200" y="0" width="200" height="200" preserveAspectRatio="none" xlink:href="p17.jpg"
filter="url(#F)"/>
</g>
<use xlink:href="#g" transform=" translate(200,100) scale(-1,1)"/>
</pattern>
<rect x="0" y="0" width="100%" height="100%" fill="url(#Pix)" />

Voc tambm pode usar <feColorMatrix> para girar os valores de cor (atravs da escala circular, que o
arco-ris de tons) usando "hueRotate":
<filter id="F">
<feColorMatrix type="hueRotate" values="90" />
</filter>
<filter id="G">
<feColorMatrix type="hueRotate" values="180" />
</filter>
<filter id="H">
<feColorMatrix type="hueRotate" values="270" />
</filter>
<image id="I" x="0" y="0" width="200" height="200" preserveAspectRatio="none" xlink:href="p17.jpg" />
<use xlink:href="#I" filter="url(#F)" transform="translate(200,0)" />
<use xlink:href="#I" filter="url(#G)" transform="translate(400,0)" />
<use xlink:href="#I" filter="url(#H)" transform="translate(600,0)" />

Na ilustrao acima, observe como o contraste de cor entre os lbios e a pele no parece to bem sob
rotao de matiz; isto porque em ltima anlise, os Cromas so muito semelhantes. No final desta
seo, vamos discutir brevemente como exagerar contrastes de cor sob rotao.

O filtro primitivo <feColorMatrix> um pouco mais potente, no exemplo mostrado abaixo:

Sem entrar em detalhes sobre a coleo inteira de efeitos, existem seis imagens de bitmap (faces) em
cima de trs listras coloridas. A primeira imagem, esquerda, no filtrada. Cada uma das outras tem
um filtro mais ou menos como a do terceiro:

<filter id="inv">
<feColorMatrix type="matrix"
values="1 0 0 0 0
0 -1 0 0 0
0 0 -1 0 0
1 1 1 0 0"
>
</feColorMatrix>
</filter>

O que isto faz pegar cada um dos quatro canais de cor, tratados como linhas da matriz vermelho,
verde, azul, e alfa (opacidade) e comp-lo fora dos valores de cores dos outros trs canais. Nesse caso,
o canal vermelho mantido inalterado:
Red = 1 * Red + 0 * G + 0 * B + 0 * A

Os canais de verde e azul so, no entanto, invertidos, com os seus novos valores de cor a serem definidos
iguais com o inverso do seu valor. Finalmente, o canal alfa contribudo positivamente pelos valores
vermelho, verde e azuis:
Alpha = 1 * Red + 1 * G + 1 * B

O efeito faz com que os pixels brilhantes (elevados em todos os trs canais) sejam mantidos opacos,
enquanto os pixels escuros (baixo em todos os trs canais) sejam convertidos para transparente. A ltima
coluna da matriz representa uma constante utilizada para ajustar o brilho de um canal, tipicamente para
escalar os valores de modo a que o resultado varie de 0 a 1, no entanto, no estritamente necessrio.

No exemplo acima, note que o filtro final usado realmente animado, o que demonstra que dois
atributos de valores mltiplos, como matrizes, podem ser interpolados usando <animate>.

Encadeamento de filtros com <feColorMatrix>

Vamos introduzir mais um tpico antes de passar para a prxima primitiva de filtro: a ideia de encadear
efeitos de filtro. Acima, um dos nossos filtros <feColorMatrix> conseguiu supersaturar uma imagem.
Note-se que no exemplo de "hueRotate", os valores de cor da imagem eram suficientemente
semelhantes de tal modo que quando os tons de uma imagem foram alternados ao longo do arco-ris, a
imagem azulada tornou-se uniformemente azulada. Voc pode ajustar isto enviando os resultados de
uma primitiva de filtro para outra. Considere este cdigo:

<filter id="F">
<feColorMatrix type="matrix"
values=" 3 -1 -1 0 0
-1 3 -1 0 0
-1 -1 3 0 0
0 0 0 1 0"
/>
<feColorMatrix type="hueRotate" values="30" />
</filter>

Neste filtro, temos encadeamos dois efeitos <feColorMatrix> diferentes. O resultado que, o primeiro
supersatura a imagem e, em seguida, gira as cores em 30 graus (do amarelo ao vermelho).

digno de nota que a ordem de aplicao dos filtros significativa. Neste caso, supersaturar antes de
girar os resultados de matiz em um efeito de teto no canal vermelho. Muitos pixels so deslocados para
seus mais altos valores de vermelho possveis. Girando em primeiro lugar e, em seguida, saturando (ver a
quinta ilustrao esquerda na imagem acima), voc pode preservar melhor o diferencial de tonalidade
entre os lbios e pele. Esta capacidade de encadear efeitos de filtro proporciona uma grande quantidade
de energia em como voc pode combinar vrios efeitos.

Os mesmos filtros aplicados em ordem inversa:

<FeComponentTransfer>

Enquanto <feColorMatrix> permite o remapeamento entre canais de cor, voc pode conseguir um
controle mais preciso de remapeamento dentro de um canal de cor individual usando
<feComponentTransfer>. O filtro primitivo <FeComponentTransfer> permite a redefinio
independente de cada um dos quatro canais de cor R, G, B e A. Ele permite o ajuste de brilho e
contraste atravs da aplicao de qualquer uma das diferentes funes a qualquer um ou a todos os
canais de uma imagem. Os tipos de ajustes permitidos incluem "identity", "table", "discrete", "linear", e
"gamma". "Discrete" pode ser usado para posterizar uma imagem (isto , a reduzi-la a menos valores de
cor). "Linear" usada para iluminao simples e escurecimento, ajuste de contraste, ou mesmo inverso,
enquanto a "table" pode ser usado para remapear histograma de uma cor como o "discrete", de forma
contnua. um filtro poderoso e pode motivar um tratamento muito mais profundo do que este
captulo permite, mas vamos considerar alguns da sua gama expressiva com alguns exemplos.

Um dos usos mais comuns desta primitiva de filtro provvel que seja a posterizao, ou discretizao
suave de outra maneira de uma funo de cor-densidade. O efeito, tambm conhecido como
quantizao de cor, resulta na utilizao de menos cores globais em uma imagem, geralmente com
fronteiras ntidas entre as reas onde a cor dominante.

Veja como ele funciona. Mostrado na figura a seguir, simplesmente o efeito do Posterizao de uma
imagem. A imagem no filtrada est no topo esquerda, e a outra, posterizada, imediatamente direita.
O filtro aplicado segunda imagem se parece com isso:

<filter id="G">
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 .5 1"/>
<feFuncG type="discrete" tableValues="0 1"/>
<feFuncB type="discrete" tableValues="0"/>
</feComponentTransfer>
</filter>

O que ele faz remapear o canal vermelho da imagem para que a nova imagem tenha apenas trs valores
de vermelho: 0, 127, e 255. Todos os valores que esto mais prximos a 127 so arredondados para 127,
com outros valores recebendo arredondamento, quer para cima, para 255 ou para baixo a 0. O canal
verde quantificado a exatamente dois valores, 255 e 0, e o canal de azul est completamente
enegrecido (ou branco).

A terceira imagem primeiro desfocada (reduo de algumas das descontinuidades ao longo da borda,
de forma eficaz alisando o efeito de pixels que so diferentes de seus arredores) antes da posterizao. Ao
canal verde dado trs valores em vez de dois (para dar-lhe um pouco mais de poder discriminante), e
o vermelho deslocado um pouco mais para cima para aumentar sutilezas na faixa inferior. Isto feito
dividindo a variao de 0 a 255 em quatro intervalos de classe e arredondamento que variam entre 0 a
65 para 0, de 66 a 127 para 127, e de 127-255 para 255, resultando em um vermelho lquido da
imagem. Isto , utilizando o seguinte cdigo, esta opo mapeia os valores de vermelho no intervalo
[0,1] para um dos trs valores como segue:
(de 0 at .25) 0; (de .25 at .50) .5; (de .50 at .75 e de .75 at 1.0) 1

<filter id="H">
<feGaussianBlur stdDeviation="3" />
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 .5 1 1"/>
<feFuncG type="discrete" tableValues="0 .5 1"/>
<feFuncB type="discrete" tableValues="0"/>
</feComponentTransfer>
</filter>

Ou seja, voc pode usar <feComponentTransfer> para fazer um pouco de equalizao manual. A
imagem inferior esquerda usa um conjunto bastante simples de transformaes:

<filter id="F">
<feComponentTransfer>
<feFuncR type="table" tableValues="1 0 0"/>
<feFuncB type="table" tableValues="0"/>
<feFuncA type="table" tableValues=".75"/>
</feComponentTransfer>
</filter>

Ele efetivamente inverte o canal vermelho, mapeando dois teros dos valores de vermelho para o escuro
e o mais escuro um tero (neste canal) para brilhante. O canal verde deixado inalterado, e o canal de
azul (apenas presente na imagem original para comear) completamente suprimido (escurecido). No
outro lado, todos os valores alfa (que so 1,0, para comear, uma vez que esta uma imagem opaca) so
feitos ligeiramente transparentes mapeando alfa para 0,75.

As outras duas imagens, o cdigo-fonte da qual voc pode examinar na pgina da web, faz um pouco
mais do que jogar com o atributo "discrete", com a ltima imagem, adicionalmente, usando o
feColorMatrix> reformular apenas alguns dos pixels (o mais amarelos) para transparente. Esta
capacidade de, seletivamente fazer certos pixels transparentes, no algo que <feComponentTransfer>
tenha por si prprio, uma vez que s funciona com um canal de cada vez. Utilizado em conjunto com
<feColorMatrix>, porm, voc pode produzir alguns resultados bastante interessantes.

Outros atributos de <feComponentTransfer> incluem "identity", "table", "linear", e "gamma".


"identity" parece ser o filtro nulo, deixando intacto o seu canal; "gamma" ajusta a curvinilearidade do
canal; "table" permite o remapeamento dos valores de cores especficas (como em uma distribuio de
cores j discretizada); "linear" vale a pena um pouco de mais destaque.

Assim como o valor "discrete" estabelece limites onde as fronteiras entre um canal quantificado de
valores mapeiam uma direo ou outra, "linear" permite variar a inclinao da funo que transforma
pixels originais para novos em um canal selecionado.

Voc pode usar isso para realmente inverter uma imagem (girando cada um de seus canais de cor de
cabea para baixo), como mostrado abaixo:
O cdigo para fazer isso emprega uma nova ideia: uma ligeira alterao no espao de cores do padro
RGB, espao de cor usado em SVG, para sRGB. Este espao de cor alternativo ajusta a configurao de
gama de uma forma bastante extravagante que mapeia as cores semelhantes em ambos os dispositivos,
impressoras e monitores. O cdigo usado parece com isso:

<filter id="J" color-interpolation-filters="sRGB">


<feComponentTransfer>
<feFuncR type="linear" slope="-1" intercept="1" />
<feFuncG type="linear" slope="-1" intercept="1" />
<feFuncB type="linear" slope="-1" intercept="1" />
</feComponentTransfer>
</filter>

Como voc pode ver, ns simplesmente traamos uma linha de (0,1) para (1,0) em vez do habitual (0,0)
para (1,1), da invertendo os valores em cada canal.

Enquanto a imagem resultante pode no ser exatamente igual ao negativo fotogrfico, Eu realizei o
seguinte teste: As duas imagens foram tomadas em Adobe Photoshop. A imagem esquerda foi colada
em cima do outro direita, com uma opacidade de 50% aplicado camada colada. O resultado foi uma
regio cinzenta aparentemente monocromtica (pelo menos a olho nu). Aps a equalizao da rea,
diferenas sutis apareceram, mas estes eram provavelmente apenas artefatos de processamento do
navegador. Em outras palavras, o resultado visualmente indistinguvel de um negativo fotogrfico!

Quando o tipo igual a "table", semelhante ao "discrete", s que em vez de apertar os valores no
intervalo de classe para o valor especificado, os valores so linearmente interpolados em intervalos de
classe adjacentes; assim, em vez de discretizao, "table" cria transformaes lineares por partes, como as
funes "sawtooth". Voc pode ver o contraste entre type = "discreta" e type = "table" no exemplo a
seguir, em que uma funo "sawtooth" aplicado tanto discretamente como por partes linearmente, no
canal azul.

Aqui est um exemplo final ilustrando algumas das riquezaa do <feComponentTransfer> (usado aqui
como apoio ao <feGaussianBlur> e <feColorMatrix>).

Ele comea com um <feGaussianBlur> (animado em desvioPadro) para variar a granularidade das
bordas. Ele usa uma funo discreta para quantificar o canal dominante, vermelho. Em seguida, ele usa
um ajuste linear para animar os canais azul e verde. Finalmente, ele usa um <feColorMatrix> para
converter pixels brilhantes em transparentes. Desde o declive das funes em azul e verde est oscilando
(em diferentes frequncias), isso significa que os pixels que so transparentes mudam com o tempo.
Vrios tipos de tela so mostrados aqui:

<FeMorphology>

<FeMorphology> normalmente usado como uma parte do canal alfa de uma imagem para diluir ou
engrossar uma imagem. O W3C d um exemplo no qual um tipo de letra em negrito feita mais fina,
embora com o uso de um filtro <FeMorphology>.

No exemplo a seguir voc pode ver os efeitos de animao dos dois tipos possveis de <feMorphology>:
"dilate" e "erode". Quando aplicado a uma rea que tem alguma transparncia nele, ele pode expandir
(dilate) ou diminuir (erode) a regio afetada.

O exemplo comea atravs da utilizao de <FeComponentTransfer> e <feColorMatrix> para converter


uma parte da imagem para transparente. A dilatao morfolgica , ento, animada para expandir
lentamente a regio transparente, deslocando outros valores de pixels em sua esteira.

<FeConvolveMatrix>

Este um efeito de filtro poderoso mas complexo, bem conhecido no processamento de imagem
cientfica, uma vez que muitas vezes usado para afiar as imagens, ou para a deteco de limite. Ele
permite o que conhecido como um filtro de convoluo (convolution filter). Para us-lo, voc define
uma matriz quadrada (tipicamente n n para algum nmero mpar n) em que a clula central da matriz
refere-se ao pixel propriamente dito; e as clulas acima, esquerda, abaixo e direita, dentro da matriz
se referem aos pixels de cima, esquerda, em baixo, e para a direita do referido pixel da imagem fonte.
Os coeficientes numricos na matriz definem o peso que cada pixel vizinho ter para o clculo do novo
valor de cor daquele pixel. No caso mais simples, a matriz
deixa qualquer imagem afetada, uma vez que o novo valor de um pixel ser igual a 1 vezes o seu valor
atual mais a soma dos 0 vezes os valores de seus oito vizinhos mais prximos (aqueles imediatamente
norte, nordeste, a leste, sudeste, sul, sudoeste, oeste e noroeste do mesmo). Isto , cada pixel no
afetado pelos seus vizinhos.

Em uma convoluo ligeiramente diferente, voc pode aperfeioar uma imagem permitindo que cada
pixel seja influenciado negativamente por seus oito vizinhos, mas ainda mantendo a sua prpria
identidade:

<feConvolveMatrix order="3" kernelMatrix=


" -1 -1 -1
-1 9 -1
-1 -1 -1
" />

Note-se que a soma dos coeficientes 1, ou seja, geralmente, que os valores do brilho geral de
o resultado (em cada canal) ser aproximadamente a mesma que o original. Em geral, voc quer evitar
a soma dos coeficientes de ser 0.

Aqui est outro exemplo que pode ajudar a explicar como esses efeitos funcionam. Para conseguir um
efeito um pouco como desfoque vertical, voc pode usar um filtro tal como se segue. Nisso, cada pixel
melhorado se semelhante aos pixels na sua mesma "listra" vertical, mas tambm ele se agua um pouco
se diferir de pixels mais sua esquerda ou sua direita.

<filter id="G">
<feConvolveMatrix order="7" kernelMatrix="
-1 0 0 2 0 0 -1
-1 0 0 2 0 0 -1
-1 0 0 2 0 0 -1
-1 0 0 3 0 0 -1
-1 0 0 2 0 0 -1
-1 0 0 2 0 0 -1
-1 0 0 2 0 0 -1
" />
</filter>

O resultado ilustrado na imagem central abaixo e contrastado com o efeito do uso simples de efeitos
<feGaussianBlur> verticais. Note que a imagem complicada, enquanto verticalmente desfocada, feito
de modo muito mais claro do que com o uso do filtro de desfoque mais simples, que espalha valores de
pixel. Isto , a nitidez das formas sugere um efeito mais discreta e menos anlogo, o que em grande
medida consistente com a natureza da filosofia subjacente dos clculos.
Filtros de utilidade

Um nmero de primitivas de filtragem servem apenas para fornecer algum tipo de funcionalidade
necessria, mas seria raro ser usado sozinho. Por exemplo, alguns podem introduzir algum tipo de
imagem bsica em uma cadeia de filtros. O mais importante deles so <feTurbulence>,
<feDiffuseLighting> e <feSpecularLighting>. Alguns outros, <feFlood>, <feImage>, <feTile> e
<feOffset>, fornecem operaes rudimentares que so teis dentro da cadeia de filtros. A apresentao
comear com cuidado, e construir mais complexidade gradualmente.

Filtros de utilidades simples

Os filtros de utilidade simples permitem maneiras para inserir coisas em uma cadeia de filtros. Cada um
dos filtros de utilidade permite algo a ser inserido na cadeia de filtros atravs do que chamaremos "R",
que se refere ao retngulo subtendido pelo filtro, atravs de suas prprias propriedades (x, y, largura e
altura), ou atravs da geometria do objeto ao qual ela aplicada.

<feFlood> entra em uma nica cor em R.


<feOffset> permite que algo de uma cadeia de filtro seja movido na horizontal e na vertical.
<feImage> entra um arquivo externo ou imagem local (bitmap ou SVG) em R.
<feTile> permite uma imagem de entrada em uma cadeia de filtro para ladrilho R como um padro.

<feFlood> e <feOffset>

No exemplo, as duas imagens na linha superior mostram os efeitos da aplicao de <feFlood>, neste caso
depositados sobre qualquer retngulo, preenchido ou no.

<filter id="f1">
<feFlood x="10%" y="10%" width="80%" height="80%" flood-color="green" flood-opacity=".5"/>
</filter>
<rect x="15%" y="15%" width="20%" height="30%" fill="none" stroke-width="2" stroke="blue"/>
<rect x="15%" y="15%" width="20%" height="30%" filter="url(#f1)"/>
<rect x="60%" y="15%" width="20%" height="30%" fill="red" stroke-width="2" stroke="blue"/>
<rect x="60%" y="15%" width="20%" height="30%" filter="url(#f1)"/>
A vantagem disso que voc pode, portanto, usar um filtro que se aplica um pouco de verde no topo de
qualquer outro grfico que voc tenha, utilizando o mesmo filtro onde for desejado. Note-se que o
efeito do filtro (como muitos outros) sangra fora do retngulo do grfico no qual ele aplicado. Como
discutido anteriormente neste captulo, porm, voc pode restringir isso definindo as propriedades X, Y,
altura e largura do prprio filtro.
Observe tambm que a aplicao de "flood-opacity" deixa o contedo subjacente visvel atravs do
efeito de filtro, e, como se ver mais tarde, ajustar as opacidades individuais de vrios filtros <feFlood>
no mesmo filtro, pode revelar-se bastante til.

Os dois exemplos direita nesta ilustrao usa <offset> em conjunto com <feFlood> deslizando o efeito
alguns pixels sobre e para baixo.

<filter id="f2">
<feFlood x="10%" y="10%" width="80%" height="80%" flood-color="green" flood-opacity=".5"/>
<feOffset dx="40" dy="25"/>
</filter>
<rect x="15%" y="55%" width="20%" height="30%" fill="none" stroke-width="2" stroke="blue"/>
<rect x="15%" y="55%" width="20%" height="30%" filter="url(#f2)"/>
<rect x="60%" y="55%" width="20%" height="30%" fill="red" stroke-width="2" stroke="blue"/>
<rect x="60%" y="55%" width="20%" height="30%" filter="url(#f2)"/>

<FeOffset> frequentemente usado para criar sombras, como mostrado abaixo (neste caso usando
Gaussian Blur para a sombra e algo chamado <feMergeNode>, que ser discutido mais tarde, para
recombinar os resultados de diferentes primitivos).

<FeImage> e <feTile>

Em cada um dos dois exemplos um retngulo filtrado usando <feImage>, que permite a insero de
uma imagem externa (ou interna) para a corrente do filtro. A segunda instncia da imagem ento
passada para um filtro <feTile>, que funciona um pouco como <pattern>, mas dentro de uma cadeia de
filtros.
No primeiro caso (mostrada esquerda no grfico em baixo), em vez de um retngulo, simplesmente
filtrado enquanto uma imagem bitmap introduzida:

<filter id="f1" primitiveUnits="objectBoundingBox">


<feImage xlink:href="p84.jpg" preserveAspectRatio="none"/>
</filter>
<rect x="10%" y="10%" width="20%" height="30%" filter="url(#f1)" />

No segundo caso, tomamos os resultados do <feImage> e colocamos em um <feTile>, que permite que
o contedo seja ladrilhado como em um elemento <pattern>:

<filter id="f2" primitiveUnits="objectBoundingBox">


<feImage xlink:href="p84.jpg" x="0" y="0" width="25%" height="50%" preserveAspectRatio="none"/>
<feTile/>
</filter>

Neste caso, <feTile> vai fazer quatro cpias da imagem horizontalmente e dois verticalmente por causa
da forma como os atributos de largura e altura foram definidos em <feImage>. O contorno do retngulo
azul mostra o seu tamanho original do retngulo antes de filtrar.

<FeTile> uma primitiva bastante simples que se estende apenas ao contedo para preencher 100 por
cento da rea a ser preenchida. A sua convenincia que ele pode ser facilmente inserido numa cadeia
de filtros e que os clculos do tamanho do espao padro no precisam ser calculados manualmente,
como frequentemente o caso do elemento <pattern>.

<FeTurbulence>

<FeTurbulence> um dos mais expressivos e complexos das primitivas de filtro. utilizado, muitas
vezes em conjunto com outros, para criar texturas e teias que envolvem formas randmicas.

Da especificao do SVG 1.1 do W3C, ns achamos que ele "cria uma imagem usando a funo
turbulncia Perlin. Ele permite a sntese de texturas artificiais, como nuvens ou mrmore."

Como o filtro <feFlood>, <feTurbulence> preenche um retngulo com o novo contedo. Tem cinco
atributos especficos: "baseFrequency" (obrigatrio), "numOctaves", "seed", "stitchTiles", e "type". No
caso mais simples, utilizado como se segue:
<filter id="T1">
<feTurbulence baseFrequency=".04"/>
</filter>
<rect x="30" y="10" height="100" width="100" filter="url(#T1)"/>
Um exemplo mais popular da sintaxe mostrado aqui:
<filter id="T2">
<feTurbulence baseFrequency=".01" type="fractalNoise" numOctaves="3" seed="23" stitchTiles="stitch" />
</filter>
<rect x="30" y="10" height="100" width="100" filter="url(#T2)"/>

Os parmetros que regem <feTurbulence> so cada um no valor da explicao, por isso vamos discuti-
los em seguida.

baseFrequency

O mais importante dos parmetros, "baseFrequency", controla a escala ou a frequncia do rudo.


Nmeros maiores (se aproximando 1) resultam em um gro mais apertado, enquanto que os nmeros
menores (aproximando 0) resultam texturas grosseiras de gros maiores. Tal como acontece com
<feGaussianBlur>, voc pode controlar tanto os componentes horizontais e verticais de <feTurbulence>.
Aqui esto quatro exemplos em que, por type = "fractalNoise", os valores de "baseFrequency" foram
variados.

Note-se que no ltimo exemplo, um valor mais baixo para "baseFrequency" foi fornecido na direo
horizontal, o que significa que a frequncia superior nessa direo, o que resulta no aparecimento de
riscos horizontais.

numOctaves

Variaes na "numOctaves" essencialmente ajustam a quantidade de detalhes presentes na textura.


Apenas nmeros inteiros so permitidos, e na maioria dos casos, mais de trs oitavas de turbulncia (ou
gros de rudo) no aumenta o grau de complexidade visual do filtro. Geralmente, dependendo da
utilizao, uma ou duas oitavas de turbulncia ser suficiente para a maioria dos cenrios.
Type

H apenas dois valores para o type: "turbulence" e "fractalNoise". O valor padro "turbulence". A
diferena visual principalmente que "turbulence" parece fibroso e "fractalNoise" parece nublado. Voc
pode ver o contraste na figura abaixo.

Seed

<FeTurbulence> aceita um valor de "seed" que permite que diferentes cenas de mesmas caractersticas
sejam geradas de instncia para instncia. No exemplo mostrado abaixo, quatro retngulos adjacentes na
linha superior so preenchidos com "turbulence" que tem o mesmo valor de "seed". Note como todos
os quatro retngulos adjacentes no tm linha de juno. A linha de fundo, por outro lado, tem quatro
diferentes valores de "seed", e as junes entre os quatro ladrilhos so claramente visveis (uma vez que o
contraste foi melhorado e a transparncia eliminada para tornar o efeito mais bvio).

Como mostrado no exemplo acima, voc pode criar novos tipos de texturas, filtrando ainda mais os
resultados de <feTurbulence>. Vamos apresentar alguns outros exemplos disso, juntamente com algumas
idias sobre como criar texturas de qualidade. A seguir um exemplo de "turbulence" a partir do qual o
canal de transparncia foi efetivamente removido (por valores de mapeamento alfa em todos os lugares a
1,0).

A descrio acima criada, como segue:

<filter id="Q" x="0" y="0" height="100%" width="100%">


<feTurbulence baseFrequency=".01" numOctaves="1" />
<feComponentTransfer>
<feFuncA type='linear' intercept="1" slope='0' />
</feComponentTransfer>
</filter>
<rect x="15%" y="15%" height="70%" width="70%" filter="url(#Q)"/>

Agora, ao mesmo tempo que fcil variar o padro especfico apresentado neste retngulo, alterando o
valor de "seed", no to fcil de simplesmente mover o padro ao redor. Para tornar este ponto mais
claro, considere o o exemplo seguinte:

Este exemplo mostra cinco posies de um nico retngulo filtrado (como no exemplo anterior) como a
sua localizao muda atravs de uma animao. Note como os retngulos que se sobrepem
compartilham o mesmo padro. como se o retngulo fosse uma janela, movendo-se atravs de um
espao infinito preenchido com turbulncia.

O retngulo animado como se segue:


<rect x="40%" y="40%" height="20%" width="20%" filter="url(#T1)">
<animate attributeName="x" values="10%;60%;70%;10%" dur="5s" repeatCount="indefinite" />
<animate attributeName="y" values="70%;10%;30%;60%;70%" dur="7s" repeatCount="indefinite" />
</rect>

Este exemplo ilustra que <feTurbulence> definida em relao s coordenadas absolutas. O padro no
se move com o objeto que foi filtrado com ele! Isso pode criar tanto obstculos como oportunidades,
dependendo de como voc olha para ele e o que voc quer realizar. Mas deve causar alguma reflexo de
como voc pode usar a turbulncia para animar certos tipos de coisas, tais como nuvens, fogo, gua,
chuva, bolhas, e fumaa. Em caso de movimento do fluido, voc vai querer a turbulncia "flow" de
forma contnua numa determinada direo.

Uma abordagem que tem sido em torno desde os primeiros dias de animao SVG (usado na cintilao
de vela da Zona SVG da Adobe) parece resolver este problema de forma bastante eficiente. Uma vez que
a turbulncia no pode facilmente ser movida por meio de um retngulo, a abordagem funciona como
se segue:

<g filter="url(#Q)">
<animateTransform attributeName="transform" type="translate" from="0 0" to="0 -20000" dur="200"
repeatCount="indefinite"/>
<rect x="25%" y="25%" height="50%" width="50%"/>
<animateTransform attributeName="transform" type="translate" from="0 0" to="0 20000" dur="200"
repeatCount="indefinite"/>
</rect>
</g>

Essencialmente, neste exemplo arrasta o retngulo com a mesma velocidade em dois sentidos opostos,
com o efeito lquido que deixado parado. A razo porque ele funciona dessa maneira que o <g>, que
filtrado, quando arrastado, traz ambos os filtros, da regio e <rect> com ele, mas apenas o <rect>
retransformado, com o aparecimento do lquido s na regio do filtro (e por isso o padro) parece se
mover. Este efeito usado duas vezes na figura mostrada abaixo animando separadamente duas camadas
diferentes de nuvens em velocidades diferentes.

Da mesma forma, utilizando duas camadas de turbulncia, juntamente com os efeitos de iluminao
(discutido na prxima seo), permite o aparecimento de um viaduto e de uma lua distante.
Esta seo termina com uma variedade de efeitos usando turbulncia, e descreve algumas das formas que
a turbulncia pode ser usada em combinao com outros efeitos de filtro para criar uma variedade de
intrigantes texturas.

No exemplo abaixo voc pode ver quatro diferentes efeitos criados por ajustamento do croma de
turbulncia usando <feColorMatrix> e / ou <feComponentTransfer>.

No efeito do exemplo na parte superior esquerda, a transparncia da turbulncia, bem como os canais
de verde e azul so simplesmente eliminados, como se segue:
<filter id="T1" x="0" y="0" height="100%" width="100%">
<feTurbulence baseFrequency=".015" numOctaves="1" />
<feComponentTransfer>
<feFuncA type="linear" intercept="1" slope='0' />
<feFuncG type="linear" intercept="0" slope='0' />
<feFuncB type="linear" intercept="0" slope='0' />
</feComponentTransfer>
</filter>

Este semelhante ao efeito na parte inferior direita, que elimina os canais de verde, azul, e alfa atravs
de um <feColorMatrix>:
<feColorMatrix type="matrix"
values="1 0 0 1 0
00000
00000
0 0 0 0 1">
</feColorMatrix>

O efeito no canto inferior esquerdo mostra o que acontece se, mais uma vez, os canais azul e alfa so
eliminados, mas se os canais vermelho e verde so discretizados (mapeamento de intervalo mdio de
vermelho ou verde para valores altos e eliminando baixos valores atravs do <feComponentTransfer>):

<feFuncR type="table" tableValues="0 0 1 1 1 1 1 1 1 1 1"/>


<feFuncG type="table" tableValues="0 0 1 1 1 1 1 1 1"/>

Finalmente, o mais complexo dos exemplos, no canto superior direito, tem os seus azul, verde, e canais
alfa removidos como antes, e tem o seu canal vermelho discretamente mapeado; no entanto, neste caso,
transformado nonmonotonically, de modo que muito baixa, mdia, e elevados valores de vermelho so
eliminados, mas os valores baixos so intensificados.

<feFuncR type="table" tableValues="0 0 .5 1 .5 0 0 0 0 0 0 0 "/>

O resultado que as "ilhas" vermelhos tm buracos esculpidos neles.


Nos exemplos mostrados na figura a seguir, estes conceitos so explorados um pouco mais.

O exemplo no canto superior esquerdo leva turbulncia e, mais uma vez, ajusta o croma:

<feTurbulence baseFrequency=".019,.06" numOctaves="1"/>


<feComponentTransfer>
<feFuncA type="linear" intercept="1" slope='0' />
<feFuncR type="linear" intercept="0" slope='.1' />
<feFuncG type="linear" intercept="0" slope='.4' />
<feFuncB type="linear" intercept="0" slope='.9' />
</feComponentTransfer>

Especificamente, aps a eliminao da transparncia (definindo os valores alfa a 1), em vez de eliminar
dois dos canais, o canal vermelho severamente atenuado, e o canal verde parcialmente atenuado.
O resultado uma textura que lembra vagamente a gua. No exemplo na parte superior direita, o canal
azul discretizado, tanto como no exemplo "ilhas" discutido acima, assim:

<feFuncB type="table" tableValues="0 0 0 1 1 0 0 0 0 0 0 0 "/>

Em seguida, os limites dos pseudo glifos (ilhas com buracos) so suavizados, pela primeiro "blur" e
em seguida, "sharpen":
<feGaussianBlur stdDeviation="3"/>
<feConvolveMatrix order="5" kernelMatrix="
11111
1 -2 -2 -2 1
1 -2 -.2 -2 1
1 -2 -2 -2 1
11111
"/>

Voc pode querer experimentar mudar o nmero de oitavas para um ou trs (de dois) neste exemplo,
para ver como a complexidade das formas pode ser aumentada ou diminuda em conformidade. No
canto inferior direito, o exemplo funciona da mesma maneira como os "pseudoglyphs" azuis. As
diferenas so que as bordas exteriores das ilhas (os tons mais escuros de azul) so transformados em azul
e o interior das peas ficou verde. Isto realizado como se segue:

<feComponentTransfer>
<feFuncA type="linear" intercept="1" slope='0' />
<feFuncB type="table" tableValues="0 0 .5 1 1 0 .5 .5 0 0 0 0 "/>
</feComponentTransfer>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values=" 0 0 0 0 0
00100
0 0 2 0 -1
0 0 0 1 0"
/>

Especificamente, <feComponentTransfer> utilizado para fazer o canal de azul bimodal , com modos
em 4/13 e 7/13 do caminho entre os 13 intervalos estabelecidos pelos 12 valores da tabela. Ento
<feColorMatrix> usada para eliminar o canal vermelho (que tambm poderia ter sido utilizado para
eliminar o canal alfa, portanto, poupando o uso anterior do <feFuncA>). O canal azul preservado, mas
bifurcado em azul e verde. Isto , no resultado, ambos os pixels que possuem valores altos e baixos de
azul sero transformados em verde; apenas aos que possuem altos valores de azul ser feito tanto azul
quanto verde, ou seja, ciano.
O final destes quatro efeitos (na parte inferior direita) realizado da seguinte forma:
<feTurbulence baseFrequency=".08 .03" numOctaves="1" />
<feColorMatrix type="matrix" values=".5 .5 0 0 .1
.4 .5 0 0 -.1
00000
0 0 0 0 1"
></feColorMatrix>
<feGaussianBlur stdDeviation="1 2"/>
<feConvolveMatrix order="5" kernelMatrix=" 1 1 1 1 1
1 -2 -2 -2 1
1 -2 -.7 -2 1
1 -2 -2 -2 1
1 1 1 1 1"
/>
<feComponentTransfer>
<feFuncG type="linear" intercept="-.5" slope='1' />
</feComponentTransfer>

Neste cdigo, vrias coisas acontecem:

1. baseFrequency = ". 08 0,03" usado para fazer a frequncia mais elevada na direo horizontal.

2. <feColorMatrix> sucede pela primeira vez eliminando azul e alfa, e, em seguida, unindo em conjunto
(um pouco) dos canais de verde e vermelho, de modo que o resultado predominantemente laranja,
mas com um pouco de independncia do verde da vermelhido do vermelho e um pouco mais forte do
que o verdor.

3. Ns borramos, um pouco mais verticalmente do que horizontalmente, e, em seguida, aplicamos uma


ligeira nitidez, para melhorar as bordas escuras ao redor dos gros.

4. Finalmente, o canal verde ainda atenuado para deslocar a imagem mais para vermelho e distanciar
do amarelo, utilizando um efeito de transferncia de componente. Este ltimo efeito poderia, talvez, ter
sido realizado dentro do <feColorMatrix>, mas um pouco de agitao com os valores no teve sucesso,
ento eu apenas tampei como um efeito colateral.
A seguir, vamos explorar uma srie de exemplos envolvendo a criao de uma textura de madeira:

O primeiro desses exemplos (canto superior esquerdo) prossegue simplesmente com base em exemplos
anteriores:

<feTurbulence baseFrequency=".007,.15" numOctaves="2" />


<feComponentTransfer>
<feFuncR type="linear" intercept="-.1" slope="1"/>
<feFuncG type="linear" intercept="-.05" slope=".2"/>
<feFuncB type="linear" intercept="0" slope="0"/>
<feFuncA type="linear" intercept="1"/>
</feComponentTransfer>

Isto , as altas frequncias so usadas no sentido vertical, o que resulta num gro horizontal. Os canais
azul e alfa so eliminados; enquanto o verde consideravelmente atenuado. Isto d um gro plausvel e
gama de colorao.
O segundo exemplo (canto superior direito) mostra que <feColorMatrix> pode render controle mais
preciso sobre a colorao:

<feTurbulence baseFrequency=".007,.15" numOctaves="2" />


<feColorMatrix type="matrix" values=" 1.2 0 0 0 -.1
.05 .03 0 0 0
0 0 .02 0 0
00001
"/>

Neste exemplo, o vermelho de novo enfatizado mais que o verde, mas em vez de os dois serem
independentes, como na turbulncia no transformados, um pouco de co-variao introduzido,
permitindo que o canal verde seja ser influenciado por ambos vermelho e verde. O azul no enfatizado
e a transparncia eliminado.

As terceira e quarta ilustraes (linha inferior) ambas so conceitos de uso desenvolvidos na seo
seguinte: a introduo de novos tpicos em uma cadeia de filtros que so depois recombinados. Vamos
ainda articular estes conceitos em seguida, mas por agora, sabemos que em ambos os exemplos, um
filtro <feFlood> usado para introduzir uma cor em particular (neste caso um castanho avermelhado)
para dentro do filtro, o qual ento utilizado como o fundo da textura. No segundo, outro filtro,
<feDisplacementMap>, usado para distorcer o gro utilizando contudo uma outra fonte de
turbulncia para definir a distoro.

Finalmente, o exemplo a seguir mostra o efeito da concorrente variao de <feBaseFrequency> e o


croma de uma textura aplicada a um padro que se tem um espao de padres de animao:

Efeitos de iluminao

Dois filtros bastante complexos envolvem efeitos de iluminao: <feDiffuseLighting> e


<feSpecularLighting>. Ambos so bastante semelhantes, em alguns aspectos, a <feConvolveMatrix> e
<feGaussianBlur>, na medida em que permitem efeitos direcionais. Isto , eles permitem que pixels
sejam influenciados pelos seus vizinhos em certas direes. No caso destes efeitos de luz, que primeiro
convertem uma imagem binria em preto e branco, e ento ns fingimos que estes tons representam
elevaes e que uma sombra projetada em todo os contornos resultantes. O que varia o tipo e
posicionamento da fonte de luz. Efeitos de iluminao so frequentemente usados em conjunto com
outros filtros para criar efeitos mais complexos. Basicamente, existem filtros de efeitos difusos e
especulares no qual voc pode colocar um conjunto de luzes.

Vamos apresentar algumas experincias com <feDiffuseLighting> em primeiro lugar, com um link para
um exemplo de animao que revela os efeitos da variao simultnea de vrios parmetros associados
com efeito de iluminao.

No exemplo a seguir, vrios tipos diferentes de luzes so colocado em um elemento <feDiffuseLighting>


(com uma <feSpecularLighting> usada pela ltima vez).

Nestes exemplos, o mesmo padro colorido que foi utilizado no exemplo anterior (envolvendo
<FeConvolveMatrix>) reutilizado nove vezes, cada uma com um efeito de iluminao ligeiramente
diferente. Cada uma das trs luzes de base colocada no interior da primitiva de filtro, utilizando tanto
<feDiffuseLighting> ou <FeSpecularLighting>. Vamos mostrar o efeito mdio ("middle PointLight
left") com algum detalhe e deixar a inspeo dos outros para voc, se voc quiser explorar mais.

Aqui esto o filtro e o efeito no objeto (uma elipse preenchida com um padro tricromtico com um
fundo branco):

<filter id="pointLightB" filterUnits="objectBoundingBox" x="0" y="0" width="1" height="1">


<feDiffuseLighting in="SourceGraphic" diffuseConstant="1" surfaceScale="10" lighting-color="white">
<fePointLight x="40" y="50" z="10"/>
</feDiffuseLighting>
</filter>
<ellipse fill="url(#OvalPattern)" stroke="black" stroke-width="2" filter="url(#pointLightB)" cx="50%" cy="50%"
rx="10%" ry="10%"/>

Neste caso, voc pode imaginar que uma fonte de luz est localizada a 10 pixels acima do plano do
desenho e que cada elipse escura sobressai como uma pequena meia-esfera acima do plano. A luz emana
em todos a partir de um ponto situado a 10 unidades acima das coordenadas (40,50), com base em um
retngulo afetado pelo filtro (superior esquerdo sendo [0,0]). Voc pode, talvez, entender melhor o
efeito por animar o X, as posies Y e Z, como feito na imagem imediatamente direita (PointLight
animated).
Voc tambm pode modificar a cor da luz, embora se quiser duas luzes de cores diferentes, voc
teria que usar filtros diferentes no local.

Formas de combinar filtros

Existem vrias maneiras de combinar ou encadear dois ou mais efeitos de filtro. Voc j viu muitos
exemplos simples de encadeamento: tomar a sada de uma primitiva de filtro e us-la como uma entrada
para o prximo, dentro de uma tag compartilhada <filter>. Voc pode at criar diagramas de fluxo de
processamento de imagens verdadeiras com o mdulo de filtros SVG, permitindo a enorme variao e
sofisticao nos efeitos que podem ser produzidos.

Primeiro, considere a forma padro no qual filtros lidam com vrios efeitos. Normalmente, a primeira
primitiva dentro de um <filter> recebe como entrada o "SourceGraphic" o elemento ao qual o filtro
foi aplicado. Por exemplo, se definirmos
<rect filter="url(#Fs)" ... />

ento o retngulo considerado para ser o "SourceGraphic" do filtro "Fs". Cada primitiva em sucesso
(FP1, FP2,... FPk), toma a sada, ou resultado, a partir do filtro anterior, como se fosse a sua entrada.
Aqui vamos demonstrar duas abordagens equivalentes, a primeira das quais utiliza apenas valores
predefinidos dos atributos "in" e "result" de filtros sucessivos, enquanto o segundo faz com que todos os
valores padro sejam explcitos. No haveria razo para especificar os valores de "in" ou "result" no
exemplo a seguir, mas o exemplo pode ajudar a tornar mais claro o que se entende por "in" e "result" de
um filtro. Em ambos os casos, o filtro final a partir do qual a sada processada nos objetos grficos
afetados.

<filter id="Fs">
<FP1/>
<FP2/>
<FP3/>
<FP4/>
<FP5/>
</filter>

<filter id="Fs">
<FP1 in="SourceGraphic" result="A"/>
<FP2 in="A" result ="B" />
<FP3 in="B" result ="C" />
<FP4 in="C" result ="D" />
<FP5 in="D" />
</filter>

No exemplo acima, FPx refere-se a qualquer filtro de primitivas (por exemplo, <feGaussianBlur>). Uma
vez que voc sabe onde o "SourceGraphic" entra nos clculos e como os resultados so nomeados e
reutilizado, ento voc est em posio de iniciar variao da ordem e usar essas primitivas de filtro mais
complexas que combinam resultados de duas ou mais primitivas, por conseguinte, o encadeamento de
primitivas de filtro juntamente em formas mais complexas e interessantes.

SVG tambm d acesso ao contedo grfico abaixo de uma determinada imagem. Ou seja, voc pode
usar o estado processado das imagens na camada inferior do prprio objeto filtrado como parte do filtro.
Este permite combinaes de uma imagem com seu fundo usando tcnicas para a combinao de duas
imagens: <FeMergeNode>, <feBlend>, <feComposite> e <feDisplacementMap>. Vamos revisitar o uso
de BackgroundImage em breve.

<FeMergeNode>

O filtro <feMerge> permite que a combinao de filtros simultnea, em vez de em srie (como nos
exemplos anteriores). Em vez de cada filtro ser aplicado sada do filtro anterior, <feMerge> nos d uma
maneira de armazenar temporariamente a sada de cada filtro. Uma vez que vrias camadas foram
criadas e armazenadas como os resultados de diferentes primitivas, voc pode coloc-las na tela, em
ordem de baixo para cima. As camadas mais superficiais devem ter alguma transparncia (ou serem
incompletas) no preenchimento da rea para permitir que essas camadas abaixo sejam visveis.

No exemplo a seguir, estamos interessados na converso de uma imagem de padro RGB para
transparncia parcial, neste caso, utilizando as partes mais escuras da imagem de modo que uma cor
subjacente brilhe. Neste caso, estamos usando amarelo, criado atravs do <feFlood> como parte do
filtro.

O cdigo para a ilustrao acima mostrado a seguir:

<filter id="twoF" x="0%" y="0%" width="100%" height="100%">


<feFlood flood-color="yellow" result="A"/>
<feColorMatrix type="matrix" in="SourceGraphic" result="B"
values=" 1 0 0 0 0
01000
00100
11100
"/>
<feMerge>
<feMergeNode in="A"/>
<feMergeNode in="B"/>
</feMerge>
</filter>
<image x="35%" y="20%" xlink:href="p84.jpg" filter="url(#twoF)" height="50%" width="30%"/>

<FeFlood> inseriu um retngulo amarelo na corrente do filtro, mas mantido temporariamente em


memria como resultado A. Como antes, <feColorMatrix> usado para mapear partes escuras da
imagem para transparente (mantendo alpha elevado para valores brilhantes de vermelho, verde e azul); o
resultado armazenado em B. Finalmente, os dois efeitos so sobrepostos, como se empilhados, e o
resultado A comea sob o resultado B.

Para reforar a sua compreenso destes efeitos, importante ressaltar que o cdigo a seguir realiza
essencialmente o mesmo resultado.

<filter id="twoF" x="0%" y="0%" width="100%" height="100%">


<feFlood flood-color="yellow" result="A"/>
<feImage xlink:href="p84.jpg" preserveAspectRatio="none"/>
<feColorMatrix type="matrix" result="B"
values="1 0 0 0 0
01000
00100
11100
"/>
<feMerge>
<feMergeNode in="A"/>
<feMergeNode in="B"/>
</feMerge>
</filter>
<rect x="35%" y="20%" filter="url(#twoF)" height="50%" width="30%"/>

Aqui, em vez de filtrar uma <image>, ns filtramos um <rect>, inserindo a imagem no filtro atravs do
<FeImage>.

Dois outros exemplos demonstram formas alternativas de realizar a mesma coisa. No primeiro,
apresentamos um tipo de turbulncia em outro pelo estabelecimento de um retngulo que contm a
turbulncia parcialmente opaca em cima de outro retngulo preenchido com alta frequncia de
turbulncia. No segundo, ns realizamos este efeito com um nico filtro por camadas dos efeitos com
<feMergeNode>.

<FeBlend>

A primitiva <feBlend> permite a combinao de duas camadas de uma imagem usando os mtodos
"multiply", "darken", "screen", ou "lighten" similar aos utilizados em programas como o Adobe
Photoshop para combinar logicamente valores de cor de pixels coincidentes. O exemplo abaixo
demonstra esses quatro modos de compor uma imagem com o que se encontra por baixo.
Exceto para o valor do atributo modo, todos estes efeitos so os mesmos, por isso, ilustraremos somente
o exemplo "multiply" em detalhes.
O filtro em si relativamente simples:
<filter id="multiply" x="0" y="0" height="100%" width="100%">
<feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/>
</filter>

No entanto, o cdigo contm uma exceo significativa a utilizao de duas imagens de entrada: "in"
e "in2". Isso permite que o que est por baixo ou seja, as trs listras coloridas seja multiplicado pelo
"SourceGraphic". Inserindo o que est por baixo e definindo como BackgroundImage permite habilitar
o background em um elemento do grupo que contm os trs listras e a imagem filtrada:

<g habilitar-background = "new">


<Rect x = "0" y = "10%" height = "4%" width = "100%" preencher = "red" />
<Rect x = "0" y = "14%" height = largura "4%" = "100%" preencher = "green" />
<Rect x = "0" y = "18%" height = "4%" width = "100%" preencher = "blue" />
<Image x = "5%" y = "5%" xlink: href = filtro "p84.jpg" = "url (#multiply)" height = "23%" width = "15%"
preserveAspectRatio = "none" />
</g>

Portanto, qualquer contedo previsto antes do objeto filtrado no grupo com fundo habilitado ser
utilizado no clculo do <feBlend>. Note-se que uma vez que o filtro aplicado a uma imagem, o valor
padro de "in" est na verdade no "SourceGraphic", assim mencionando "in = SourceGraphic", como
acima, no estritamente necessrio.

Os modos de <feBlend> trabalham da seguinte forma:

"normal" permite BackgroundImage (ou outro valor para o atributo "in2") para ser visvel apenas se
"SourceGraphic" (ou outro valor para o atributo "in") contm transparncia.

"screen" permite que os valores de cada imagem adicionem brilho para os outros. Por exemplo:
white screen black = white
e
red (#FF0000) screen grey (#808080) = #ff8080 ("rosa"ou uma rosa como cor)

"multiply" permite valores das imagens para subtrair o brilho de um. Por exemplo:
white mult black = black
e
red (#FF0000) mult grey (#808080) = #800000 (um tom de vermelho mais escuro do que "darkred")

"lighten" toma o valor mais brilhante das duas imagens em cada pixel. Por exemplo:
white lighten black = white
e
red (#FF0000) lighten grey (#808080) = #ff8080 ("rose")

"darken" toma o valor mais escuro das duas imagens em cada pixel. Por exemplo:
white darken black = black
e
red (#FF0000) darken grey (#808080) = #800000 ("vermelho mais escuro")

<FeComposite>

Nem <feMerge> nem <feBlend> apresenta-nos uma maneira de fazer uma mdia ou interseco de duas
imagens. <feComposite> pode ser usado para esse trabalho. Ele permite a sobreposio de pegadas de
imagens bem como a mistura relativa dos seus valores de pixel. Como <feMerge>, que leva duas
entradas, e in2. Por padro, "in" o "SourceGraphic".

Um exemplo representativo (com o operador = "in") se parece com isso:


<filter id="in">
<feComposite in2="BackgroundImage" in="SourceGraphic" operator="in" />
</filter>

O operador mais complexo, "arithmetic", merece um pouco mais de explicao. Quando for
especificado "arithmetic", quatro outros parmetros so invocados: k1, k2, k3 e k4. Estes parmetros
atribuem, respectivamente, para um componente representando o mltiplo das duas imagens, o efeito
linear da primeira imagem, o efeito linear da segunda imagem e um "intercept", ou ajuste de brilho. Na
ilustrao a seguir, quando o operador "arithmetic", em seguida, K1 = 0, K2 = 1, K3 = -1, K4 = 1,
significa que o "SourceGraphic" (in) contribui de forma positiva, o "BackgroundImage" (in2) contribui
de forma negativa, e o brilho reforado.
O exemplo mostrado na figura a seguir ilustra outro conjunto de usos para <feComposite>.

As duas primeiras ilustraes (na parte superior esquerda) mostram as formas bsicas para serem
combinadas: uma elipse simples e um mapa turbulncia. O Terceiro a partir da esquerda na linha
superior mostra o resultado de combinar os dois usando operador = "in".
Aqui est o cdigo correspondente:

<filter id="compositeI" y="0" x="0" width="100%" height="100%">


<feTurbulence baseFrequency=".05" numOctaves="3" result="A"/>
<feComposite in="A" in2="SourceGraphic" operator="in" />
</filter>
<ellipse cx="385" cy="87" rx="75" ry="87" fill="red" filter="url(#compositeI)"/>

Efetivamente, isso restringe a turbulncia da prpria elipse. Imediatamente direita da imagem, a fim
de que a composio seja invertida:

<filter id="compositeJ" y="0" x="0" width="100%" height="100%">


<feTurbulence baseFrequency=".05" numOctaves="3" result="A"/>
<feComposite in2="A" in="SourceGraphic" operator="in" />
</filter>
<ellipse cx="535" cy="87" rx="75" ry="87" fill="red" filter="url(#compositeJ)"/>

Em suma, por meio do operador = "in", podemos mapear as cores de uma imagem para a forma da
outra. A imagem mais direita na linha superior mostra a mesma coisa, mas com o operador =
"arithmetic".
Aqui est o cdigo:

<filter id="compositeA" y="0" x="0" width="100%" height="100%">


<feTurbulence baseFrequency=".05" numOctaves="3" result="A" />
<feComposite in2="A" in="SourceGraphic" operator="arithmetic" k1="1" k2="1" k3="1" k4="-1" />
</filter>
<ellipse filter="url(#compositeA)" cx="700" cy="87" rx="75" ry="87" fill="red" />
Na sua utilizao de operador = "arithmetic", K1, K2, K3 e so todos iguais a 1,0, o que significa que
ambas as imagens, bem como o seu produto cruzado, contribuir positivamente para o resultado. Uma
vez que isto resulta numa imagem muito brilhante, K4, o ajuste (ou brilho) coeficiente, ajustado para
baixo para garantir que, entre outras coisas, a composio permanece dentro da pegada da elipse.

Imediatamente abaixo dessa imagem, um outro conjunto de valores para operador = "arithmetic"
mostrado. Aqui est o cdigo:
<feComposite in2="A" in="SourceGraphic" operator="arithmetic" k1="8" k2="1" k3="1" k4="-1" />

Isto tem o resultado de fixao das cores das reas onde se sobrepem as formas mais perto dos valores
de vermelho da elipse representada por "SourceGraphic".

De um modo geral, parece que os conjuntos mais interessantes de valores associados com os parmetros
neste caso surgem variando k1.

Os efeitos permanecem na pgina com animao, bem como o mascaramento. Ao aplicar uma mscara
que se desvanea em transparncia na borda externa da elipse, o aparecimento de ressalto nas bordas
transmitido, e, quando combinado com animao, d a iluso de uma esfera sendo girada.

<feDisplacementMap>

Este efeito um pouco diferente dos outros no sentido que ele converte os valores de cor de uma
imagem em distores geomtricas de pixels no mesmo local, em outra imagem.

<feDisplacementMap> carrega em (SourceGraphic por padro) e "in2", e usa um canal especificado (R,
G, B ou A) de "in2" para servir como valor de deslocamento, para determinar a direo ea distncia de
cada pixel de "in" que vai ser movido no sentido x ou y (ou ambos).

Por exemplo, se voc quisesse usar o canal vermelho da "in2" para distorcer "in" horizontalmente, e se a
imagem subjacente representada por in2 , digamos, um tabuleiro de xadrez vermelho-e-preto (da, alto
no vermelho sobre os quadrados vermelhos e baixo no vermelho sobre os quadrados pretos), ento esses
pixels de "in" que se encontram acima dos quadrados vermelhos seriam movidos para a direita,
enquanto que aqueles acima nos quadrados pretos seriam movidos para a esquerda.

No exemplo abaixo, um padro quadriculado utilizado para preencher o fundo. Um elemento


<image> ento filtrado com um deslocamento que move os pixels acima dos quadrados vermelhos e
aqueles acima dos quadrados pretos 150 pixels para alm de um outro tanto na direes x e y.
Aqui, o cdigo para esse exemplo:

<defs>
<pattern id="Pattern" patternUnits="userSpaceOnUse" width="100" height="100">
<rect x="0" y="0" width="100" height="100" fill="#f02"/>
<rect x="0" y="0" width="50" height="50" fill="black"/>
<rect x="50" y="50" width="50" height="50" fill="black"/>
</pattern>
<filter id="d" x="-20%" y="-20%" height="140%" width="140%">
<feDisplacementMap scale="150" in2="BackgroundImage" yChannelSelector="R" xChannelSelector="R" />
</filter>
</defs>
<g enable-background="new">
<rect x="0%" y="0%" height="100%" width="100%" fill="url(#Pattern)"/>
<image filter='url(#d)' xlink:href="p17.jpg" x="30%" y="25%" width="40%" height="50%"
preserveAspectRatio="none" />
</g>

Isto faz separar todos os outros quadrados da imagem e em move cada parte tanto na vertical como na
horizontal, como se mostra.

<feDisplacementMap> uma ferramenta notvel quando se trata de entortar imagens e produzir certos
efeitos naturalistas, particularmente quando <feTurbulence> usado na fonte do deslocamento.
Seguem-se uma coleo de exemplos que usam <feTurbulence>, juntamente com breves explicaes
sobre como cada um feito.

Warping (entortar) com um Gradiente Simples

No exemplo abaixo, um gradiente linear inserido em um filtro atravs do <feImage>. Em seguida,


utilizado como a fonte de distoro por algum outro contedo SVG, como mostrado:

<defs>
<linearGradient id="LG" gradientTransform="rotate(12 .5 .5)">
<stop offset="0" stop-color="black"/>
<stop offset=".35" stop-color="#300"/>
<stop offset=".45" stop-color="#8a8"/>
<stop offset=".5" stop-color="blue"/>
<stop offset=".57" stop-color="#8a8"/>
<stop offset="1" stop-color="black"/>
</linearGradient>
<rect id="r" x="0" y="0" height="100%" width="100%" fill="url(#LG)"/>
</defs>
<filter id="D" height="165%" y="-30%" width="140%">
<feImage xlink:href="#r" result="M" />
<feDisplacementMap in="SourceGraphic" in2="M" scale="1" xChannelSelector="B"
yChannelSelector="G">
<animate attributeName="scale" dur="2s" values="0;85;0" repeatCount="indefinite"/>
</feDisplacementMap>
</filter>
<use xlink:href="#r"/>
<g id="GEL" filter='url(#D)'>
<ellipse cx="50%" cy="50%" fill="none" stroke="#302" stroke-width="40" rx="20%" ry="15%" />
<text x="40%" y="53%" font-size="55" fill="black" font-family="arial">Warping</text>
</g>

Warping (entortar) com Turbulence

Os exemplos abaixo mostram como usar <feTurbulence> como fonte de distoro de uma imagem pode
produzir resultados interessantes. A ilustrao a seguir mostra este efeito manifestado de forma diferente
em quatro cpias separadas da mesma imagem:

Warping (entortar) esfrico

A ilustrao (mostrada abaixo) tem duas imagens que voc pode comparar, um dos quais teve um efeito
de lente aplicado (ou seja, um gradiente esfrico foi usado como a fonte de deslocamento).
Uma comparao perto das duas imagens revelam que, enquanto o gro da imagem direita
dimensionado de modo semelhante em toda a imagem, no exemplo da esquerda, o gro tende a ser
maior para o centro. Como as imagens giram, a iluso da imagem esquerda sendo esfrica mais
aparente.

A ilustrao a seguir mostra como voc pode usar a imagem de origem raster com
<feDisplacementMap> para transformar uma forma esfrica, tal como no exemplo abaixo:

Como neste outro exemplo, sphere.png trazido para o filtro usando <feImage>, onde usado para
filtrar uma grade retangular simples:

<filter id="sphere" y="-60%" x="-60%" width="260%" height="220%" >


<feImage xlink:href="sphere.png" />
<feOffset dx="-35" dy="15" result="Map" />
<feDisplacementMap in="SourceGraphic" in2="Map" scale="250" xChannelSelector="R"
yChannelSelector="G" result="C"/>
</filter>

<feOffset> usado para contrabalanar o deslocamento que <feDisplacementMap> transmite a toda


imagem e, em seguida, em virtude da natureza do mapa (sphere.png), o canal vermelho usado para
compensar horizontalmente, enquanto o verde usado para deslocamentos verticais. A imagem depois
turvada e posterizeda para induzir o padro visual interessante.

Outros exemplos do uso de distoro esfrica incluem o que demonstra algo como um movimento
planetrio e outro que demonstra algo vagamente reminiscente de um sistema meteorolgico mundial.

Das könnte Ihnen auch gefallen