Dado um círculo centrado em (200.200), raio 25, como faço para desenhar um arco de 270 graus a 135 graus e um arco que varia de 270 a 45 graus?
0 grau significa que está bem no eixo x (o lado direito) (o que significa que é a posição das 3 horas) 270 graus significa que está na posição de 12 horas e 90 significa que está na posição de 6 horas
De maneira mais geral, o que é um caminho para um arco para parte de um círculo com
x, y, r, d1, d2, direction
significado
center (x,y), radius r, degree_start, degree_end, direction
arcSweep
variável está realmente controlando olarge-arc-flag
parâmetro svg A. No código acima, o valor para osweep-flag
parâmetro é sempre zero.arcSweep
provavelmente deve ser renomeado para algo comolongArc
.endAngle - 0.0001
caso contrário, o arco completo não será renderizado.Você deseja usar o comando elíptico
A
rc . Infelizmente para você, isso exige que você especifique as coordenadas cartesianas (x, y) dos pontos inicial e final, em vez das coordenadas polares (raio, ângulo) que você possui, portanto, é necessário fazer algumas contas. Aqui está uma função JavaScript que deve funcionar (embora eu não a tenha testado) e espero que seja bastante auto-explicativa:Quais ângulos correspondem a quais posições do relógio dependerão do sistema de coordenadas; apenas troque e / ou negue os termos sin / cos, conforme necessário.
O comando arc possui estes parâmetros:
Para o seu primeiro exemplo:
rx
=ry
= 25 ex-axis-rotation
= 0, pois você deseja um círculo e não uma elipse. Você pode calcular as coordenadas iniciais (que você deveM
dedicar) e as coordenadas finais (x, y) usando a função acima, produzindo (200, 175) e aproximadamente (182.322, 217.678), respectivamente. Dadas essas restrições até agora, na verdade existem quatro arcos que podem ser desenhados, então as duas bandeiras selecionam uma delas. Acho que você provavelmente deseja desenhar um pequeno arco (significadolarge-arc-flag
= 0), na direção do ângulo decrescente (significadosweep-flag
= 0). Todos juntos, o caminho SVG é:Para o segundo exemplo (supondo que você queira ir na mesma direção e, portanto, um arco grande), o caminho SVG é:
Novamente, eu não testei isso.
(editar 2016-06-01) Se, como @clocksmith, você está se perguntando por que eles escolheram essa API, dê uma olhada nas notas de implementação . Eles descrevem duas possíveis parametrizações de arco, "parametrização de ponto final" (a que eles escolheram) e "parametrização central" (que é como o que a pergunta usa). Na descrição da "parametrização do terminal", eles dizem:
Então, basicamente, é um efeito colateral dos arcos serem considerados parte de um caminho maior, em vez de seu próprio objeto separado. Suponho que, se o seu renderizador SVG estiver incompleto, ele poderá pular qualquer componente do caminho que não saiba como renderizar, desde que saiba quantos argumentos eles levam. Ou talvez ele permita a renderização paralela de diferentes pedaços de um caminho com muitos componentes. Ou talvez tenham feito isso para garantir que os erros de arredondamento não se acumulem ao longo de um caminho complexo.
As notas de implementação também são úteis para a pergunta original, pois possuem mais pseudocódigo matemático para a conversão entre as duas parametrizações (o que eu não percebi quando escrevi essa resposta pela primeira vez).
fonte
large-arc-flag
tiver que ser alternado de 0 a 1, poderá ocorrer algum erro.Modifiquei levemente a resposta do opsb e fiz o preenchimento de suporte para o setor do círculo. http://codepen.io/anon/pen/AkoGx
JS
HTML
fonte
centerX
,centerY
a 100, por exemplo.viewBox="0 0 500 500"
Esta é uma pergunta antiga, mas achei o código útil e me poupou três minutos de pensamento :) Então, estou adicionando uma pequena expansão à resposta do @opsb .
Se você deseja converter esse arco em uma fatia (para permitir preenchimento), podemos modificar um pouco o código:
e lá vai você!
fonte
As respostas da @ opsb são claras, mas o ponto central não é preciso, além disso, como @Jithin observou, se o ângulo for 360, nada será traçado.
@Jithin corrigiu o problema 360, mas se você selecionou menos de 360 graus, obterá uma linha que fecha o loop do arco, o que não é necessário.
Corrigi isso e adicionei algumas animações no código abaixo:
fonte
Eu queria comentar a resposta @Ahtenus, especificamente o comentário de Ray Hulha dizendo que o codepen não mostra nenhum arco, mas minha reputação não é alta o suficiente.
A razão para esse codepen não funcionar é que seu html está com defeito com uma largura de traço igual a zero.
Corrigi-o e adicionei um segundo exemplo aqui: http://codepen.io/AnotherLinuxUser/pen/QEJmkN .
O html:
O CSS relevante:
O javascript:
fonte
Uma imagem e algum Python
Apenas para esclarecer melhor e oferecer outra solução.
Arc
OA
comando [ ] usa a posição atual como ponto de partida, portanto você deve usar oMoveto
comando [M] primeiro.Os parâmetros de
Arc
são os seguintes:Se definirmos, por exemplo, o seguinte arquivo svg:
Você definirá o ponto inicial com
M
o ponto final com os parâmetrosxf
eyf
deA
.Estamos procurando por círculos, então definimos como
rx
iguaisry
basicamente agora ele tentará encontrar todo o círculo de raiorx
que cruza o ponto inicial e final.Você pode ter uma explicação mais detalhada neste post que escrevi.
fonte
Nota para os que procuram respostas (quem eu também era) - se o uso de arco não é obrigatório , uma solução muito mais simples de desenhar um círculo parcial é usar o
stroke-dasharray
SVG<circle>
.Divida a matriz do traço em dois elementos e dimensione seu alcance no ângulo desejado. O ângulo inicial pode ser ajustado usando
stroke-dashoffset
.Nem um único cosseno à vista.
Exemplo completo com explicações: https://codepen.io/mjurczyk/pen/wvBKOvP
fonte
A função original polarToCartesian de wdebeaum está correta:
Reversão dos pontos inicial e final usando:
É confuso (para mim) porque isso reverterá a bandeira de varredura. Usando:
com a bandeira de varredura = "0" desenha arcos "normais" no sentido anti-horário, o que eu acho mais direto. Consulte https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
fonte
Uma ligeira modificação na resposta do @ opsb. Não podemos desenhar um círculo completo com esse método. ou seja, se dermos (0, 360), isso não atrairá nada. Portanto, uma pequena modificação feita para corrigir isso. Pode ser útil exibir pontuações que às vezes atingem 100%.
fonte
Versão ES6:
fonte
const d = `M ${start.x} ${start.y} A ${radius} ${radius} 0 ${largeArc} 0 ${end.x} ${end.y}`
Componente ReactJS com base na resposta selecionada:
fonte
você pode usar o código JSFiddle que fiz para a resposta acima:
https://jsfiddle.net/tyw6nfee/
tudo o que você precisa fazer é alterar o código console.log da última linha e fornecer seu próprio parâmetro:
fonte