Рисование круга с дуговым путем SVG
следующий путь SVG может нарисовать 99,99% круга: (попробуйте на http://jsfiddle.net/DFhUF/46/ и посмотрите, видите ли вы 4 дуги или только 2, но обратите внимание, что если это IE, он отображается в VML, а не SVG, но имеет аналогичную проблему)
M 100 100 a 50 50 0 1 0 0.00001 0
но когда это 99.9999999999% круга, то ничего не будет отображаться вообще?
M 100 800 a 50 50 0 1 0 0.00000001 0
и это то же самое со 100% круга (это все еще дуга, не так ли, просто очень полная arc)
M 100 800 a 50 50 0 1 0 0 0
как это можно исправить? Причина в том, что я использую функцию для рисования процента дуги, и если мне нужно "особый случай" 99,9999% или 100% дуги для использования функции круга, это было бы глупо.
опять же, тестовый пример на jsfiddle, используя RaphaelJS на http://jsfiddle.net/DFhUF/46/
(и если это VML на IE 8, даже второй круг не будет отображаться... вы должны изменить его на 0.01)
обновление:
это потому, что я рендеринг дуги для оценки в нашей системе, поэтому 3.3 точки получают 1/3 круга. 0.5 получает половину круга, а 9.9 очков-99% круга. Но что, если в нашей системе есть оценки, которые составляют 9,99? Должен ли я проверить, близок ли он к 99,999% круга, и использовать или
13 ответов
Я знаю, что это немного поздно в игре, но я вспомнил этот вопрос, когда он был новым, и у меня была аналогичная диллемма, и я случайно нашел "правильное" решение, если кто-то все еще ищет его:
<path
d="
M cx cy
m -r, 0
a r,r 0 1,0 (r * 2),0
a r,r 0 1,0 -(r * 2),0
"
/>
другими словами, это:
<circle cx="100" cy="100" r="75" />
может быть достигнуто как путь с этого:
<path
d="
M 100, 100
m -75, 0
a 75,75 0 1,0 150,0
a 75,75 0 1,0 -150,0
"
/>
трюк состоит в том, чтобы иметь две дуги, вторая поднимает, где первая остановилась, и использует отрицательный диаметр, чтобы вернуться к исходной дуге начальная точка.
преимущества решения, которое я предлагаю:
- это легко перевести из круга непосредственно в путь, и
- в двух дуговых линиях нет перекрытия (которое может вызвать проблемы, если вы используете маркеры или узоры и т. д.). Это чистая непрерывная линия, хотя и разделенная на две части.
ничего из этого не имело бы значения, если бы они просто позволяли textpaths принимать формы. Но я думаю, что они избегают этого решения, поскольку элементы формы, такие как круг, технически не имеют "начальной" точки.
jsfiddle demo:http://jsfiddle.net/crazytonyi/mNt2g/
обновление:
если вы используете путь к textPath
ссылка и вы хотите, чтобы текст отображался на внешнем краю дуги, вы бы использовали тот же самый метод, но изменили флаг развертки с 0 на 1, чтобы он рассматривал внешнюю часть пути как поверхность, а не внутреннюю (подумайте о 1,0
как кто-то сидит в центре и рисуя круг вокруг себя, в то время как 1,1
как кто-то ходит вокруг центра на расстоянии радиуса и перетаскивает свой мел рядом с ними, если это поможет). Вот код, как выше, но с изменением:
<path
d="
M cx cy
m -r, 0
a r,r 0 1,1 (r * 2),0
a r,r 0 1,1 -(r * 2),0
"
/>
обратитесь к решению Энтони вот функция, чтобы получить путь:
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';
}
совершенно другой подход:
вместо того, чтобы возиться с путями для указания дуги в svg, вы также можете взять элемент circle и указать штрих-dasharray в псевдо-коде:
with $score between 0..1, and pi = 3.141592653589793238
$length = $score * 2 * pi * $r
$max = 7 * $r (i.e. well above 2*pi*r)
<circle r="$r" stroke-dasharray="$length $max" />
его простота является основным преимуществом по сравнению с методом множественной дуги пути (например, при написании сценариев вы подключаете только одно значение, и вы сделали для любой длины дуги)
дуга начинается в самой правой точке и может быть сдвинута с помощью поворота преобразиться.
Примечание: Firefox имеет нечетную ошибку, где вращения более 90 градусов или более игнорируются. Итак, чтобы начать дугу сверху, используйте:
<circle r="$r" transform="rotate(-89.9)" stroke-dasharray="$length $max" />
Adobe Illustrator использует кривые Безье, такие как SVG, и для кругов он создает четыре точки. Вы можете создать круг с двумя команды эллиптической дуги...но тогда для круга в SVG я бы использовал <circle />
:)
Это хорошая идея, что с помощью команды две дуги, чтобы нарисовать полный круг.
обычно я использую элемент эллипса или круга для рисования полного круга.
записывается как функция, это выглядит так:
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";
}
основываясь на ответах Энтони и Антона, я включил способность вращать сгенерированный круг, не влияя на его общий внешний вид. Это полезно, если вы используете путь для анимации и вам нужно контролировать, где он начинается.
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;
}
для таких, как я, которые искали атрибуты эллипса для преобразования пути:
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`
Я сделал jsfiddle, чтобы сделать это здесь:
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))
все, что вам нужно сделать, это изменить ввода консоли.войдите и получите результат в консоли
другой способ-использовать две кубические кривые Безье. Это для людей iOS, использующих pocketSVG который не распознает параметр svg arc.
C x1 y1, x2 y2, x y (или C dx1 dy1, dx2 dy2, dx dy)
последний набор координат здесь (x, y), где вы хотите, чтобы линия заканчивалась. Два других-контрольные точки. (x1, y1) является контрольной точкой для начала вашей кривой и (x2,y2) для конечной точки вашего кривая.
<path d="M25,0 C60,0, 60,50, 25,50 C-10,50, -10,0, 25,0" />
эти ответы слишком сложные.
более простой способ сделать это без создания двух дуг или преобразования в различных системах координат..
это предполагает, что ваша область холста имеет ширину w
и высотой h
.
`M${w*0.5 + radius},${h*0.5}
A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}`
просто используйте флаг "длинная дуга", поэтому заполняется полный флаг. Затем сделайте дуги 99,9999% полным кругом. Визуально это то же самое. Избегайте флага развертки, просто начиная круг в самой правой точке круга (один радиус непосредственно горизонтальный от центра).
эти примеры слишком сложны!!!
просто сделайте это с литералами шаблонов es6.
более простой способ сделать это без создания двух дуг..
предполагается, что область холста имеет ширину w и высоту h.
`M${w*0.5 + radius},${h*0.5}
A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}`
просто используйте флаг "длинная дуга", чтобы заполнить полный флаг. Затем сделайте дуги 99,9999% полным кругом. Визуально это то же самое. Избегайте флага развертки, просто начиная круг в самой правой точке круга (один радиус непосредственно горизонтальный от центра).