PerfectVector
Por Irene Kim10 min de leitura

Comandos relativos em SVG: acompanhe o ponto atual

Leia traçados SVG absolutos e relativos acompanhando o ponto atual. Teste pares moveto, reinícios de closepath e coordenadas cúbicas em um exemplo original equivalente.

Nesta página

Comandos absolutos de traçado SVG, como M, L e C, usam posições no sistema atual de coordenadas do usuário. Suas formas relativas, m, l e c, usam deslocamentos a partir do ponto atual. Para ler ou reescrever um traçado, acompanhe esse ponto após cada segmento. Mudar a letra de um comando sem mudar seus números pode alterar a forma.

Duas regras causam boa parte da confusão: o primeiro par de um m inicial funciona como um movimento absoluto, enquanto os pares adicionais são linhas relativas; e Z ou z fecha um subtraçado e redefine o ponto atual como seu início. Um novo movimento relativo após esse fechamento usa o ponto redefinido.

Leia posições e deslocamentos separadamente

A especificação de traçados do W3C define um traçado por seu ponto atual, subtraçados e comandos de desenho. As coordenadas são unidades de usuário SVG, não necessariamente pixels da tela. Um viewBox ou uma transformação pode mapeá-las para outra posição exibida.

Partindo de (40, 40), estes dois comandos descrevem a mesma linha:

L180 40
l140 0

O primeiro especifica o ponto final (180, 40). O segundo soma (140, 0) a (40, 40). Ambos terminam em (180, 40), que se torna o ponto atual para o próximo segmento.

Já l180 40 soma (180, 40) e termina em (220, 80). O comando tem sintaxe válida, mas desenha uma linha diferente.

ComandoSignificado dos valores de posição
M x yInicia um subtraçado na posição especificada
m dx dyInicia um subtraçado em relação ao ponto atual, com o comportamento do m inicial explicado abaixo
L x yDesenha uma linha até uma posição
l dx dyDesenha uma linha até o ponto atual somado a um deslocamento
C / cEspecifica dois controles e um ponto final, como posições ou deslocamentos a partir do mesmo início
Z / zFecha no início do subtraçado e redefine o ponto atual

Z maiúsculo e minúsculo têm o mesmo efeito: não recebem argumentos de coordenadas. A referência de d no MDN lista os comandos e seus parâmetros individuais.

Compare duas descrições da mesma arte original

Salve este SVG completo como absolute.svg e abra-o em um navegador. Ele contém um emblema composto verde-petróleo com uma abertura quadrada e uma curva cúbica coral separada:

<svg xmlns="http://www.w3.org/2000/svg" width="300" height="240" viewBox="0 0 300 240">
  <path class="badge" fill="#173b40" fill-rule="evenodd" d="M40 40L180 40L210 80L180 140L40 140Z M80 70L80 110L120 110L120 70Z"/>
  <path class="curve" fill="none" stroke="#f28567" stroke-width="6" d="M40 190C80 145 155 225 220 180"/>
</svg>

Para relative.svg, mantenha o tamanho, o viewBox e os estilos do SVG, mas substitua os dois elementos path por estes:

<path class="badge" fill="#173b40" fill-rule="evenodd"
  d="m40 40 140 0 30 40 -30 60 -140 0z m40 30 0 40 40 0 0 -40z"/>
<path class="curve" fill="none" stroke="#f28567" stroke-width="6"
  d="m40 190c40 -45 115 35 180 -10"/>

Renderizamos os dois arquivos originais em um navegador, ao lado de uma cópia do emblema absoluto com um erro proposital. A cópia com erro muda apenas seu primeiro L180 40 para l180 40; os números permanecem iguais.

Renderizações reais de SVG mostram emblemas compostos e curvas cúbicas equivalentes em coordenadas absolutas e relativas, além de um emblema distorcido após um comando de linha mudar de maiúsculo para minúsculo sem converter suas coordenadas
As duas primeiras descrições coincidem. A terceira muda o ponto final da primeira linha de (180, 40) para (220, 80). Os painéis inferiores acompanham o fechamento, os deslocamentos cúbicos e as medições do navegador para o par apresentado.

Nossa página usou as funções SVG nativas getTotalLength() e getPointAtLength() para comparar 301 amostras por traçado em frações correspondentes do comprimento total. Os comprimentos exibidos foram 657.082 unidades de usuário para cada emblema e 189.066 para cada curva. A maior diferença entre os pontos amostrados foi exibida como 0.000000 para ambos os pares.

Essa medição corrobora essas strings específicas, cujos vértices de linha e pontos cúbicos também coincidem pelos cálculos abaixo. Ela não prova que qualquer reescrita ou conversor lida com todos os comandos SVG. A comparação usa a mesma viewport sem transformações e as mesmas configurações de pintura em todos os casos.

Acompanhe o primeiro m e suas linhas implícitas

Nosso emblema começa com:

m40 40 140 0 30 40 -30 60 -140 0z

Apenas o primeiro par executa um movimento. Os pares restantes se comportam como segmentos l relativos implícitos. A definição de moveto mantém explicitamente esses pares posteriores relativos, embora o m40 40 inicial seja tratado como um início absoluto.

Acompanhe um par por vez:

Par ou comandoOperaçãoPonto atual depois
m40 40Movimento inicial(40, 40)
140 0Linha relativa implícita(180, 40)
30 40Linha relativa implícita(210, 80)
-30 60Linha relativa implícita(180, 140)
-140 0Linha relativa implícita(40, 140)
zFecha no início deste subtraçado(40, 40)

Para comparação, um M maiúsculo com vários pares transformaria os pares posteriores em segmentos L absolutos implícitos. Ele não trataria cada par como outro movimento nem usaria os mesmos deslocamentos deste exemplo em minúsculas.

Um elemento path estabelece sua própria sequência de traçado. Não inicie seu m relativo inicial a partir do ponto final de um elemento path anterior sem relação com ele.

Use o início do subtraçado fechado para o próximo movimento

A abertura começa após o primeiro z:

m40 30 0 40 40 0 0 -40z

Nesse momento, o ponto atual é (40, 40), portanto o novo movimento relativo soma (40, 30) e inicia a abertura em (80, 70). Suas linhas implícitas então chegam a (80, 110), (120, 110) e (120, 70) antes de fechar.

Se você usasse, por engano, o ponto final da última linha do emblema externo, (40, 140), como base, colocaria esse movimento em (80, 170). O fechamento anterior é o que torna esse cálculo incorreto. A definição de closepath redefine o ponto atual como o ponto inicial do subtraçado atual.

Os dois subtraçados pertencem a um único elemento path. Seu fill-rule="evenodd" faz do quadrado interno uma abertura neste exemplo. Mantenha a regra de preenchimento e as configurações de pintura estáveis ao comparar reescritas de coordenadas, para que uma mudança de preenchimento não esconda a geometria que você está testando.

Meça cada controle cúbico a partir do mesmo ponto inicial

A curva separada começa em (40, 190):

M40 190 C80 145 155 225 220 180
m40 190 c40 -45 115 35 180 -10

Para esse único segmento c minúsculo, os três pares são deslocamentos a partir de (40, 190). O segundo controle não é medido a partir do primeiro, e o ponto final não é medido a partir do segundo.

PontoPar relativoPosição absoluta
Primeiro controle(40, -45)(80, 145)
Segundo controle(115, 35)(155, 225)
Final(180, -10)(220, 180)

Após o segmento, atualize o ponto atual para seu ponto final (220, 180). Um segmento relativo seguinte usaria esse novo início. O tutorial de traçados do MDN explica os controles cúbicos e as formas absolutas e relativas; o guia de junções Bézier aborda separadamente as alças tangentes e o comando abreviado S.

Não generalize a subtração de coordenadas para todos os números de todos os comandos. Em um arco, os raios, a rotação e os indicadores têm funções diferentes; apenas seu par de ponto final alterna entre posições absolutas e relativas. Consulte a explicação dos indicadores de arco antes de reescrever dados A ou a. Este exemplo demonstra linhas, movimentos, fechamento e um segmento cúbico comum, em vez de uma rotina geral de conversão de traçados.

Mova a arte sem confundir posicionamento com sintaxe do traçado

Neste emblema composto inteiramente relativo, mudar o m40 40 inicial para m60 60 desloca seus vértices em (20, 20): os deslocamentos posteriores e o movimento relativo do subtraçado acompanham o novo início. Isso não altera o traçado separado da curva. Em dados mistos, as posições absolutas posteriores também permanecem ancoradas nas coordenadas especificadas, portanto editar o primeiro movimento pode deformar o traçado.

Para mover toda a arte de dois traçados como uma unidade, mantenha as duas strings d e coloque seus elementos dentro de um grupo com transform="translate(20 20)". A especificação do sistema de coordenadas SVG explica como transformações estabelecem mapeamentos de coordenadas. Uma transformação de grupo muda o posicionamento sem reescrever os dados originais do traçado.

Confira se a viewport ainda contém a arte movida; transladar um grupo não aumenta automaticamente sua área de desenho. O guia da ordem de transformações SVG aborda o posicionamento quando translação e escala são combinadas.

Inspecione a geometria de origem antes de mudar sua notação

O PerfectVector pode ajudar quando a arte existe apenas como PNG ou JPG. Prepare um SVG candidato e compare a silhueta, as aberturas e o formato das curvas recuperados com a origem antes de editar os dados do traçado. A notação absoluta ou relativa não determina se a geometria recuperada é adequada.

Use diretamente um original vetorial disponível, ou redesenhe um símbolo simples quando isso for mais fácil de controlar. Reescrever comandos não recupera a forma pretendida a partir de informações raster ausentes. A visão geral da vetorização de imagens explica essa etapa separada de reconstrução.

Ao editar um SVG utilizável, guarde uma cópia do original, altere um segmento compatível por vez e compare o arquivo real na mesma escala. Acompanhe o início do subtraçado e o ponto atual. Preserve as configurações de preenchimento e traço durante a comparação e teste o arquivo exportado no aplicativo de destino.

Perguntas frequentes

O primeiro m minúsculo é relativo a outro traçado? Não. Quando m é o primeiro comando de um traçado, seu primeiro par é tratado como um início absoluto. Os pares adicionais são linhas relativas implícitas, e o ponto final de outro elemento path não é sua base inicial.

Onde fica o ponto atual após Z ou z? No início do subtraçado que acabou de fechar. Um movimento relativo seguinte usa esse ponto redefinido, não o ponto final da linha anterior.

Posso converter um traçado colocando seus comandos em minúsculas? Não. Os valores de posição precisam ser recalculados segundo a semântica de cada comando. Neste exemplo, L180 40 se torna l140 0 a partir do ponto atual (40, 40), enquanto l180 40 desenha uma linha diferente.

Fontes

  1. W3C — Traçados SVG 2 — Define pontos atuais, moveto inicial, linhas implícitas, fechamento e parâmetros cúbicos.
  2. MDN — Tutorial de traçados — Ilustra comandos absolutos e relativos de linhas e curvas.
  3. MDN — Atributo d — Lista as funções dos parâmetros dos comandos, incluindo arcos e closepath.
  4. W3C — Sistemas de coordenadas SVG 2 — Explica os mapeamentos de coordenadas do usuário e o posicionamento da arte por transformações.

Sua arte existe apenas em raster? Prepare traçados SVG com o PerfectVector, inspecione a silhueta e as aberturas recuperadas e edite apenas os comandos que você entende, verificando o SVG entregue em relação ao original.

Mais do blog

Recomece com um SVG mais limpo
e fácil de editar