Dr. O. Hoffmann
In der Welt ist es sehr selten mit dem Entweder-Oder getan.
Johann Wolfgang von Goethe
Ein interessantes Problem tritt auf, wenn entschieden werden soll, was
innen und was außen ist. Was die fill
-Eigenschaft
betrifft, nimmt fill-rule
dem
Autor da eine Menge Arbeit ab, der damit elegant angeben kann, wie seine
Pfadangaben gemeint sind. Allgemein gibt in SVG
fill
die Farbe des inneren
Bereiches an, ein SVG-Darstellungsprogramm hat also ein definiertes Verhalten,
was die Bedeutung von innen und außen festlegt. Es gibt auch Pfade, die
kein Innen und Außen haben, dieses sind einfache gerade Strecken und
Punkte, beides kann in SVG dargestellt werden, die Begriffe innen und außen
ergeben für diese Pfade keinen Sinn.
Anders sieht die Situation aus, wenn es darum geht, den Rand gezielt zu malen, so daß er etwa nur exakt innerhalb des Gebietes definiert durch einen Pfad gezeichnet wird oder nur exakt außerhalb. Bei einfachen Formen kann der Autor dies natürlich leicht selbst ausrechnen und die Pfadangaben dann modifizieren, allerdings gibt es dann Probleme mit der Skalierbarkeit der Graphik. Das Problem verschärft sich bei Anwendungen wie etwa der Kartographie, wo man natürlich nicht möchte, daß Grenzen zwischen zwei Gebieten, die aneinandergrenzen, überlappen. Gleichzeitig ist es bei Karten natürlich erwünscht, Ausschnitte ohne Verlust der Genauigkeit beliebig zu vergrößern oder zu verkleinern.
Da entsprechende einfache Angaben in SVG bislang (bis Version 1.1) fehlen, muß
der Autor auf einige Tricks zurückgreifen. Hier vorgestellt wird, wie mit
dem clipPath
-Element und der clip-path
Eigenschaft einerseits oder dem mask
-Element oder
der mask
-Eigenschaft andererseits das Malen des
Randes so eingegrenzt werden kann, daß oben beschriebenes Problem innerhalb von
SVG 1.1 gelöst ist.
Während clipPath
ja nur den Pfad an sich auswertet und keine Farbangaben,
ermöglicht mask
eine detailliertere Maskierung, weil dort direkt die Farben
in eine Teiltransparenz umgerechnet werden. Verwendet man eine reine
schwarz-weiß-Maske wie hier, so kann man damit sehr flexibel den zu
malenden Bereich eingrenzen. Ähnlich, aber noch flexibler können
Filter verwendet werden, die aber erfahrungsgemäß verglichen mit
clipPath
oder mask
mehr Rechenleistung erfordern.
clipPath
und clip-path
Der erste Ansatz ist recht einfach. Stellen wir uns vor, eine Karte eines Gebietes
liegt als Pfad vor. Ziel ist es, nur den Teil des Randes (stroke
)
zu malen, der innerhalb des Gebietes liegt. Nach kurzem Überlegen stellen wir fest, daß
dies genau der Teil von stroke
ist, der auf fill
gemalt ist. Ausschneiden kann man
dies einfach, indem man dieselbe Pfadangabe nutzt, um den Malbereich
einzuschränken. Damit der Pfad nicht mehrmals ins Dokument geschrieben
werden muß, wird er einfach einmal angegeben und dann mit use
referenziert:
nur den Anteil von stroke
auf fill
darstellen
(Quelltext: Anteil von stroke
auf fill
darstellen).
In einer Animation wird die Eigenschaft clip-path
alle 3s zwischen
dem genannten Pfad und none gewechselt, was dann einer
kompletten Darstellung von stroke
entspricht.
Mit einem Klick wird stroke
auf none gesetzt,
um nur fill
zu sehen, also die exakte Form des angegebenen Pfades.
Durch einen weiteren Trick kann auch nur der äußere Anteil von
stroke
zum
Zeichnen ausgewählt werden. Dazu wird einfach die Eigenschaft von innen und
außen für die clipPath
-Angabe vertauscht. Das geht durch Hinzufügen
eines weiteren Pfades um das Gebiet herum, am besten entweder direkt der Rand des
Zeichenbereiches oder sogar jenseits davon. Um den Pfad nicht mehrmals angeben
zu müssen, wird dieser mit einer Erweiterung der Dokumenttypdeklaration definiert
und jeweils im Pfadelement referenziert:
Anteil von stroke
außen oder innen darstellen
(Quelltext: Anteil von
stroke
außen oder innen darstellen).
Der innere oder der außere Teil von stroke
eines Pfades wird
abgetrennt, so daß nur der außerhalb oder innerhalb von
fill
liegende Anteil dargestellt
wird, indem der Pfad selbst als clipPath
verwendet wird und mit
clip-path
angewendet wird.
In einer Animation wird die Eigenschaft clip-path
alle 3s zwischen
dem genannten Pfad innerhalb oder außerhalb und none gewechselt, was dann einer
kompletten Darstellung von stroke
entspricht.
Mit einem Klick wird stroke
auf none gesetzt,
um nur fill
zu sehen,
also die exakte Form des angegebenen Pfades.
mask
Ein ähnliches Vorgehen wie bei clipPath
führt auch bei
mask
zum Ziel.
Bei Bedarf kann ausgenutzt werden, daß stroke
auch zum
Maskieren verwendet werden
kann, was einem das Vertauschen von innen und außen wie bei clipPath
erspart:
Anteil von stroke
außen oder innen mit mask darstellen
(Quelltext: Anteil von
stroke
außen und innen
mit mask
darstellen).
Der innere oder der außere Teil von stroke
eines Pfades wird
abgetrennt, so daß nur der außerhalb oder innerhalb von
fill
liegende Anteil dargestellt wird, indem der Pfad selbst als Maske
verwendet wird und mit mask
angewendet wird.
In einer Animation wird die Eigenschaft mask
alle 3s zwischen
dem genannten Pfad innerhalb oder außerhalb und none gewechselt, was dann einer
kompletten Darstellung von stroke
entspricht.
Mit einem Klick wird stroke
auf none gesetzt,
um nur fill
zu sehen,
also die exakte Form des angegebenen Pfades.
Mit einer kleinen Variation des Beispieles lassen sich natürlich auch Muster von Anteilen
von stroke
darstellen, dabei kommt es darauf an, von außen
nach innen jeweils weiße
und schwarze Flächen aufeinander zu schichten. Es kann sich dabei als vorteilhaft erweisen,
sich bei der Erstellung die Maske selbst erstmal anzugucken, um gezielt den Effekt zu erreichen, den
man gerne haben möchte:
mehrere Anteile von
stroke
darstellen
(Quelltext: Mehrere Anteile von stroke
darstellen).
mask
anzeigen
Auch bei mask
kann man natürlich innen und außen vertauschen, um noch
flexibler zu arbeiten.
So oder so stellt der Pfad an sich immer einen besonderen Streifen dar, wobei es etwas kniffliger sein kann,
wenn der darzustellende Anteil teilweise innen und teilweise außen liegt und dabei noch asymmetrisch
zwischen innen und außen verteilt sein soll. Auch das geht natürlich mit etwas Überlegung:
Beliebigen Anteil von stroke
darstellen
(Quelltext: Beliebigen Anteil von stroke
darstellen).
Man beachte, daß in SVG auch nicht geschlossene Pfade ein Innen und Außen haben
können. Das kann bei den hier diskutierten Anwendungen zu geringfügigen
Überraschungen führen:
Beliebigen Anteil von stroke
eines offenen
Pfades darstellen
(Quelltext: Beliebigen Anteil von
stroke
eines offenen Pfades darstellen).
Pfad anklickern, um fill-rule
zu ändern.
Überraschungen können auch auftreten, wenn eine Kurve sich selbst
überschneidet oder wenn sich der Pfad relativ zur stroke-width
relativ nahe kommt.
Bei offenen Pfaden wäre es vermutlich sinnvoller, man könnte festlegen, von wie
weit links nach wie weit rechts ein Anteil von stroke
gemalt werden soll,
wobei sich links und rechts relativ zur Richtung bezieht, die sich aus der Angabe der Punkte in der
Pfaddefinition ergibt.
Das ist in SVG 1.1 nicht vorgesehen, ebensowenig wie einfachere Angaben zu den hier
vorgestellten Methoden der Maskierung.
Es gibt vielfältige Möglichkeiten, Filter in diesem Zusammenhang
anzuwenden. Das folgende Beispiel ist da nicht einmal repräsentativ, weder
in der Auswahl der Filtermethoden, noch in den sich ergebenden Resultaten.
Hier sind der Phantasie des Autors in beiden Fällen nur weite Grenzen gesteckt,
viel Spaß beim Herumprobieren!
Filter anwenden
(Quelltext: Filter anwenden).
Einige hundert verschiedene Filterkombinationen
werden im Sekundentakt angezeigt, einige davon
werden sich wiederholen, weil verschiedene
Kombinationen zum gleichen Resultat führen.
Die Manigfaltigkeit der Anwendungsmöglichkeiten
von Filtern ist so groß, daß die hier natürlich
nicht einmal ansatzweise durchgespielt werden
können.