Рисование окружности с помощью пути дуги 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.99999999% круга, то ничего не будет показывать вообще?
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 " />
трюк состоит в том, чтобы иметь две дуги, вторая из которых поднимается там, где первая остановилась, и использует отрицательный диаметр, чтобы вернуться к исходной дуге начальная точка.
причина, по которой это не может быть сделано как полный круг в одной дуге (и я просто размышляю), заключается в том, что вы скажете ему нарисовать дугу от себя (скажем, 150,150) к себе (150,150), что он отображает как "о, я уже там, нет дуги!".
преимущества решения, которое я предлагаю:
- это легко перевести из круга непосредственно в путь, и
- нет перекрытия в двух дуговых линиях (которые может вызвать проблемы, если вы используете маркеры или узоры и т. д.). Это чистая непрерывная линия, хотя и нарисованная в двух частях.
ничего из этого не имело бы значения, если бы они просто позволяли 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 и указать stroke-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% полного круга. Визуально это то же самое. Избегайте флага развертки, просто начиная круг в самой правой точке круга (один радиус непосредственно горизонтальный от центра).