Подтвердить что ты не робот

Нарисуйте полый круг в SVG

Я не уверен, как подойти к рисованию полого круга в SVG.

Мне нужна форма кольца, заполненная цветом, а затем черная контур.

То, как я думал об этом, было 2 круга, один с меньшим радиусом, чем другой. Проблема в том, когда я их заполняю, как сделать меньший круг тем же цветом заливки, что и на нем?

4b9b3361

Ответ 1

Просто используйте fill="none", и тогда будет нарисован только stroke (контур).

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
   <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="none" />
</svg> 

Ответ 2

Благодаря Chasbeen я понял, как сделать настоящий звонок/пончик в SVG. Обратите внимание, что внешний круг на самом деле не закрыт, что видно только при использовании обводки. Очень полезно, когда у вас много концентрических колец, особенно если они интерактивные (например, с помощью CSS-команд при наведении курсора).

Для команды рисования...

M cx, cy // Move to center of ring
m 0, -outerRadius // Move to top of ring
a outerRadius, outerRadius, 0, 1, 0, 1, 0 // Draw outer arc, but don't close it
Z // default fill-rule:even-odd will help create the empty innards
m 0 outerRadius-innerRadius // Move to top point of inner radius
a innerRadius, innerRadius, 0, 1, 1, -1, 0 // Draw inner arc, but don't close it
Z // Close the inner ring. Actually will still work without, but inner ring will have one unit missing in stroke       

JSFiddle - содержит несколько колец и CSS для имитации интерактивности. Обратите внимание на обратную сторону: в начальной точке (вверху) отсутствует один пиксель, который присутствует только при добавлении обводки.

Редактировать: Нашел этот ТАК ответ (а еще лучше этот ответ), в котором описано, как получить пустые внутренние данные в целом.

Ответ 3

Ответ MDragon00 работает, но внутренний и внешний круги не идеально выровнены (например, центрированы).

Я немного изменил свой подход, используя 4 полукруглых дуги (2 внешних и 2 внутренних в обратном направлении), чтобы точно выравнивать выравнивание.

<svg width="100" height="100">
  <path d="M 50 10 A 40 40 0 1 0 50 90 A 40 40 0 1 0 50 10 Z M 50 30 A 20 20 0 1 1 50 70 A 20 20 0 1 1 50 30 Z" fill="#0000dd" stroke="#00aaff" stroke-width="3" />
</svg>

<!--

Using this path definition as d:

M centerX (centerY-outerRadius)
A outerRadius outerRadius 0 1 0 centerX (centerY+outerRadius)
A outerRadius outerRadius 0 1 0 centerX (centerY-outerRadius)
Z
M centerX (centerY-innerRadius)
A innerRadius innerRadius 0 1 1 centerX (centerY+innerRadius)
A innerRadius innerRadius 0 1 1 centerX (centerY-innerRadius)
Z

-->

Ответ 4

Это классическая форма пончика Я не уверен, если вы пытаетесь достичь этого с помощью стандартного SVG или JavaScript, который производит SVG Эта цель может быть достигнута путем включения относительной команды "moveto" в определение одного пути

И нажмите "дырки от бублика" в правой части интерактивных примеров. По крайней мере, вы можете увидеть определение пути, который сделал красный пончик.

Ответ 5

Вы можете сделать это в соответствии со спецификацией SVG, используя путь с двумя компонентами и fill-rule = "evenodd". Эти два компонента представляют собой полукруглые дуги, которые соединяются в круг (в атрибуте "d" ниже они заканчиваются буквой "z"). Область внутри внутреннего круга не считается частью фигуры, поэтому интерактивность хорошая.

Чтобы немного расшифровать нижнее, "340 260" - это верхняя середина внешнего круга, "290 290" - радиус внешнего круга (дважды), "340 840" - нижняя середина внешнего круга. "340 492" - это верхняя середина внутреннего круга, "58 58" - радиус внутреннего круга (дважды), а "340 608" - нижняя середина внутреннего круга.

<svg viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg">
    <path fill-rule="evenodd" d="M340 260A290 290 0 0 1 340 840A290 290 0 0 1 340 260zM340 492A58 58 0 0 1 340 608A58 58 0 0 1 340 492z" stroke-width="4" stroke="rgb(0,0,0)" fill="rgb(0,0,255)">
        <title>This will only display on the donut</title>
    </path>
</svg>

Ответ 6

Вот рутина для создания дуги безье, которая находится так близко, что не имеет никакого отношения к кругу. Вам нужно четыре из них в пути для полного круга.

 BezierCurve BezierArc(double ox, double oy, double r, double thetaa, double thetab)
    {
        double theta;
        double cpx[4];
        double cpy[4];
        int i;
        int sign = 1;

        while (thetaa > thetab)
            thetab += 2 * Pi;
        theta = thetab - thetaa;
        if (theta > Pi)
        {
            theta = 2 * Pi - theta;
            sign = -1;
        }
        cpx[0] = 1;
        cpy[0] = 0;
        cpx[1] = 1;
        cpy[1] = 4.0 / 3.0 * tan(theta / 4);
        cpx[2] = cos(theta) + cpy[1] * sin(theta);
        cpy[2] = sin(theta) - cpy[1] * cos(theta);
        cpx[3] = cos(theta);
        cpy[3] = sin(theta);
        cpy[1] *= sign;
        cpy[2] *= sign;
        cpy[3] *= sign;

        for (i = 0; i < 4; i++)
        {
            double xp = cpx[i] * cos(thetaa) + cpy[i] * -sin(thetaa);
            double yp = cpx[i] * sin(thetaa) + cpy[i] * cos(thetaa);
            cpx[i] = xp;
            cpy[i] = yp;
            cpx[i] *= r;
            cpy[i] *= r;
            cpx[i] += ox;
            cpy[i] += oy;
        }

        return BezierCurve({cpx[0], cpy[0]},{cpx[1], cpy[1]}, {cpx[2], cpy[2]}, {cpx[3], cpy[3]});
    }