Tengo el siguiente 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>
Quiero conseguir un CSS-como border-top-right-radius
y border-top-bottom-radius
efecto.
¿Cómo puedo lograr ese efecto de esquina redondeada?
xml
image
svg
vector-graphics
Danis
fuente
fuente
border-radius
y sus variantes no funcionen en SVG.rx=3
ory=3
redondear las esquinas. developer.mozilla.org/en-US/docs/Web/SVG/Attribute/rxRespuestas:
Así es como puede crear un rectángulo redondeado con 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" />
Explicación
m100,100: mover al punto (100,100)
h200: dibuja una línea horizontal de 200px desde donde estamos
a20,20 0 0 1 20,20: dibuja un arco con un radio X de 20px, un radio Y de 20px, en el sentido de las agujas del reloj, hasta un punto con una diferencia de 20px en los ejes X e Y
v200: dibuja una línea vertical de 200px desde donde estamos
a20,20 0 0 1-20,20: dibuja un arco con un radio de 20px X e Y, en el sentido de las agujas del reloj, hasta un punto con una diferencia de -20px en X y una diferencia de 20px en el eje Y
h-200: dibuja una línea horizontal de -200px desde donde estamos
a20,20 0 0 1-20, -20: dibuja un arco con un radio X e Y de 20px, en el sentido de las agujas del reloj, hasta un punto con una diferencia de -20px en X y una diferencia de -20px en el eje Y
v-200: dibuja una línea vertical de -200px desde donde estamos
a20,20 0 0 1 20, -20: dibuja un arco con un radio X e Y de 20px, en el sentido de las agujas del reloj, hasta un punto con una diferencia de 20px en X y una diferencia de -20px en el eje Y
z: cierra el camino
<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>
fuente
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>
No estoy seguro de por qué nadie publicó una respuesta SVG real. Aquí hay un rectángulo SVG con esquinas redondeadas (radio 3) en la parte superior:
<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" />
Se trata de Mover a (M), Línea a (L), Arco a (A), Línea a (L), Arco a (A), Línea a (L), Cerrar ruta (Z).
Los números delimitados por comas son coordenadas absolutas. Los arcos se definen con parámetros adicionales que especifican el radio y el tipo de arco. Esto también podría lograrse con coordenadas relativas (use letras minúsculas para L y A).
La referencia completa para esos comandos se encuentra en la página W3C SVG Paths , y en este artículo se puede encontrar material de referencia adicional sobre las rutas SVG .
fuente
Como se menciona en mi respuesta a Aplicar esquinas redondeadas a rutas / polígonos , he escrito una rutina en javascript para redondear esquinas genéricamente de rutas SVG, con ejemplos, aquí: http://plnkr.co/edit/kGnGGyoOCKil02k04snu .
Funcionará independientemente de cualquier efecto de accidente cerebrovascular que pueda tener. Para usar, incluya el archivo rounding.js de Plnkr y llame a la función así:
El resultado será el camino redondeado.
Los resultados se ven así:
fuente
Ha configurado explícitamente su
stroke-linejoin
toround
pero sustroke-width
to0
, por lo que, por supuesto , no verá esquinas redondeadas si no tiene trazo para redondear.Aquí hay un ejemplo modificado con esquinas redondeadas hechas a través de trazos:
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" />
De lo contrario, si necesita un relleno de forma redondeada real y no solo un trazo grueso redondeado, debe hacer lo que dice @Jlange y crear una forma redondeada real.
fuente
stroke-linecap
lugar destroke-linejoin
. Esto funciona para mi.También consideraría usar un viejo simple
<rect>
que proporcione los atributosrx
yry
MDN SVG docs <- observe el segundo elemento rect dibujado
fuente
Hoy mismo me encontré con este problema y logré resolverlo escribiendo una pequeña función de JavaScript.
Por lo que puedo decir, no hay una manera fácil de dar un elemento de ruta en un SVG con esquinas redondeadas, excepto si solo necesita que los bordes estén redondeados, en cuyo caso los atributos (CSS)
stroke
,stroke-width
y lo más importantestroke-linejoin="round"
son perfectamente suficientes.Sin embargo, en mi caso utilicé un objeto de ruta para crear formas personalizadas con n esquinas que se rellenan con un color determinado y no tienen bordes visibles, como esto:
Me las arreglé para escribir una función rápida que toma una matriz de coordenadas para una ruta SVG y devuelve la cadena de ruta terminada para poner en el
d
atributo del elemento html de la ruta. La forma resultante se verá así:Aquí está la función:
/** * 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(' '); }
Puede determinar la fuerza del redondeo configurando la variable curveRadius en la parte superior. El valor predeterminado es 3 para un sistema de coordenadas de 100x100 (ventana gráfica), pero dependiendo del tamaño de su SVG, es posible que deba ajustarlo.
fuente
Esta pregunta es el primer resultado para buscar en Google "svg ruta de esquinas redondeadas". Sugerencia de Phrogz para usar
stroke
tiene algunas limitaciones (es decir, que no puedo usar el trazo para otros fines y que las dimensiones deben corregirse para el ancho del trazo).La sugerencia de Jlange de usar una curva es mejor, pero no muy concreta. Terminé usando curvas cuadráticas de Bézier para dibujar esquinas redondeadas. Considere esta imagen de una esquina marcada con un punto azul y dos puntos rojos en los bordes adyacentes:
Las dos líneas se pueden hacer con el
L
comando. Para convertir esta esquina afilada en una esquina redondeada, comience a dibujar una curva desde el punto rojo izquierdo (useM x,y
para moverse a ese punto). Ahora, una curva de Bézier cuadrática tiene un solo punto de control que debe establecer en el punto azul. Establezca el final de la curva en el punto rojo de la derecha. Como la tangente en los dos puntos rojos está en la dirección de las líneas anteriores, verá una transición fluida, "esquinas redondeadas".Ahora, para continuar la forma después de la esquina redondeada, se puede lograr una línea recta en una curva de Bézier estableciendo el punto de control entre en la línea entre las dos esquinas.
Para ayudarme a determinar la ruta, escribí este script de Python que acepta bordes y un radio. La matemática vectorial hace que esto sea realmente muy fácil. La imagen resultante de la salida:
#!/usr/bin/env python # Given some vectors and a border-radius, output a SVG path with rounded # corners. # # Copyright (C) Peter Wu <[email protected]> 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)
fuente
A continuación, se muestran algunas rutas para las pestañas:
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>
Las otras respuestas explicaron la mecánica. Me gustó especialmente la respuesta de hossein-maktoobian.
Las rutas en la pluma hacen la mayor parte del trabajo, los valores se pueden modificar para adaptarse a las dimensiones deseadas.
fuente
Encontré una solución, pero es un poco engañosa, por lo que puede que no siempre funcione. Descubrí que si tiene un arco (A o a) con valores realmente pequeños, lo obliga a crear una curva en un punto, formando así una esquina redondeada ...
<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>
fuente
Solo para simplificar la implementación de la respuesta de @ hmak.me, aquí hay un fragmento comentado de código React para generar rectángulos redondeados.
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'), );
Enlace jsfiddle.
fuente
<?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>'; } ?>
fuente
Está utilizando un elemento de ruta, ¿por qué no le da una curva a la ruta? Vea aquí cómo hacer curvas usando elementos de ruta: http://www.w3.org/TR/SVG/paths.html#PathDataCurveCommands
fuente