Ich habe die folgende 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>
Ich möchte ein CSS-ähnliches border-top-right-radius
und border-top-bottom-radius
effektives Ergebnis erzielen.
Wie kann ich diesen Effekt mit abgerundeten Ecken erzielen?
xml
image
svg
vector-graphics
Danis
quelle
quelle
border-radius
und seine Varianten in SVG nicht funktionieren.rx=3
oderry=3
abrunden. developer.mozilla.org/en-US/docs/Web/SVG/Attribute/rxAntworten:
So können Sie mit SVG Path ein abgerundetes Rechteck erstellen:
<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" />
Erläuterung
m100,100: gehe zum Punkt (100,100)
h200: Zeichne eine horizontale Linie von 200 Pixel von dort, wo wir sind
a20,20 0 0 1 20,20: Zeichnen Sie einen Bogen mit einem Radius von 20 x X und einem Radius von 20 x Y im Uhrzeigersinn zu einem Punkt mit einem Unterschied von 20 x in der X- und Y-Achse
v200: Zeichnen Sie eine vertikale 200-Pixel- Linie von dort, wo wir uns befinden
a20,20 0 0 1 -20,20: Zeichnen Sie einen Bogen mit einem X- und Y-Radius von 20 Pixel im Uhrzeigersinn zu einem Punkt mit einem Unterschied von -20 Pixel in X und einem Unterschied von 20 Pixel in der Y-Achse
h-200: Zeichnen Sie eine horizontale Linie von -200 Pixel von dort, wo wir uns befinden
a20,20 0 0 1 -20, -20: Zeichnen Sie einen Bogen mit einem X- und Y-Radius von 20 Pixel im Uhrzeigersinn zu einem Punkt mit einem Unterschied von -20 Pixel in X und einem Unterschied von -20 Pixel in Y
v-200: Zeichnen Sie eine vertikale Linie von -200 Pixel von dort, wo wir uns befinden
a20,20 0 0 1 20, -20: Zeichnen Sie einen Bogen mit einem X- und Y-Radius von 20 Pixel im Uhrzeigersinn zu einem Punkt mit einer Differenz von 20 Pixel in X und einer Differenz von 20 Pixel in der Y-Achse
z: Schließen Sie den Pfad
<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>
quelle
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 zu verwenden = "100" rx = "15" style = "Strich: # 000000; Füllung: #FFFFFF" /> `</svg>
Ich bin mir nicht sicher, warum niemand eine tatsächliche SVG-Antwort gepostet hat. Hier ist ein SVG-Rechteck mit abgerundeten Ecken (Radius 3) oben:
<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" />
Dies ist eine Verschiebung nach (M), Linie nach (L), Bogen nach (A), Linie nach (L), Bogen nach (A), Linie nach (L), Pfad schließen (Z).
Die durch Kommas getrennten Zahlen sind absolute Koordinaten. Die Bögen werden mit zusätzlichen Parametern definiert, die den Radius und die Art des Bogens angeben. Dies könnte auch mit relativen Koordinaten erreicht werden (verwenden Sie Kleinbuchstaben für L und A).
Die vollständige Referenz für diese Befehle finden Sie auf der Seite W3C- SVG-Pfade. Zusätzliches Referenzmaterial zu SVG-Pfaden finden Sie in diesem Artikel .
quelle
Wie in meiner Antwort zum Anwenden abgerundeter Ecken auf Pfade / Polygone erwähnt , habe ich eine Routine in Javascript zum generischen Runden von Ecken von SVG-Pfaden mit Beispielen hier geschrieben: http://plnkr.co/edit/kGnGGyoOCKil02k04snu .
Es funktioniert unabhängig von eventuellen Schlaganfällen. Fügen Sie zur Verwendung die Datei rounding.js aus dem Plnkr hinzu und rufen Sie die Funktion folgendermaßen auf:
Das Ergebnis ist der abgerundete Pfad.
Die Ergebnisse sehen folgendermaßen aus:
quelle
Sie haben explizit Ihr
stroke-linejoin
auf,round
aber Ihrstroke-width
auf festgelegt0
, sodass Sie natürlich keine abgerundeten Ecken sehen, wenn Sie keinen Strich zum Runden haben.Hier ist ein modifiziertes Beispiel mit abgerundeten Ecken, die durch Striche erstellt wurden:
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" />
Andernfalls müssen Sie - wenn Sie eine tatsächlich abgerundete Formfüllung und nicht nur einen abgerundeten Fettstrich benötigen - das tun, was @Jlange sagt, und eine tatsächlich abgerundete Form erstellen.
quelle
stroke-linecap
anstelle von verwendenstroke-linejoin
. Für mich geht das.Ich würde auch in Betracht ziehen, ein einfaches altes zu verwenden
<rect>
, das dierx
undry
Attribute bereitstelltMDN SVG docs <- Beachten Sie das zweite gezeichnete Rect-Element
quelle
Ich bin heute selbst auf dieses Problem gestoßen und habe es geschafft, es durch Schreiben einer kleinen JavaScript-Funktion zu lösen.
Von dem, was ich sagen kann, gibt es keine einfache Möglichkeit , ein Pfadelement in einer SVG zu geben abgerundeten Ecken , außer wenn Sie brauchen nur die Grenzen gerundet werden, wobei in diesem Fall die (CSS) Attribute
stroke
,stroke-width
und vor allemstroke-linejoin="round"
ist vollkommen ausreichend.In meinem Fall habe ich jedoch ein Pfadobjekt verwendet, um benutzerdefinierte Formen mit n Ecken zu erstellen , die mit einer bestimmten Farbe ausgefüllt sind und keine sichtbaren Ränder haben, ähnlich wie folgt:
Ich habe es geschafft, eine Schnellfunktion zu schreiben, die ein Array von Koordinaten für einen SVG-Pfad verwendet und die fertige Pfadzeichenfolge zurückgibt, um sie in das
d
Attribut des Pfad-HTML-Elements einzufügen. Die resultierende Form sieht dann ungefähr so aus:Hier ist die Funktion:
/** * 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(' '); }
Sie können die Rundungsstärke bestimmen, indem Sie die Variable edgeRadius oben einstellen . Der Standardwert ist 3 für ein Koordinatensystem mit 100 x 100 (Ansichtsfenster). Abhängig von der Größe Ihres SVG müssen Sie dies möglicherweise anpassen.
quelle
Diese Frage ist das erste Ergebnis für Googeln "svg abgerundete Ecken Pfad". Der Vorschlag von Phrogz zur Verwendung
stroke
weist einige Einschränkungen auf (nämlich, dass ich den Strich nicht für andere Zwecke verwenden kann und dass die Abmessungen für die Strichbreite korrigiert werden müssen).Jlange Vorschlag, eine Kurve zu verwenden, ist besser, aber nicht sehr konkret. Am Ende habe ich quadratische Bézier-Kurven zum Zeichnen abgerundeter Ecken verwendet. Betrachten Sie dieses Bild einer Ecke, die mit einem blauen Punkt und zwei roten Punkten an benachbarten Kanten markiert ist:
Die zwei Zeilen könnten mit dem
L
Befehl erstellt werden. Um diese scharfe Ecke in eine abgerundete Ecke zu verwandeln, zeichnen Sie eine Kurve vom linken roten Punkt (verwenden SieM x,y
diese Option, um zu diesem Punkt zu gelangen). Jetzt hat eine quadratische Bézier-Kurve nur einen einzigen Kontrollpunkt, den Sie auf den blauen Punkt setzen müssen. Setzen Sie das Ende der Kurve auf den rechten roten Punkt. Da die Tangente an den beiden roten Punkten in Richtung der vorherigen Linien verläuft, sehen Sie einen fließenden Übergang, "abgerundete Ecken".Um nun die Form nach der abgerundeten Ecke fortzusetzen, kann eine gerade Linie in einer Bézier-Kurve erreicht werden, indem der Kontrollpunkt zwischen auf der Linie zwischen den beiden Ecken festgelegt wird.
Um mir bei der Ermittlung des Pfads zu helfen, habe ich dieses Python-Skript geschrieben, das Kanten und einen Radius akzeptiert. Vektormathematik macht dies eigentlich sehr einfach. Das resultierende Bild aus der Ausgabe:
#!/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)
quelle
Hier sind einige Pfade für Registerkarten:
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>
Die anderen Antworten erklärten die Mechanik. Besonders gut hat mir die Antwort von Hossein-Maktoobian gefallen.
Die Pfade im Stift machen die Hauptlast der Arbeit. Die Werte können so geändert werden, dass sie den gewünschten Abmessungen entsprechen.
quelle
Ich habe eine Lösung gefunden, aber sie ist etwas hackig, sodass sie möglicherweise nicht immer funktioniert. Ich fand heraus, dass ein Bogen (A oder a) mit wirklich kleinen Werten ihn zwingt, an einer Stelle eine Kurve zu erstellen, wodurch eine abgerundete Ecke entsteht ...
<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>
quelle
Um die Implementierung der Antwort von @ hmak.me zu vereinfachen, finden Sie hier einen kommentierten Teil des React-Codes zum Generieren abgerundeter Rechtecke.
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 Link.
quelle
<?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>'; } ?>
quelle
Sie verwenden ein Pfadelement. Warum geben Sie dem Pfad nicht einfach eine Kurve? Hier erfahren Sie, wie Sie mithilfe von Pfadelementen Kurven erstellen: http://www.w3.org/TR/SVG/paths.html#PathDataCurveCommands
quelle