Sonntag, 31. Januar 2010

SVG - Vektorgrafik mit Geschwindigkeitsvorteil

In einem meiner letzten Projekte musste ich Grafiken für eine vertikale Navigation erstellen. Um die Ladezeiten zu reduzieren, entschied ich mich für die CSS-Matrix-Technik. Mit dieser Technik speichert man alle Hintergrundgrafiken in einer einzelnen großen Grafik und greift per CSS auf einen Ausschnitt zu. Soweit so gut.

Leider war die Navigation durch ein ungewöhnliches Design sehr komplex:

  1. Es gibt verschiedene Ebenen mit unterschiedlichen Höhen und Hintergründen.

  2. Wenn ein Menüelement ein Unternemenü anzeigt, ändert sich die Höhe und der Hintergrund des Menüelements.

  3. Es gibt verschiedene Zustände für ein Menüelement: normal, mouseover und selected.

  4. Es gibt unterschiedliche Farbkennzeichnungen für einen gleichen Menütyp.

Ganz schön kompliziert, obwohl das Design kinderleicht aussieht. Wer sich nichts darunter vorstellen kann, kann sich gerne die Website als Beispiel ansehen: www.phibu.de

Die dazugehörige background-Grafik sieht so aus:

Ein Designer legt eine solche Grafik mittels Hilfslinie in Photoshop an. Als Geek programmiert man dagegen ein kleines PHP-Script, das einem die Grafik erstellt. Ursprünglich wollte ich das Bild über Imagemagick erstellen. Doch ich entschied mich aufgrund des einfachen Handlings für die Nutzung von SVG.
SVG steht für Scalable Vector Graphics und nutzt die XML-Auszeichnung für die Beschreibung von zwei-dimensionalen Vektor-Grafiken. Jeder, der HTML versteht, kann SVG für die Erstellung von Grafiken nutzen. Es ist ganz einfach. Zu erst definiert man den Doctype:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

Dann leitet man die Grafik ein:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" version="1.1" baseProfile="full" width="932" height="306">

Dann macht es Sinn, einen Titel und eine Beschreibung zu vergeben:

<title>phibu</title>
<desc>Hintergründe für Menüs erstellen</desc>

Nun kommt die eigentliche Beschreibung der geometrischen Figuren:

<!-- Hintergrundfarbe -->
<rect x="0" y="0" width="233" height="306" fill="#fff" />
<!-- Dicke Balken -->
<rect x="0" y="0" width="233" height="34" fill="#fff" />
<rect x="0" y="34" width="233" height="34" fill="#ede8da" />
<rect x="0" y="68" width="233" height="34" fill="#bcad92" />
<rect x="0" y="102" width="233" height="26" fill="#fff" />
<rect x="0" y="128" width="233" height="26" fill="#ede8da" />
<rect x="0" y="154" width="233" height="26" fill="#bcad92" />
<rect x="0" y="180" width="233" height="16" fill="#ede8da" />
<rect x="0" y="196" width="233" height="16" fill="#ede8da" />
<rect x="0" y="212" width="233" height="16" fill="#bcad92" />
<rect x="0" y="228" width="233" height="26" fill="#ede8da" />
<rect x="0" y="254" width="233" height="26" fill="#ede8da" />
<rect x="0" y="280" width="233" height="16" fill="#bcad92" />
<rect x="0" y="296" width="233" height="16" fill="#ede8da" />
<!-- 13px Left -->
<rect x="0" y="0" width="13" height="306" fill="#bcad92" />
<!-- Trenner -->
<rect x="0" y="0" width="233" height="1" fill="#bcad92" />
<rect x="0" y="32" width="233" height="2" fill="#fff" />
<rect x="0" y="34" width="233" height="1" fill="#bcad92" />
<rect x="0" y="66" width="233" height="2" fill="#fff" />
<rect x="0" y="100" width="233" height="2" fill="#fff" />
<rect x="0" y="102" width="233" height="1" fill="#bcad92" />
<rect x="0" y="128" width="233" height="1" fill="#bcad92" />
<rect x="0" y="252" width="233" height="2" fill="#fff" />
<rect x="0" y="278" width="233" height="2" fill="#fff" />
<rect x="0" y="304" width="233" height="2" fill="#fff" />
<!-- Pfeile -->
<polygon points="13,199, 18,203,13,207" style="fill:#bcad92;" />
<polygon points="13,257, 18,261,13,265" style="fill:#bcad92;" />

Und zum Schluss sollte man das schließende Tag nicht vergessen:

</svg>

Um ehrlich zu sein, habe ich nur die erste Spalte erstellt und dann in PHP mit sprintf() und einer array-Schleife die gesamte Grafik erstellt. Das ging recht schnell und zeigt auch den Vorteil dieser Technik.

Am liebsten hätte ich die SVG-Grafik direkt im CSS benutzt. Leider kann der IE bis heute kein SVG interpretieren (es seie denn, man installiert ein Adobe-Plugin). Daher habe ich die Grafik als PNG gespeichert. Firefox, Chrome, Safari und Opera haben zum Glück keine Probleme mit SVG.

Die schnellste Möglichkeit, eine SVG-Grafik in ein anderes Grafik-Format zu konvertieren: In Opera (dem besten Browser der Welt) kann man mit der rechten Maus-Taste eine SVG-Grafik in die Zwischenablage kopieren und dann in einem beliebigen Grafikprogramm einfügen und im gewünschten Format speichern. Ich habe keine Möglichkeit gefunden, die SVG-Grafik schneller zu konvertieren:-P

Ich empfehle allen Interessierten folgende Links:

Einige weitergehende Möglichkeiten mit SVG:

Für die Zukunft sollte man SVG und das data URI Schema im Auge behalten. Mit der data-URL-Technik kann man Daten wie z.B. eine SVG-Grafik direkt im HTML-Code verankern. Leider sammelt der Internet Explorer auch hier wieder Minuspunkte. Erst der IE8 unterstützt data-URI und dann auch nur bis 32kB:-P