Wie würde ich eine SVG-Form füllen, nicht mit einer einzelnen Farbe, einem Bild oder einem Farbverlauf, sondern mit einem Schraffurmuster, wenn möglich diagonal.
Es ist 2 Stunden her und ich habe nichts gefunden (zumindest nach 2005).
Ich denke, ein möglicher Hack wäre ein schraffiertes PNG, das als Füllung dienen würde, aber das ist nicht ideal.
Antworten:
Ich habe auch im Internet nichts für diagonale Schraffuren gefunden, daher werde ich meine Lösung hier teilen:
<pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4"> <path d="M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2" style="stroke:black; stroke-width:1" /> </pattern>
(Beachten Sie den Kleinbuchstaben "l" im Pfadausdruck)
Das Obige erzeugt eine Schraffur mit diagonalen Linien von links unten nach rechts oben, die 4 Pixel voneinander entfernt sind. Neben der diagonalen Linie (
M0,4 l4,-4
) müssen Sie auch den oberen linken und den unteren rechten Rand des Musterbereichs streichen, da die Linie sonst aufgrund von Übersteuerungen, die die Kanten des Quadrats schneiden, "eingeengt" wird.Um ein Rechteck mit diesem Muster zu füllen, gehen Sie wie folgt vor:
<rect x="0" y="0" width="100%" height="100%" fill="url(#diagonalHatch)"/>
quelle
M 0 0 L 20 20 M 10 -10 L 30 10 M -10 10 L 10 30
.shape-rendering="cripsEdges"
.M-1,1 l2,-2 M0,10 l10,-10 M9,11 l2,-2
Verwenden Sie das Attribut patternTransform, um ein vertikales (oder horizontales) Liniensegment zu drehen. Diese Methode kachelt nahtlos und verwendet den einfachsten Pfad. Das Musterattribut
width
steuert, wie eng parallele Schraffuren sind.<pattern id="diagonalHatch" width="10" height="10" patternTransform="rotate(45 0 0)" patternUnits="userSpaceOnUse"> <line x1="0" y1="0" x2="0" y2="10" style="stroke:black; stroke-width:1" /> </pattern>
quelle
width
Musterattribut legt den Abstand zwischen den Streifen fest). Um es noch einfacher zu machen, würde ich<line x1="0" y1="0" x2="0" y2="2" style="stroke:black; stroke-width:1" />
anstelle von verwenden<g>...</g>
.<rect x="0" y="0" width="10" height="10" style="fill:skyblue"/>
vor dem<line/>
.<rect>
statt<line>
und machen Sie Ihre Mustergröße 10x1 statt 10x10.Möglicherweise können Sie mithilfe eines
<pattern>
Tags erstellen, was Sie möchten .Als Ausgangspunkt können Sie dieses Beispiel des jeweiligen MDN-Dokuments nehmen :
<?xml version="1.0"?> <svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <pattern id="Triangle" width="10" height="10" patternUnits="userSpaceOnUse"> <polygon points="5,0 10,10 0,10"/> </pattern> </defs> <circle cx="60" cy="60" r="50" fill="url(#Triangle)"/> </svg>
quelle
Dieser Code von http://bl.ocks.org/jfsiii/7772281 scheint sehr sauber und wiederverwendbar zu sein:
svg { width: 500px; height: 500px; } rect.hbar { mask: url(#mask-stripe) } .thing-1 { fill: blue; } .thing-2 { fill: green; }
<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>SVG colored patterns via mask</title> </head> <body> <svg> <defs> <pattern id="pattern-stripe" width="4" height="4" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"> <rect width="2" height="4" transform="translate(0,0)" fill="white"></rect> </pattern> <mask id="mask-stripe"> <rect x="0" y="0" width="100%" height="100%" fill="url(#pattern-stripe)" /> </mask> </defs> <!-- bar chart --> <rect class="hbar thing-2" x="0" y="0" width="50" height="100"></rect> <rect class="hbar thing-2" x="51" y="50" width="50" height="50"></rect> <rect class="hbar thing-2" x="102" y="25" width="50" height="75"></rect> <!-- horizontal bar chart --> <rect class="hbar thing-1" x="0" y="200" width="10" height="50"></rect> <rect class="hbar thing-1" x="0" y="251" width="123" height="50"></rect> <rect class="hbar thing-1" x="0" y="302" width="41" height="50"></rect> </svg> </body> </html>
quelle
Ein Problem beim Zeichnen einer diagonalen Linie innerhalb eines Musters besteht darin, dass beim Kacheln des Musters die Linien nicht immer ausgerichtet sind - insbesondere bei hohen Zooms. (Dies hängt von der SVG-Rendering-Engine ab, die Sie gerade verwenden.) Die obige Antwort von @ Ingo versucht, dieses Problem zu lösen, indem die Dreiecke oben links und unten rechts gezeichnet werden. Bei Verwendung einiger Rendering-Engines und hoher Zooms sieht es jedoch nicht immer am besten aus. Manchmal sieht die Linie auch so aus ein bisschen wie eine Reihe von Würstchen.
Ein anderer Ansatz besteht darin, eine horizontale Linie in das Muster zu zeichnen und das Muster zu drehen, z
<svg:svg viewBox="0 0 100 100" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg:defs> <svg:pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4" patternTransform="rotate(45 2 2)"> <svg:path d="M -1,2 l 6,0" stroke="#000000" stroke-width="1"/> </svg:pattern> </svg:defs> <svg:rect x="0" y="0" height="100" width="100" fill="url(#diagonalHatch)"/>
quelle
Diese beiden Ressourcen sind sehr hilfreich: https://bocoup.com/weblog/using-svg-patterns-as-fills https://github.com/iros/patternfills/blob/master/public/patterns.css
Zum Beispiel:
<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'> <rect width='10' height='10' fill='red'/> <path d='M-1,1 l2,-2 M0,10 l10,-10 M9,11 l2,-2' stroke='orange' stroke-width='2'/> </svg>
quelle
Dies ist eine Lösung für diagonale Linien mit Kreis im Muster. Sie können den Winkel gemäß Ihren Anforderungen ändern.
<svg width="500" height="500"> <defs> <pattern id="transformedPattern" x="0" y="0" width="2" height="20" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"> <circle cx="1" cy="1" r="2" style="stroke: none; fill: #0000ff" /> </pattern> </defs> <rect x="10" y="10" width="100" height="100" style="stroke: #000000; fill: url(#transformedPattern);" /> </svg>
quelle
Ich habe es mit diesem Beispiel versucht. Hoffentlich kann es Ihnen viel helfen.
<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>SVG colored patterns via mask</title> </head> <body> <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg"> <defs> <pattern id="stripes" viewBox="0,0,8,8" width="16" height="16" patternUnits="userSpaceOnUse"> <polygon points="0,0 4,0 0,4" fill="yellow"></polygon> <polygon points="0,8 8,0 8,4 4,8" fill="yellow"></polygon> <polygon points="0,4 0,8 8,0 4,0" fill="green"></polygon> <polygon points="4,8 8,8 8,4" fill="green"></polygon> </pattern> </defs> <rect fill="url(#stripes)" x="150" y="20" width="100" height="50" /> <circle cx="50" cy="50" r="50" fill="url(#stripes)"/> </svg> </body> </html>
Grüße, Vu Phan
quelle
SVG 2 hat speziell für diesen Zweck eine
hatch
Entität . Aus dem Beispielabschnitt dieser Seite:<hatch hatchUnits="userSpaceOnUse" pitch="5" rotate="135"> <hatchpath stroke="#a080ff" stroke-width="2"/> </hatch>
Dies ist eine sehr einfach zu konfigurierende Methode zum Erstellen von Luken:
Darüber hinaus kann der Schraffurpfad auch angepasst werden:
<hatchpath stroke-width="1" d="C 0,4 8,6 8,10 8,14 0,16 0,20"/>
quelle
Für React Native kann diese Komponente verwendet werden, um Hintergrundlinienmuster zu erstellen. Sie sollten Ihrem Projekt react-native-svg hinzufügen
import PropTypes from 'prop-types'; import React, { PureComponent } from "react"; import { View } from "react-native"; import Svg, { Defs, Line, Pattern, Rect } from 'react-native-svg'; export default class PatternLineView extends PureComponent { static propTypes = { pattern: PropTypes.func.isRequired, space: PropTypes.number, backgroundColor: PropTypes.string, lineColor: PropTypes.string, lineWidth: PropTypes.number, rotation: PropTypes.number } static defaultProps = { pattern: () => { }, space: 8, lineColor: "#D2D9E5", lineWidth: 3, rotation: 45 } render() { const transform = `rotate(${this.props.rotation})` return <View style={{ flex: 1, flexDirection: "row", height: "100%", width: "100%", position: "absolute", top: 0, start: 0, backgroundColor: this.props.backgroundColor }}> <Svg width="100%" height="100%"> <Defs> <Pattern id="linePattern" patternUnits="userSpaceOnUse" patternTransform={transform} width={this.props.space} height={this.props.space}> <Line x1="0" y1="0" x2="0" y2="100%" stroke={this.props.lineColor} strokeWidth={this.props.lineWidth} /> </Pattern> </Defs> <Rect fill="url(#linePattern)" x="0" y="0" width="100%" height="100%" /> </Svg> </View> } }
quelle
Ich habe Ingos Antwort hier angepasst .
<defs> <pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4"> <!-- background --> <path id="background" d="M-1,3 L3,-1 M1,5 L5,1" style="stroke:pink; stroke-width:10" /> <!-- hatches --> <path id="hatches" d="M-2,2 L2,-2 M0,4 L4,0 M2,6 L6,2" style="stroke:red; stroke-width:1" /> </pattern> </defs>
Dieses Muster enthält zwei Pfade, einen für den Hintergrund und einen für die Schraffuren. Die Hintergrundfarbe ist gegenüber JS adressierbar, z. B.:
const hatchPath = document.querySelector("path#hatches");
hatchPath.setAttribute('style', "stroke:blue; stroke-width:1")
Der Hintergrundpfad ist absichtlich zu breit, sodass kein Teil des Musters zumindest vom Hintergrund abgedeckt wird. In der Zwischenzeit kann die Breite der Luken angepasst werden, um die Dicke der Linien zu ändern.
quelle