PerfectVector
Por Irene Kim

Meça o comprimento de caminhos SVG sem confundir a escala

Meça caminhos SVG em unidades de usuário, considere transformações e tamanho nominal e diferencie totais de contornos, calibração pathLength e percurso de máquina.

10 min de leitura
Nesta página

Para medir um caminho SVG, chame getTotalLength() no elemento geométrico e depois identifique o sistema de coordenadas por trás do número. O navegador devolve um comprimento em unidades de usuário. Esse número não é automaticamente o comprimento exibido, uma medida em milímetros ou a distância percorrida por uma máquina.

Por exemplo, nossa diagonal original mede 50 unidades de usuário. Uma escala uniforme dobra seu comprimento no espaço raiz para 100, enquanto escalar apenas a direção horizontal leva esse comprimento a cerca de 72.111. O resultado local da API continua 50 nos dois casos. Esses números respondem a perguntas diferentes de medição.

Meça um segmento conhecido antes de medir a arte

Você precisa de um SVG com geometria acessível e de um navegador que execute SVG inline e JavaScript. Trabalhe em uma cópia da arte. Decida se precisa de geometria local, transformada ou de um comprimento em tamanho físico especificado antes de registrar um resultado.

Um caminho armazena uma rota com comandos como mover, linha, curva e fechar. Uma unidade de usuário pertence a esse sistema de coordenadas SVG; não a chame de pixel ou milímetro sem conferir o mapeamento. A referência de getTotalLength() da MDN define o resultado como o comprimento do caminho calculado pelo navegador em unidades de usuário.

Este exemplo HTML completo mede um segmento reto. Salve como arquivo HTML e abra no navegador:

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>SVG length control</title>
<svg width="240" height="240" viewBox="0 0 120 120">
  <path id="route" d="M10 10 L40 50"
        fill="none" stroke="black" />
</svg>
<pre id="result"></pre>
<script>
  const route = document.querySelector("#route");
  document.querySelector("#result").textContent =
    route.getTotalLength() + " local user units";
</script>
</html>

A variação horizontal é 30 e a vertical é 40, então o comprimento esperado é sqrt(30² + 40²) = 50. O resultado exibido fornece um controle conhecido antes de confiar em uma curva complexa ou em um emblema importado. A área de visualização de 240 pixels não transforma esse resultado local em 100 unidades de usuário.

No nosso exemplo de navegador, declaramos uma tolerância de 0.01 unidade de usuário. Um controle de quarto de círculo com raio 10 tem comprimento analítico de 5π, aproximadamente 15.708. O navegador de teste informou Chrome 155 e retornou cerca de 15.7102, dentro dessa tolerância. O navegador calcula numericamente o comprimento de curvas, então mantenha uma precisão útil e compare com uma tolerância adequada em vez de exigir os mesmos últimos decimais de toda implementação.

Separe comprimentos locais e transformados

Nossos próximos dois exemplos mantêm o mesmo d="M10 10 L40 50" e acrescentam transformações:

Segmento originalComprimento local da APIComprimento após a transformação indicada, em unidades de usuário do SVG raiz
Sem transformação5050
scale(2)50100
scale(2 1)50Cerca de 72.111

A escala uniforme multiplica todas as direções pela mesma magnitude, então multiplicar o comprimento local por 2 funciona na segunda linha. A escala não uniforme trata as direções de maneiras diferentes. Na terceira linha, o segmento alterado tem 60 unidades na horizontal e 40 para baixo: sqrt(60² + 40²), não 50 × 2.

A especificação de sistemas de coordenadas SVG explica como transformações e o mapeamento de viewBox estabelecem sistemas de coordenadas. Nomeie seu espaço de destino. Um comprimento em unidades de usuário do SVG raiz ainda difere de pixels CSS na área de visualização.

Para esse segmento reto conhecido, mapeamos seus extremos para o espaço de usuário do SVG raiz:

const root = route.ownerSVGElement;
const relative = root.getCTM().inverse().multiply(route.getCTM());
const a = new DOMPoint(10, 10).matrixTransform(relative);
const b = new DOMPoint(40, 50).matrixTransform(relative);
const transformedLength = Math.hypot(b.x - a.x, b.y - a.y);

A matriz raiz inversa remove o mapeamento da área de visualização raiz; a matriz relativa preserva a transformação do caminho para o espaço de usuário raiz. Esse trecho pressupõe um SVG anexado ao documento com matrizes invertíveis e o segmento reto específico acima. Seus extremos são conhecidos a partir da origem desse caminho.

Para uma curva, a distância entre os extremos é apenas uma corda. Para medir uma curva com transformação geral, transforme a geometria para o sistema de coordenadas de destino e meça essa geometria, ou use uma aproximação numérica controlada que preserve contornos separados. Não aplique essa fórmula de extremos a uma rota curva nem multiplique uma forma transformada de modo não uniforme por um único fator de escala estimado.

Controles reais de medição no navegador mostrando escala uniforme e não uniforme, um emblema de dois contornos, comprimentos locais e um cálculo nominal em milímetros
Geometria original criada diretamente com resultados ao vivo do navegador. Comprimentos locais, comprimentos transformados no espaço raiz e milímetros nominais calculados têm rótulos separados. Nenhum aplicativo de destino ou teste físico de produção é mostrado.

Converta para milímetros só depois de fixar o mapeamento

Nosso documento original do emblema declara width="50mm", height="50mm" e viewBox="0 0 100 100". Com o mapeamento uniforme pretendido, isso equivale a 0.5 mm por unidade de usuário. A largura externa do emblema abrange 80 unidades, então sua largura nominal é 40 mm.

Os comprimentos de seus dois contornos somam 380 unidades de usuário. Nessa escala declarada:

50 mm / 100 user units = 0.5 mm per user unit
380 user units × 0.5 mm per user unit = 190 mm of contours

Esse é um cálculo a partir das dimensões criadas. Não medimos um objeto impresso, não verificamos um monitor com régua nem testamos o tamanho de importação de um editor. CSS pode sobrescrever a área de visualização do SVG, e um destino pode redimensionar a arte. Confirme as dimensões entregues nesse destino antes de tratar um cálculo nominal como medida de produção.

A largura do documento inteiro também difere da largura da arte dentro dele. Se você definir apenas a largura externa do emblema como 50 mm, suas 80 unidades dão outro fator: 50 / 80 = 0.625 mm per unit. As mesmas 380 unidades representariam então 237.5 mm de contornos. Registre qual largura definiu; use o guia de caixa delimitadora SVG quando precisar inspecionar os limites primeiro.

pathLength calibra distâncias sem redimensionar a geometria

Também fizemos uma cópia do segmento original de 50 unidades com pathLength="1". O resultado de getTotalLength() continuou 50. O atributo não mudou seus extremos nem tornou seu comprimento geométrico igual a uma unidade.

A especificação da API de geometria SVG exclui explicitamente pathLength do resultado calculado. A referência de pathLength da MDN descreve sua calibração do comportamento de distância ao longo do caminho, incluindo tracejados. Isso é útil ao criar um efeito com distâncias normalizadas; não substitui medir a rota subjacente.

Para uma animação que revela o desenho, siga o guia de animação de traços SVG. Separe seus valores calibrados de tracejado do comprimento geométrico registrado para inspecionar a arte.

Some contornos sem transformar o total em percurso de máquina

Nosso emblema tem um limite externo e um furo em forma de losango. O caminho composto original armazena os dois contornos fechados:

<path fill-rule="evenodd"
      d="M10 10 H90 V60 L50 90 L10 60 Z
         M50 25 L65 45 L50 65 L35 45 Z" />

O contorno externo mede 280 unidades e o interno mede 100. O caminho composto retornou 380; medir os dois contornos como elementos separados e somar também retornou 380. A especificação de caminhos SVG distingue novos subcaminhos de segmentos de linha e fechamento. Mover até o furo não acrescenta um segmento desenhado conectando os contornos.

Essa soma descreve a geometria armazenada selecionada. Uma linha grossa traçada pode ter duas rotas de borda; um caminho duplicado pode somar a geometria novamente; um emblema pode incluir pequenos contornos internos que você não pretendia processar. Meça os objetos e contornos realmente desejados e inspecione antes de interpretar o total.

O percurso da máquina é outro resultado. Um trabalho pode incluir deslocamento entre contornos, escolhas de ordem, passadas repetidas ou mudanças de caminho específicas do destino. Nosso total no navegador não estabelece nada disso. Também não fornece tempo de corte, consumo de material ou um resultado de máquina bem-sucedido. Se precisar de uma única rota central a partir de um desenho digitalizado, o guia de SVG de linha única aborda essa outra tarefa de reconstrução.

Registre a medida com seus pressupostos

  1. Identifique a geometria selecionada e confira se contém vários contornos ou duplicatas.
  2. Meça um controle conhecido e os caminhos selecionados em unidades de usuário locais.
  3. Registre as transformações e o espaço de coordenadas necessário para o resultado.
  4. Estabeleça as dimensões pretendidas do documento ou da arte antes de converter unidades.
  5. Identifique separadamente valores de calibração, totais de contornos e medidas do destino.

Se o controle reto conhecido não retornar 50 dentro da tolerância declarada, confira qual elemento selecionou e se seus dados de origem mudaram. Se os resultados locais coincidirem, mas o tamanho nominal diferir, inspecione área de visualização, transformações e escala de destino antes de alterar os caminhos. Mais casas decimais não resolvem um mapeamento de coordenadas errado.

A conferência geométrica do arquivo termina quando outra pessoa consegue reproduzir o total de contornos selecionado e entender suas unidades, mapeamento, tolerância e objetos incluídos. Nosso exemplo de navegador preservado passou nesses controles numéricos. Não houve teste de importação em editor, percurso de máquina ou tamanho físico.

Se a única origem for um bitmap, o fluxo de imagem para vetor do PerfectVector pode reconstruir primeiro a geometria SVG editável. Inspecione os contornos e furos recuperados e depois meça essa geometria selecionada com uma escala explícita. A vetorização cria caminhos a partir de pixels; ela não recupera um tamanho físico perdido, não infere uma linha central nem fornece uma estimativa de percurso de máquina. Preserve um original vetorial existente quando disponível. O emblema deste artigo foi criado diretamente e não foi traçado.

Perguntas frequentes

getTotalLength() retorna pixels ou milímetros? Ele retorna o comprimento calculado pelo navegador em unidades de usuário SVG. Estabeleça o mapeamento de coordenadas e tamanho antes de expressar o resultado em pixels da área de visualização ou unidades físicas nominais.

Por que escalar o caminho não muda o resultado local da API? A rota local armazenada e sua representação transformada ocupam espaços de coordenadas diferentes. Nosso segmento com os mesmos dados retornou 50 localmente após escala uniforme e não uniforme. Seus comprimentos transformados foram 100 e cerca de 72.111 unidades do SVG raiz.

pathLength="1" significa que o caminho mede uma unidade? Ele fornece um valor de calibração para comportamentos compatíveis de distância ao longo do caminho. O comprimento calculado pela API de geometria ignora esse atributo; nosso controle de 50 unidades continuou retornando 50.

Posso estimar o tempo de corte a partir de um total de contornos? O total sozinho é insuficiente. Ele não estabelece as rotas geradas no destino, deslocamento entre contornos, passadas repetidas, mudanças de velocidade ou comportamento do material. Use as verificações do trabalho no destino real e um teste de produção adequado.

Fontes

  1. MDN: SVGGeometryElement.getTotalLength() — Comprimento do caminho calculado pelo navegador em unidades de usuário.
  2. W3C: API de geometria SVG — Comprimento calculado e sua independência da calibração pathLength.
  3. W3C: Sistemas de coordenadas SVG — Mapeamentos de área de visualização, viewBox e transformações.
  4. MDN: pathLength — Calibração do comportamento de distância ao longo do caminho.
  5. W3C: Caminhos SVG — Subcaminhos, segmentos desenhados e comandos de fechamento.

Precisa de geometria editável de um bitmap antes de medir? Crie um candidato em SVG, inspecione os contornos que contém e estabeleça a escala pretendida antes de registrar um comprimento.

Mais do blog

PerfectVector

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

Sem cartão de crédito