Cerchio di disegno con il percorso ad arco di SVG

Il seguente percorso SVG può disegnare il 99,99% di un cerchio: (provalo su http://jsfiddle.net/DFhUF/46/ e vedi se vedi 4 archi o solo 2, ma nota che se è IE, viene reso in VML, non in SVG, ma hanno il problema simile)

M 100 100 a 50 50 0 1 0 0.00001 0 

Ma quando è il 99,999999999% di un cerchio, allora non verrà mostrato nulla?

 M 100 800 a 50 50 0 1 0 0.00000001 0 

E lo stesso vale per il 100% di un cerchio (è ancora un arco, non è vero, solo un arco molto completo)

 M 100 800 a 50 50 0 1 0 0 0 

Come può essere risolto? Il motivo è che io uso una funzione per disegnare una percentuale di un arco, e se ho bisogno di “caso speciale” un arco del 99,999% o 100% per usare la funzione cerchio, sarebbe una specie di sciocco.

Di nuovo, un test case su jsfiddle usando RaphaelJS è su http://jsfiddle.net/DFhUF/46/
(e se è VML su IE 8, anche il secondo cerchio non verrà mostrato … devi cambiarlo in 0.01)


Aggiornare:

Questo perché sto rendendo un arco per una partitura nel nostro sistema, quindi 3,3 punti ottengono 1/3 di un cerchio. 0,5 ottiene mezzo cerchio e 9,9 punti ottengono il 99% di un cerchio. Ma cosa succede se ci sono punteggi che sono 9,99 nel nostro sistema? Devo verificare se è vicino al 99,999% di un cerchio e utilizzare di conseguenza una funzione arc o una funzione circle ? Allora che dire di un punteggio di 9,9997? Quale usare? È ridicolo dover sapere quale tipo di punteggi verranno mappati su un “cerchio troppo completo” e passare a una funzione circolare, e quando è “un certo 99,9%” di un cerchio o un punteggio di 9,9997, quindi utilizzare la funzione arco .

Lo stesso per l’arco di XAML. Basta chiudere l’arco del 99,99% con una Z e hai un cerchio!

So che è un po ‘tardi nel gioco, ma mi sono ricordato di questa domanda da quando era nuovo e avevo un dillemma simile, e ho trovato per caso la soluzione “giusta”, se qualcuno ne sta ancora cercando uno:

  

In altre parole, questo:

  

può essere raggiunto come un percorso con questo:

   

Il trucco consiste nell’avere due archi, il secondo che riprende da dove era stato interrotto il primo e che utilizzava il diametro negativo per tornare al punto iniziale dell’arco originale.

Il motivo per cui non può essere fatto come un cerchio completo in un arco (e sto solo speculando) è perché lo diresti per disegnare un arco da se stesso (diciamo 150,150) a se stesso (150,150), che rende come “oh, sono già lì, nessun arco necessario!”.

I vantaggi della soluzione che sto offrendo sono:

  1. è facile da tradurre da un cerchio direttamente a un percorso, e
  2. non ci sono sovrapposizioni nelle due linee d’arco (il che potrebbe causare problemi se si utilizzano indicatori o schemi, ecc.). È una linea continua pulita, anche se disegnata in due pezzi.

Nulla di tutto ciò sarebbe importante se consentissero solo ai percorsi di testo di accettare forms. Ma penso che stiano evitando quella soluzione dato che gli elementi di forma come il cerchio non hanno tecnicamente un punto di “inizio”.

demo di jsfiddle: http://jsfiddle.net/crazytonyi/mNt2g/

Aggiornare:

Se stai usando il percorso per un riferimento a textPath e vuoi che il testo textPath il rendering sul bordo esterno dell’arco, dovresti usare lo stesso identico metodo ma cambiare il flag di sweep da 0 a 1 in modo che tratti l’esterno di il percorso come superficie anziché l’interno (pensate a 1,0 come qualcuno seduto al centro e disegnando un cerchio attorno a sé, mentre 1,1 come qualcuno che cammina intorno al centro a distanza raggio e trascinando il loro gesso accanto a loro, se questo è qualsiasi aiuto). Ecco il codice come sopra ma con la modifica:

  

Fare riferimento alla soluzione di Anthony qui è una funzione per ottenere il percorso:

 function circlePath(cx, cy, r){ return 'M '+cx+' '+cy+' m -'+r+', 0 a '+r+','+r+' 0 1,0 '+(r*2)+',0 a '+r+','+r+' 0 1,0 -'+(r*2)+',0'; } 

Un approccio completamente diverso:

Invece di manipolare i percorsi per specificare un arco in svg, puoi anche prendere un elemento circolare e specificare un tratto-dasharray, in pseudo codice:

 with $score between 0..1, and pi = 3.141592653589793238 $length = $score * 2 * pi * $r $max = 7 * $r (ie well above 2*pi*r)  

La sua semplicità è il vantaggio principale rispetto al metodo del percorso ad arco multiplo (ad esempio, quando si esegue lo scripting, si inserisce solo un valore e si è pronti per qualsiasi lunghezza dell’arco)

L’arco inizia nel punto più a destra e può essere spostato usando una trasformazione di rotazione.

Nota: Firefox ha un bug strano in cui le rotazioni superiori a 90 gradi o più vengono ignorate. Quindi per iniziare l’arco dall’alto, usa:

  

Adobe Illustrator utilizza le curve di Bezier come SVG e per le cerchie crea quattro punti. Puoi creare un cerchio con due comandi ad arco ellittico … ma poi per un cerchio in SVG userei un 🙂

È una buona idea usare due comandi arc per disegnare un cerchio completo.

di solito, utilizzo l’ellisse o l’elemento cerchio per disegnare un cerchio completo.

Scritto come una funzione, assomiglia a questo:

 function getPath(cx,cy,r){ return "M" + cx + "," + cy + "m" + (-r) + ",0a" + r + "," + r + " 0 1,0 " + (r * 2) + ",0a" + r + "," + r + " 0 1,0 " + (-r * 2) + ",0"; } 

Basandosi sulle risposte di Anthony e Anton, ho incorporato la capacità di ruotare il cerchio generato senza influire sul suo aspetto generale. Questo è utile se stai utilizzando il percorso per un’animazione e devi controllare da dove inizia.

 function(cx, cy, r, deg){ var theta = deg*Math.PI/180, dx = r*Math.cos(theta), dy = -r*Math.sin(theta); return "M "+cx+" "+cy+"m "+dx+","+dy+"a "+r+","+r+" 0 1,0 "+-2*dx+","+-2*dy+"a "+r+","+r+" 0 1,0 "+2*dx+","+2*dy; } 

Per quelli come me che cercavano attributi di ellisse per la conversione del percorso:

 const ellipseAttrsToPath = (rx,cx,ry,cy) => `M${cx-rx},${cy}a${rx},${ry} 0 1,0 ${rx*2},0a${rx},${ry} 0 1,0 -${rx*2},0` 

Ho fatto un jsfiddle per farlo qui:

 function polarToCartesian(centerX, centerY, radius, angleInDegrees) { var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0; return { x: centerX + (radius * Math.cos(angleInRadians)), y: centerY + (radius * Math.sin(angleInRadians)) }; } function describeArc(x, y, radius, startAngle, endAngle){ var start = polarToCartesian(x, y, radius, endAngle); var end = polarToCartesian(x, y, radius, startAngle); var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1"; var d = [ "M", start.x, start.y, "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y ].join(" "); return d; } console.log(describeArc(255,255,220,134,136)) 

collegamento

tutto quello che devi fare è cambiare l'input di console.log e ottenere il risultato in console

Un altro modo sarebbe utilizzare due curve cubiche di Bezier. Questo è per le persone iOS che utilizzano pocketSVG che non riconosce il parametro arc svg.

C x1 y1, x2 y2, xy (o c dx1 dy1, dx2 dy2, dx dy)

Curva cubica di Bézier

L’ultima serie di coordinate qui (x, y) è dove vuoi che la linea termini. Gli altri due sono punti di controllo. (x1, y1) è il punto di controllo per l’inizio della curva e (x2, y2) per il punto finale della curva.

  

Queste risposte sono troppo complicate.

Un modo più semplice per farlo senza creare due archi o convertirli in sistemi di coordinate diversi.

Ciò presuppone che l’area di disegno abbia larghezza w e altezza h .

 `M${w*0.5 + radius},${h*0.5} A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}` 

Usa semplicemente il flag “arco lungo”, quindi viene riempito il flag completo. Quindi crea gli archi al 99,999% del cerchio completo. Visivamente è lo stesso. Evita la flag di sweep semplicemente avviando il cerchio sul punto più a destra del cerchio (un raggio direttamente orizzontale dal centro).

Questi esempi sono fin troppo complicati !!!

Basta fare questo con letterali modello es6.

Un modo più semplice per farlo senza creare due archi ..

Ciò presuppone che l’area di disegno abbia larghezza w e altezza h.

 `M${w*0.5 + radius},${h*0.5} A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}` 

Usa semplicemente il flag “arco lungo”, quindi viene riempito il flag completo. Quindi crea gli archi al 99,999% del cerchio completo. Visivamente è lo stesso. Evita la flag di sweep semplicemente avviando il cerchio sul punto più a destra del cerchio (un raggio direttamente orizzontale dal centro).