У меня такой SVG:
<svg>
<g>
<path id="k9ffd8001" d="M64.5 45.5 82.5 45.5 82.5 64.5 64.5 64.5 z" stroke="#808600" stroke-width="0" transform="rotate(0 0 0)" stroke-linecap="square" stroke-linejoin="round" fill-opacity="1" stroke-opacity="1" fill="#a0a700"></path>
<path id="kb8000001" d="M64.5 45.5 82.5 45.5 82.5 64.5 64.5 64.5 z" stroke="#808600" stroke-width="0" transform="rotate(0 0 0)" stroke-linecap="square" stroke-linejoin="round" fill-opacity="1" stroke-opacity="1" fill="url(#k9ffb0001)"></path>
</g>
</svg>
Я хочу , чтобы получить CSS-как border-top-right-radius
и border-top-bottom-radius
эффект.
Как добиться эффекта закругленных углов?
xml
image
svg
vector-graphics
Данис
источник
источник
border-radius
и его варианты не работают в SVG.rx=3
илиry=3
скруглить углы. developer.mozilla.org/en-US/docs/Web/SVG/Attribute/rxОтветы:
Вот как можно создать прямоугольник с закругленными углами с помощью SVG Path:
<path d="M100,100 h200 a20,20 0 0 1 20,20 v200 a20,20 0 0 1 -20,20 h-200 a20,20 0 0 1 -20,-20 v-200 a20,20 0 0 1 20,-20 z" />
Объяснение
m100,100: перейти к точке (100,100)
h200: нарисуйте горизонтальную линию 200 пикселей от того места, где мы находимся
a20,20 0 0 1 20,20: нарисуйте дугу с радиусом 20 пикселей по оси X, радиусом по оси Y 20 пикселей по часовой стрелке до точки с разницей в 20 пикселей по осям X и Y
v200: нарисуйте вертикальную линию 200 пикселей от того места, где мы находимся
a20,20 0 0 1 -20,20: нарисуйте дугу с радиусом 20 пикселей по X и Y по часовой стрелке до точки с разницей в -20 пикселей по X и разницей в 20 пикселей по оси Y
h-200: нарисуйте горизонтальную линию -200 пикселей от того места, где мы находимся
a20,20 0 0 1 -20, -20: нарисуйте дугу с радиусом 20 пикселей по X и Y, по часовой стрелке, до точки с разницей -20 пикселей по X и -20 пикселей по оси Y
v-200: нарисуйте вертикальную линию -200 пикселей от того места, где мы находимся
a20,20 0 0 1 20, -20: нарисуйте дугу с радиусом 20 пикселей по X и Y, по часовой стрелке, до точки с разницей в 20 пикселей по оси X и -20 пикселей по оси Y
z: закрыть путь
<svg width="440" height="440"> <path d="M100,100 h200 a20,20 0 0 1 20,20 v200 a20,20 0 0 1 -20,20 h-200 a20,20 0 0 1 -20,-20 v-200 a20,20 0 0 1 20,-20 z" fill="none" stroke="black" stroke-width="3" /> </svg>
источник
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
( developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths )<svg viewBox="0 0 110 110" xmlns="http://www.w3.org/2000/svg">
`<rect x =" 5 "y =" 5 "width =" 100 "height = "100" rx = "15" style = "stroke: # 000000; fill: #FFFFFF" /> `</svg>
Не уверен, почему никто не опубликовал фактический ответ SVG. Вот прямоугольник SVG с закругленными углами (радиус 3) вверху:
<svg:path d="M0,0 L0,27 A3,3 0 0,0 3,30 L7,30 A3,3 0 0,0 10,27 L10,0 Z" />
Это перемещение к (M), линия до (L), дуга до (A), линия до (L), дуга до (A), линия до (L), закрытый путь (Z).
Числа, разделенные запятыми, являются абсолютными координатами. Дуги определяются с дополнительными параметрами, определяющими радиус и тип дуги. Это также можно сделать с помощью относительных координат (используйте строчные буквы для L и A).
Полный справочник по этим командам находится на странице W3C SVG Paths , а дополнительные справочные материалы по SVG-путям можно найти в этой статье .
источник
Как упоминалось в моем ответе на вопрос « Применение закругленных углов к путям / многоугольникам» , я написал процедуру на javascript для общего скругления углов путей SVG с примерами здесь: http://plnkr.co/edit/kGnGGyoOCKil02k04snu .
Он будет работать независимо от любых эффектов удара, которые у вас могут быть. Для использования подключите файл rounding.js из Plnkr и вызовите функцию следующим образом:
В результате получится закругленный путь.
Результаты выглядят так:
источник
Вы явно указали
stroke-linejoin
на,round
но неstroke-width
на0
, поэтому, конечно, вы не увидите закругленных углов, если у вас нет обводки для округления.Вот модифицированный пример с закругленными углами, нанесенными штрихами:
http://jsfiddle.net/8uxqK/1/
<path d="M64.5 45.5 82.5 45.5 82.5 64.5 64.5 64.5 z" stroke-width="5" stroke-linejoin="round" stroke="#808600" fill="#a0a700" />
В противном случае - если вам нужна фактическая заливка закругленной формы, а не просто закругленная жирная обводка - вы должны сделать то, что говорит @Jlange, и создать фактическую закругленную форму.
источник
stroke-linecap
вместоstroke-linejoin
. Меня устраивает.Я бы также рассмотреть возможность использования простой старый ,
<rect>
который обеспечиваетrx
иry
атрибутыMDN SVG docs <- обратите внимание на второй нарисованный прямоугольный элемент
источник
Сегодня я сам столкнулся с этой проблемой, и мне удалось решить ее, написав небольшую функцию JavaScript.
Насколько я могу судить, нет простого способа предоставить элемент пути в закругленных углах SVG, кроме случаев, когда вам нужно только округлить границы, и в этом случае атрибутов (CSS)
stroke
,stroke-width
а самое главноеstroke-linejoin="round"
, вполне достаточно.Однако в моем случае я использовал объект пути для создания пользовательских фигур с n углами, которые заполнены определенным цветом и не имеют видимых границ, примерно так:
Мне удалось написать быструю функцию, которая принимает массив координат для пути SVG и возвращает готовую строку пути для вставки в
d
атрибут элемента пути html. Результирующая форма будет выглядеть примерно так:Вот функция:
/** * Creates a coordinate path for the Path SVG element with rounded corners * @param pathCoords - An array of coordinates in the form [{x: Number, y: Number}, ...] */ function createRoundedPathString(pathCoords) { const path = []; const curveRadius = 3; // Reset indexes, so there are no gaps pathCoords = pathCoords.slice(); for (let i = 0; i < pathCoords.length; i++) { // 1. Get current coord and the next two (startpoint, cornerpoint, endpoint) to calculate rounded curve const c2Index = ((i + 1) > pathCoords.length - 1) ? (i + 1) % pathCoords.length : i + 1; const c3Index = ((i + 2) > pathCoords.length - 1) ? (i + 2) % pathCoords.length : i + 2; const c1 = pathCoords[i]; const c2 = pathCoords[c2Index]; const c3 = pathCoords[c3Index]; // 2. For each 3 coords, enter two new path commands: Line to start of curve, bezier curve around corner. // Calculate curvePoint c1 -> c2 const c1c2Distance = Math.sqrt(Math.pow(c1.x - c2.x, 2) + Math.pow(c1.y - c2.y, 2)); const c1c2DistanceRatio = (c1c2Distance - curveRadius) / c1c2Distance; const c1c2CurvePoint = [ ((1 - c1c2DistanceRatio) * c1.x + c1c2DistanceRatio * c2.x).toFixed(1), ((1 - c1c2DistanceRatio) * c1.y + c1c2DistanceRatio * c2.y).toFixed(1) ]; // Calculate curvePoint c2 -> c3 const c2c3Distance = Math.sqrt(Math.pow(c2.x - c3.x, 2) + Math.pow(c2.y - c3.y, 2)); const c2c3DistanceRatio = curveRadius / c2c3Distance; const c2c3CurvePoint = [ ((1 - c2c3DistanceRatio) * c2.x + c2c3DistanceRatio * c3.x).toFixed(1), ((1 - c2c3DistanceRatio) * c2.y + c2c3DistanceRatio * c3.y).toFixed(1) ]; // If at last coord of polygon, also save that as starting point if (i === pathCoords.length - 1) { path.unshift('M' + c2c3CurvePoint.join(',')); } // Line to start of curve (L endcoord) path.push('L' + c1c2CurvePoint.join(',')); // Bezier line around curve (Q controlcoord endcoord) path.push('Q' + c2.x + ',' + c2.y + ',' + c2c3CurvePoint.join(',')); } // Logically connect path to starting point again (shouldn't be necessary as path ends there anyway, but seems cleaner) path.push('Z'); return path.join(' '); }
Вы можете определить силу округления, установив переменную curveRadius вверху. Значение по умолчанию - 3 для системы координат 100x100 (область просмотра), но в зависимости от размера вашего SVG вам может потребоваться настроить это.
источник
Этот вопрос является первым результатом поиска в Google "пути с закругленными углами svg". Предложение Phrogz для использования
stroke
имеет некоторые ограничения (а именно, что я не могу использовать штрих для других целей и что размеры должны быть скорректированы с учетом ширины штриха).Предложение Jlange использовать кривую лучше, но не очень конкретное. В итоге я использовал квадратичные кривые Безье для рисования закругленных углов. Рассмотрим это изображение угла, отмеченного синей точкой и двумя красными точками на смежных краях:
Две строчки можно создать с помощью
L
команды. Чтобы превратить этот острый угол в закругленный, начните рисовать кривую от левой красной точки (используйтеM x,y
для перехода к этой точке). Теперь у квадратичной кривой Безье есть только одна контрольная точка, которую вы должны установить на синей точке. Установите конец кривой в правой красной точке. Поскольку касательная к двум красным точкам направлена в направлении предыдущих линий, вы увидите плавный переход, «закругленные углы».Теперь, чтобы продолжить форму после закругленного угла, можно получить прямую линию кривой Безье, установив контрольную точку между ними на линии между двумя углами.
Чтобы помочь мне определить путь, я написал этот скрипт Python, который принимает края и радиус. Векторная математика делает это на самом деле очень просто. Полученное изображение из вывода:
#!/usr/bin/env python # Given some vectors and a border-radius, output a SVG path with rounded # corners. # # Copyright (C) Peter Wu <peter@lekensteyn.nl> from math import sqrt class Vector(object): def __init__(self, x, y): self.x = x self.y = y def sub(self, vec): return Vector(self.x - vec.x, self.y - vec.y) def add(self, vec): return Vector(self.x + vec.x, self.y + vec.y) def scale(self, n): return Vector(self.x * n, self.y * n) def length(self): return sqrt(self.x**2 + self.y**2) def normal(self): length = self.length() return Vector(self.x / length, self.y / length) def __str__(self): x = round(self.x, 2) y = round(self.y, 2) return '{},{}'.format(x, y) # A line from vec_from to vec_to def line(vec_from, vec_to): half_vec = vec_from.add(vec_to.sub(vec_from).scale(.5)) return '{} {}'.format(half_vec, vec_to) # Adds 'n' units to vec_from pointing in direction vec_to def vecDir(vec_from, vec_to, n): return vec_from.add(vec_to.sub(vec_from).normal().scale(n)) # Draws a line, but skips 'r' units from the begin and end def lineR(vec_from, vec_to, r): vec = vec_to.sub(vec_from).normal().scale(r) return line(vec_from.add(vec), vec_to.sub(vec)) # An edge in vec_from, to vec_to with radius r def edge(vec_from, vec_to, r): v = vecDir(vec_from, vec_to, r) return '{} {}'.format(vec_from, v) # Hard-coded border-radius and vectors r = 5 a = Vector( 0, 60) b = Vector(100, 0) c = Vector(100, 200) d = Vector( 0, 200 - 60) path = [] # Start below top-left edge path.append('M {} Q'.format(a.add(Vector(0, r)))) # top-left edge... path.append(edge(a, b, r)) path.append(lineR(a, b, r)) path.append(edge(b, c, r)) path.append(lineR(b, c, r)) path.append(edge(c, d, r)) path.append(lineR(c, d, r)) path.append(edge(d, a, r)) path.append(lineR(d, a, r)) # Show results that can be pushed into a <path d="..." /> for part in path: print(part)
источник
Вот несколько путей для вкладок:
https://codepen.io/mochime/pen/VxxzMW
<!-- left tab --> <div> <svg width="60" height="60"> <path d="M10,10 a10 10 0 0 1 10 -10 h 50 v 47 h -50 a10 10 0 0 1 -10 -10 z" fill="#ff3600"></path> </svg> </div> <!-- right tab --> <div> <svg width="60" height="60"> <path d="M10 0 h 40 a10 10 0 0 1 10 10 v 27 a10 10 0 0 1 -10 10 h -40 z" fill="#ff3600"></path> </svg> </div> <!-- tab tab :) --> <div> <svg width="60" height="60"> <path d="M10,40 v -30 a10 10 0 0 1 10 -10 h 30 a10 10 0 0 1 10 10 v 30 z" fill="#ff3600"></path> </svg> </div>
Другие ответы объясняли механику. Мне особенно понравился ответ Хоссейна-мактубяна.
Пути в ручке делают основную работу, значения могут быть изменены, чтобы соответствовать любым желаемым размерам.
источник
Я нашел решение, но оно немного взломано, поэтому не всегда может работать. Я обнаружил, что если у вас есть дуга (A или a) с очень маленькими значениями, она заставляет ее создавать кривую в одном месте, образуя закругленный угол ...
<svg viewBox="0 0 1 0.6" stroke="black" fill="grey" style="stroke-width:0.05px;"> <path d="M0.7 0.2 L0.1 0.1 A0.0001 0.0001 0 0 0 0.099 0.101 L0.5 0.5Z"></path> </svg>
источник
Чтобы упростить реализацию ответа @ hmak.me, вот прокомментированный фрагмент кода React для создания закругленных прямоугольников.
const Rect = ({width, height, round, strokeWidth}) => { // overhang over given width and height that we get due to stroke width const s = strokeWidth / 2; // how many pixels do we need to cut from vertical and horizontal parts // due to rounded corners and stroke width const over = 2 * round + strokeWidth; // lengths of straight lines const w = width - over; const h = height - over; // beware that extra spaces will not be minified // they are added for clarity const d = ` M${round + s},${s} h${w} a${round},${round} 0 0 1 ${round},${round} v${h} a${round},${round} 0 0 1 -${round},${round} h-${w} a${round},${round} 0 0 1 -${round},-${round} v-${h} a${round},${round} 0 0 1 ${round},-${round} z `; return ( <svg width={width} height={height}> <path d={d} fill="none" stroke="black" strokeWidth={strokeWidth} /> </svg> ); }; ReactDOM.render( <Rect width={64} height={32} strokeWidth={2} round={4} />, document.querySelector('#app'), );
Ссылка Jsfiddle.
источник
Это в основном делает то же самое, что и ответ Mvins , но является более сжатой и упрощенной версией. Он работает, возвращаясь на расстояние радиуса линий, прилегающих к углу, и соединяя оба конца кривой Безье, контрольная точка которой находится в исходной угловой точке.
function createRoundedPath(coords, radius, close) { let path = "" const length = coords.length + (close ? 1 : -1) for (let i = 0; i < length; i++) { const a = coords[i % coords.length] const b = coords[(i + 1) % coords.length] const t = Math.min(radius / Math.hypot(b.x - a.x, b.y - a.y), 0.5) if (i > 0) path += `Q${a.x},${a.y} ${a.x * (1 - t) + b.x * t},${a.y * (1 - t) + b.y * t}` if (!close && i == 0) path += `M${a.x},${a.y}` else if (i == 0) path += `M${a.x * (1 - t) + b.x * t},${a.y * (1 - t) + b.y * t}` if (!close && i == length - 1) path += `L${b.x},${b.y}` else if (i < length - 1) path += `L${a.x * t + b.x * (1 - t)},${a.y * t + b.y * (1 - t)}` } if (close) path += "Z" return path }
источник
<?php $radius = 20; $thichness = 4; $size = 200; if($s == 'circle'){ echo '<svg width="' . $size . '" height="' . $size . '">'; echo '<circle cx="' . ($size/2) . '" cy="' . ($size/2) . '" r="' . (($size/2)-$thichness) . '" stroke="black" stroke-width="' . $thichness . '" fill="none" />'; echo '</svg>'; }elseif($s == 'square'){ echo '<svg width="' . $size . '" height="' . $size . '">'; echo '<path d="M' . ($radius+$thichness) . ',' . ($thichness) . ' h' . ($size-($radius*2)-($thichness*2)) . ' a' . $radius . ',' . $radius . ' 0 0 1 ' . $radius . ',' . $radius . ' v' . ($size-($radius*2)-($thichness*2)) . ' a' . $radius . ',' . $radius . ' 0 0 1 -' . $radius . ',' . $radius . ' h-' . ($size-($radius*2)-($thichness*2)) . ' a' . $radius . ',' . $radius . ' 0 0 1 -' . $radius . ',-' . $radius . ' v-' . ($size-($radius*2)-($thichness*2)) . ' a' . $radius . ',' . $radius . ' 0 0 1 ' . $radius . ',-' . $radius . ' z" fill="none" stroke="black" stroke-width="' . $thichness . '" />'; echo '</svg>'; } ?>
источник
Вы используете элемент контура, почему бы просто не придать контуру кривую? См. Здесь, как создавать кривые с использованием элементов пути: http://www.w3.org/TR/SVG/paths.html#PathDataCurveCommands
источник