PerfectVector
Di Irene Kim

Misura i tracciati SVG senza confondere la scala

Misura tracciati SVG in unità utente, considera trasformazioni e dimensioni nominali e distingui i totali dei contorni dalla calibrazione pathLength o dal percorso macchina.

10 min di lettura
In questa pagina

Per misurare un tracciato SVG, chiama getTotalLength() sull'elemento geometrico, poi identifica il sistema di coordinate dietro il numero. Il browser restituisce una lunghezza in unità utente. Quel numero non è automaticamente la lunghezza visualizzata, una misura in millimetri o la distanza percorsa da una macchina.

Per esempio, la nostra diagonale originale è lunga 50 unità utente. Una scala uniforme raddoppia la sua lunghezza nello spazio radice a 100, mentre scalare soltanto la direzione orizzontale porta quella lunghezza a circa 72.111. Il risultato dell'API locale rimane 50 in entrambi i casi. Quei numeri rispondono a domande di misura diverse.

Misura un segmento noto prima della grafica

Ti serve un SVG con geometria accessibile e un browser che esegua SVG inline e JavaScript. Lavora su una copia della grafica. Prima di registrare un risultato, decidi se ti serve la geometria locale, quella trasformata o una lunghezza a una dimensione fisica specificata.

Un tracciato memorizza un percorso con comandi come spostamento, linea, curva e chiusura. Un'unità utente appartiene a quel sistema di coordinate SVG; non chiamarla pixel o millimetro senza controllare la mappatura. La documentazione MDN di getTotalLength() definisce il risultato come lunghezza del tracciato calcolata dal browser in unità utente.

Questo esempio HTML completo misura un segmento rettilineo. Salvalo come file HTML e aprilo in un browser:

<!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>

La variazione orizzontale è 30 e quella verticale 40, quindi la lunghezza prevista è sqrt(30² + 40²) = 50. Il risultato visualizzato ti dà un controllo noto prima di fidarti di una curva complessa o di un emblema importato. Il viewport da 240 pixel non trasforma quel risultato locale in 100 unità utente.

Nel nostro campione nel browser abbiamo dichiarato una tolleranza di 0.01 unità utente. Un controllo a quarto di cerchio con raggio 10 ha una lunghezza analitica di 5π, circa 15.708. Il browser di prova si identificava come Chrome 155 e ha restituito circa 15.7102, entro quella tolleranza. Un browser calcola numericamente la lunghezza delle curve, quindi conserva una precisione utile e confronta con una tolleranza appropriata invece di esigere gli stessi decimali finali da ogni implementazione.

Separa lunghezze locali e trasformate

I due campioni successivi mantengono lo stesso d="M10 10 L40 50" e aggiungono trasformazioni:

Segmento originaleLunghezza API localeLunghezza dopo la trasformazione indicata, in unità utente SVG radice
Nessuna trasformazione5050
scale(2)50100
scale(2 1)50Circa 72.111

La scala uniforme moltiplica ogni direzione per lo stesso fattore, quindi moltiplicare la lunghezza locale per 2 funziona nella seconda riga. La scala non uniforme tratta le direzioni diversamente. Nella terza riga il segmento modificato si estende per 60 unità in orizzontale e 40 in verticale: sqrt(60² + 40²), non 50 × 2.

La specifica dei sistemi di coordinate SVG spiega come le trasformazioni e la mappatura del viewBox stabiliscano i sistemi di coordinate. Nomina lo spazio di destinazione. Una lunghezza in unità utente SVG radice differisce ancora dai pixel CSS nel viewport.

Per questo segmento rettilineo noto, abbiamo mappato le estremità nello spazio utente dell'SVG radice:

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);

La matrice inversa della radice rimuove la mappatura del viewport della radice; la matrice relativa mantiene la trasformazione del tracciato nello spazio utente radice. Questo frammento presuppone un SVG collegato al documento con matrici invertibili e il segmento rettilineo specifico precedente. Le sue estremità sono note dalla sorgente del tracciato.

Per una curva, la distanza tra le estremità è soltanto una corda. Per misurare una curva trasformata in generale, trasforma la geometria nel sistema di coordinate di destinazione e misura quella geometria, oppure usa un'approssimazione numerica controllata che mantenga separati i contorni. Non applicare questa formula delle estremità a un percorso curvo né moltiplicare una forma trasformata non uniformemente per un unico fattore di scala ipotizzato.

Controlli reali di misura nel browser con scala uniforme e non uniforme, un emblema a due contorni, lunghezze locali dei tracciati e un calcolo nominale in millimetri
Geometria originale con risultati dal browser. Lunghezze locali, lunghezze trasformate nello spazio radice e millimetri nominali calcolati sono etichettati separatamente. Non è mostrato alcun test in un'applicazione di destinazione o nella produzione fisica.

Converti in millimetri solo dopo aver fissato la mappatura

Il documento del nostro emblema originale dichiara width="50mm", height="50mm" e viewBox="0 0 100 100". Con la mappatura uniforme prevista, sono 0.5 mm per unità utente. La larghezza esterna dell'emblema copre 80 unità, quindi la sua larghezza nominale è 40 mm.

Le lunghezze dei suoi due contorni totalizzano 380 unità utente. Alla scala dichiarata:

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

È un calcolo dalle dimensioni scritte. Non abbiamo misurato un oggetto stampato, verificato un monitor con un righello o provato il dimensionamento all'importazione di un editor. Il CSS può sovrascrivere il viewport SVG e una destinazione può riscalare la grafica. Conferma le dimensioni consegnate in quella destinazione prima di considerare un calcolo nominale una misura di produzione.

Anche la larghezza dell'intero documento è diversa da quella della grafica al suo interno. Se invece imposti soltanto la larghezza esterna dell'emblema a 50 mm, le sue 80 unità di larghezza danno un fattore diverso: 50 / 80 = 0.625 mm per unit. Le stesse 380 unità rappresenterebbero allora 237.5 mm di contorni. Registra quale larghezza hai impostato; usa la guida al riquadro di delimitazione SVG se devi prima esaminare le estensioni.

pathLength calibra le distanze senza ridimensionare la geometria

Abbiamo anche creato una copia del segmento originale da 50 unità con pathLength="1". Il suo risultato getTotalLength() è rimasto 50. L'attributo non ha cambiato le estremità né reso la lunghezza geometrica pari a un'unità.

La specifica dell'API geometrica SVG esclude esplicitamente pathLength dal risultato calcolato. La documentazione MDN di pathLength descrive la sua calibrazione del comportamento delle distanze lungo il tracciato, inclusi i tratti tratteggiati. È utile per creare un effetto con distanze normalizzate; non sostituisce la misura del percorso sottostante.

Per una comparsa progressiva del disegno, segui la guida all'animazione dei tratti SVG. Mantieni i suoi valori di tratteggio calibrati separati dalla lunghezza geometrica registrata per un'ispezione della grafica.

Somma i contorni senza trasformare il totale in percorso macchina

Il nostro emblema ha un confine esterno e un foro a rombo. Il tracciato composto originale memorizza entrambi i contorni chiusi:

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

Il contorno esterno misura 280 unità e quello interno 100. Il tracciato composto ha restituito 380; misurare i due contorni come elementi tracciato separati e sommarli ha restituito ancora 380. La specifica dei tracciati SVG distingue i nuovi sottotracciati dai segmenti di linea e di chiusura. Spostarsi al foro non aggiunge un segmento disegnato che collega i contorni.

Quella somma descrive la geometria memorizzata selezionata. Una linea spessa ricalcata può avere due percorsi di confine; un tracciato duplicato può aggiungere di nuovo geometria; un emblema può includere piccoli contorni interni che non intendevi lavorare. Misura gli oggetti e i contorni che intendi davvero e ispezionali prima di interpretare un totale.

La distanza percorsa dalla macchina è un risultato separato. Un lavoro può includere spostamenti tra contorni, scelte di ordine, passaggi ripetuti o modifiche dei tracciati specifiche della destinazione. Il nostro totale nel browser non stabilisce nulla di tutto questo. Non fornisce neppure tempo di taglio, consumo di materiale o un risultato macchina riuscito. Se ti serve un percorso centrale da un disegno scansionato, la guida agli SVG a linea singola tratta quel diverso compito di ricostruzione.

Registra la misura insieme alle sue ipotesi

  1. Identifica la geometria selezionata e verifica se contiene più contorni o duplicati.
  2. Misura un controllo noto e i tracciati selezionati in unità utente locali.
  3. Registra le trasformazioni e lo spazio di coordinate necessari per il risultato.
  4. Stabilisci le dimensioni previste del documento o della grafica prima di convertire le unità.
  5. Mantieni etichettati separatamente valori di calibrazione, totali dei contorni e misure della destinazione.

Se il controllo rettilineo noto non restituisce 50 entro la tolleranza dichiarata, controlla quale elemento hai selezionato e se i suoi dati sorgente sono cambiati. Se i risultati locali coincidono ma la dimensione nominale differisce, esamina viewport, trasformazioni e scala della destinazione prima di modificare i tracciati. Più cifre decimali non risolvono una mappatura delle coordinate sbagliata.

Il controllo geometrico del file è completo quando un'altra persona può riprodurre il totale dei contorni selezionati e comprenderne unità, mappatura, tolleranza e oggetti inclusi. Il nostro campione conservato nel browser ha superato quei controlli numerici. Non sono stati eseguiti test di importazione in un editor, percorso macchina o dimensioni fisiche.

Se l'unica sorgente è una bitmap, il flusso da immagine a vettoriale di PerfectVector può prima ricostruire geometria SVG modificabile. Esamina i contorni e i fori recuperati, poi misura quella geometria selezionata con una scala esplicita. La vettorizzazione crea tracciati dai pixel; non recupera una dimensione fisica perduta, non deduce una linea centrale e non fornisce una stima del percorso macchina. Conserva un originale vettoriale esistente quando è disponibile. L'emblema di questo articolo è stato scritto direttamente e non ricalcato.

Domande frequenti

getTotalLength() restituisce pixel o millimetri? Restituisce la lunghezza calcolata dal browser in unità utente SVG. Stabilisci la mappatura di coordinate e dimensioni prima di esprimere il risultato in pixel del viewport o unità fisiche nominali.

Perché scalare il tracciato lascia invariato il risultato dell'API locale? Il percorso locale memorizzato e la sua rappresentazione trasformata occupano spazi di coordinate diversi. Il nostro segmento con gli stessi dati ha restituito 50 localmente dopo la scala sia uniforme sia non uniforme. Le sue lunghezze trasformate erano 100 e circa 72.111 unità SVG radice.

pathLength="1" significa che il tracciato è lungo un'unità? Fornisce un valore di calibrazione per i comportamenti supportati delle distanze lungo il tracciato. La lunghezza calcolata dell'API geometrica ignora quell'attributo; il nostro controllo da 50 unità restituiva ancora 50.

Posso stimare il tempo di taglio dal totale dei contorni? Il totale da solo è insufficiente. Non stabilisce i percorsi generati dalla destinazione, gli spostamenti tra contorni, i passaggi ripetuti, i cambi di velocità o il comportamento del materiale. Usa i controlli del lavoro della destinazione effettiva e una prova di produzione appropriata.

Fonti

  1. MDN: SVGGeometryElement.getTotalLength() — Lunghezza del tracciato calcolata dal browser in unità utente.
  2. API geometrica SVG del W3C — Lunghezza calcolata e indipendenza dalla calibrazione di pathLength.
  3. Sistemi di coordinate SVG del W3C — Mappature di viewport, viewBox e trasformazioni.
  4. MDN: pathLength — Calibrazione del comportamento delle distanze lungo il tracciato.
  5. Tracciati SVG del W3C — Sottotracciati, segmenti disegnati e comandi di chiusura.

Ti serve geometria modificabile da una bitmap prima di misurare? Crea un SVG candidato, esamina quali contorni contiene e stabilisci la scala prevista prima di registrare una lunghezza.

Altro dal blog

PerfectVector

Riparti da un SVG più pulito
e facile da modificare

Nessuna carta di credito