Ostereier selbst herstellen und mitnehmen
bearbeitet von
<p>SVG hat als Grafikformat <a href="https://wiki.selfhtml.org/wiki/SVG/Tutorials/Einstieg">viele Vorteile</a> gegenüber Rastergrafiken: Es ist verlustfrei skalierbar, hat viel geringere Dateigrößen und ist flexibel. SVG ist nämlich auch eine Auszeichnungssprache wie HTML, die grafische Objekte durch Grundformen mit ihren Eigenschaften beschreibt. Diese Grafiken können in entsprechenden Programmen gezeichnet, aber auch dynamisch, d. h. mit Skripten erzeugt werden. Dieser Beitrag zeigt, wie SVG-Grafiken mittels JavaScript erzeugt und gestaltet und dann für den weiteren Gebrauch gespeichert werden können.<!--more--></p>
<p>Neben den üblichen Grundformen wie Rechteck, Kreis oder Ellipse sticht heute zu Ostern natürlich das Ei hervor. Es besteht aus einem Halbkreis und einer halben Ellipse:</p>
~~~xml
<path id="ei"
d="M20,120
a60,60 0 0 0 120,0
a60,90 0 1 0 -120,0"
>
~~~
<p>In SVG können Füllungen und Randlinien per CSS gestaltet werden. Dabei sind auch Verläufe und Muster möglich. Probieren Sie unseren Generator aus!</p>
<iframe src="https://wiki.selfhtml.org/extensions/Selfhtml/example.php/Beispiel:SVG-Ostern.html" name="Osterei-Generator" width="100%" height="680"></iframe>
<h2>Speichern von inline-SVG</h2>
<p>SVG-Grafiken können im img-Element als <a href="https://wiki.selfhtml.org/wiki/SVG/Tutorials/Einstieg/Einbindung">externe Grafiken eingebunden</a> werden. Nicht nur für die dynamische Erzeugung ist es aber besser, SVG direkt inline im HTML-Markup zu notieren. Bei extern eingebundenen Grafiken bieten Browser im Kontextmenü der Grafik die Option zum Abspeichern, die bei Inline-Grafiken nicht existiert. Um an diese Grafiken zu kommen, kann natürlich der Teilbaum des svg-Elements aus dem DOM kopiert werden. Einfacher geht es mit wenigen Zeilen Javascript einen Download-Button oder -Link anzubieten.</p>
<p>Dazu wird der Teilbaum des <code>svg</code>-Elements extrahiert und in eine Form überführt, mit der sich eine <a href="https://wiki.selfhtml.org/wiki/Data-URL">data-URL</a> darstellen lässt, z. B. per <a href="https://wiki.selfhtml.org/wiki/JavaScript/encodeURIComponent">URI-Encoding</a>:</p>
~~~js
let so = document.getElementById('svg2');
let svg = '<!--?xml version="1.0" encoding="UTF-8"?-->'
+ so.outerHTML;
const uri = 'data:image/svg+xml;charset=UTF-8,'
+ encodeURIComponent(svg);
~~~
<p>Dabei gilt es zu berücksichtigen, dass Standalone-SVGs im <code>svg</code>-Element eine Namensraumangabe benötigen, damit SVG-Viewer und -Editoren damit arbeiten können. Diese wird, da sie in HTML5 nicht erforderlich ist, mit JavaScript ggf. nachträglich eingefügt:</p>
~~~js
if (so.attributes['xmlns'] === undefined) {
so.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
}
~~~
<p>Um die Download-Option anzubieten, brauchen wir nun noch einen entsprechenden <a href="https://wiki.selfhtml.org/wiki/HTML/Textauszeichnung/a#Download-Verweise">Download-Link</a>, `<a href="" id="dl_url" download="Osterei.svg">Grafik Speichern</a>`, dessen <code>href</code>-Attribut wird die entsprechende Data-URL zuweisen:</p>
~~~js
document.addEventListener('DOMContentLoaded', function(evt) {
let so = document.getElementById('svg2');
if (so.attributes['xmlns'] === undefined) {
so.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
}
let svg = '<!--?xml version="1.0" encoding="UTF-8"?-->'
+ so.outerHTML;
const prot = 'data:image/svg+xml;charset=UTF-8';
document.getElementById('dl_url').href = prot + ','
+ encodeURIComponent(svg);
});
~~~
<p>In diesem Fall ist die skalierbare Vektorgrafik statisch. Wenn sie wie bei unseren Ostereiern dynamisch ist, muss natürlich der jeweilige SVG-Baum zum Klick-Zeitpunkt ausgewertet werden:</p>
~~~js
document.addEventListener('DOMContentLoaded', function(evt) {
let a = document.getElementById('dl_url');
a.addEventListener('click', function(e) {
let so = document.getElementById('svg2');
if (so.attributes['xmlns'] === undefined) {
so.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
}
let svg = '<!--?xml version="1.0" encoding="UTF-8"?-->'
+ so.outerHTML;
const prot = 'data:image/svg+xml;charset=UTF-8';
a.href = prot + ',' + encodeURIComponent(svg);
});
});
~~~
<h2>Weiterführende Gedanken</h2>
<p>Der hier vorgestellte Ansatz kann natürlich nicht nur auf einzelne, eindeutige Grafiken mit entsprechenden Links angewendet werden, sondern als Bibliothek z. B. für <a href="https://wiki.selfhtml.org/wiki/JavaScript/DOM/Document/getElementsByTagName">alle Grafiken in einem Dokument</a> oder alle <a href="https://wiki.selfhtml.org/wiki/JavaScript/DOM/Document/getElementsByClassName">Grafiken einer bestimmten Klasse</a>. Auch der entsprechende Download-Link kann dann dynamisch ins DOM (z. B. in einer <a href="https://wiki.selfhtml.org/wiki/HTML/Textstrukturierung/figure#figcaption">Bildbeschriftung</a>) eingefügt werden.</p>
<p>Denkbar wäre eventuell auch der Einsatz als <a href="https://wiki.selfhtml.org/wiki/Bookmarklet">Bookmarklet</a>.</p>
<h2>Metadaten</h2>
<p>Da die Grafiken beim Speichern aus dem Kontext der umgebenen Webseite herausgelöst werden, können Sie im SVG-Code entsprechende Metadaten notieren, die dann mitgespeichert werden und so den Kontext weiterhin herstellen. Die freie Software <em>Inkscape</em> erzeugt dazu sehr ausführlichen Code innerhalb des <code>metadata</code>-Elements, an dem man sich orientieren kann – dabei nicht die entsprechenden XML-Namensraum-Angaben vergessen!</p>
Ostereier selbst herstellen und mitnehmen
bearbeitet von
<p>SVG hat als Grafikformat <a href="https://wiki.selfhtml.org/wiki/SVG/Tutorials/Einstieg">viele Vorteile</a> gegenüber Rastergrafiken: Es ist verlustfrei skalierbar, hat viel geringere Dateigrößen und ist flexibel. SVG ist nämlich auch eine Auszeichnungssprache wie HTML, die grafische Objekte durch Grundformen mit ihren Eigenschaften beschreibt. Diese Grafiken können in entsprechenden Programmen gezeichnet, aber auch dynamisch, d. h. mit Skripten erzeugt werden. Dieser Beitrag zeigt, wie SVG-Grafiken mittels JavaScript erzeugt und gestaltet und dann für den weiteren Gebrauch gespeichert werden können.<!--more--></p>
<p>Neben den üblichen Grundformen wie Rechteck, Kreis oder Ellipse sticht heute zu Ostern natürlich das Ei hervor. Es besteht aus einem Halbkreis und einer halben Ellipse:<br>
[code lang="xml"]<path id="ei"<br>
d="M20,120<br>
a60,60 0 0 0 120,0<br>
a60,90 0 1 0 -120,0"<br>
><br>
[/code]<br>
In SVG können Füllungen und Randlinien per CSS gestaltet werden. Dabei sind auch Verläufe und Muster möglich. Probieren Sie unseren Generator aus!</p>
<p><iframe src="https://wiki.selfhtml.org/extensions/Selfhtml/example.php/Beispiel:SVG-Ostern.html" name="Osterei-Generator" width="100%" height="680"><br>
</iframe></p>
<h2>Speichern von inline-SVG</h2>
<p>SVG-Grafiken können im img-Element als <a href="https://wiki.selfhtml.org/wiki/SVG/Tutorials/Einstieg/Einbindung">externe Grafiken eingebunden</a> werden. Nicht nur für die dynamische Erzeugung ist es aber besser, SVG direkt inline im HTML-Markup zu notieren. Bei extern eingebundenen Grafiken bieten Browser im Kontextmenü der Grafik die Option zum Abspeichern, die bei Inline-Grafiken nicht existiert. Um an diese Grafiken zu kommen, kann natürlich der Teilbaum des svg-Elements aus dem DOM kopiert werden. Einfacher geht es mit wenigen Zeilen Javascript einen Download-Button oder -Link anzubieten.</p>
<p>Dazu wird der Teilbaum des <code>svg</code>-Elements extrahiert und in eine Form überführt, mit der sich eine <a href="https://wiki.selfhtml.org/wiki/Data-URL">data-URL</a> darstellen lässt, z. B. per <a href="https://wiki.selfhtml.org/wiki/JavaScript/encodeURIComponent">URI-Encoding</a>:<br>
[code lang="javascript"]let so = document.getElementById('svg2');<br>
let svg = '<!--?xml version="1.0" encoding="UTF-8"?-->'<br>
+ so.outerHTML;<br>
const uri = 'data:image/svg+xml;charset=UTF-8,'<br>
+ encodeURIComponent(svg);<br>
[/code]<br>
Dabei gilt es zu berücksichtigen, dass Standalone-SVGs im <code>svg</code>-Element eine Namensraumangabe benötigen, damit SVG-Viewer und -Editoren damit arbeiten können. Diese wird, da sie in HTML5 nicht erforderlich ist, mit JavaScript ggf. nachträglich eingefügt:<br>
[code lang="javascript"]if (so.attributes['xmlns'] === undefined) {<br>
so.setAttribute('xmlns', 'http://www.w3.org/2000/svg');<br>
}<br>
[/code]<br>
Um die Download-Option anzubieten, brauchen wir nun noch einen entsprechenden <a href="https://wiki.selfhtml.org/wiki/HTML/Textauszeichnung/a#Download-Verweise">Download-Link</a>,</p>
<p>[code lang="html"]<a href="" id="dl_url" download="Osterei.svg">Grafik Speichern</a>[/code]</p>
<p>dessen <code>href</code>-Attribut wird die entsprechende Data-URL zuweisen:<br>
[code lang="javascript"]document.addEventListener('DOMContentLoaded', function(evt) {<br>
let so = document.getElementById('svg2');<br>
if (so.attributes['xmlns'] === undefined) {<br>
so.setAttribute('xmlns', 'http://www.w3.org/2000/svg');<br>
}<br>
let svg = '&lt;!--?xml version="1.0" encoding="UTF-8"?--&gt;'<br>
+ so.outerHTML;<br>
const prot = 'data:image/svg+xml;charset=UTF-8';<br>
document.getElementById('dl_url').href = prot + ','<br>
+ encodeURIComponent(svg);<br>
});<br>
[/code]<br>
In diesem Fall ist die skalierbare Vektorgrafik statisch. Wenn sie wie bei unseren Ostereiern dynamisch ist, muss natürlich der jeweilige SVG-Baum zum Klick-Zeitpunkt ausgewertet werden:<br>
[code lang="javascript"]document.addEventListener('DOMContentLoaded', function(evt) {<br>
let a = document.getElementById('dl_url');</p>
<p> a.addEventListener('click', function(e) {<br>
let so = document.getElementById('svg2');<br>
if (so.attributes['xmlns'] === undefined) {<br>
so.setAttribute('xmlns', 'http://www.w3.org/2000/svg');<br>
}<br>
let svg = '&lt;!--?xml version="1.0" encoding="UTF-8"?--&gt;'<br>
+ so.outerHTML;<br>
const prot = 'data:image/svg+xml;charset=UTF-8';<br>
a.href = prot + ',' + encodeURIComponent(svg);<br>
});<br>
});<br>
[/code]</p>
<h2>Weiterführende Gedanken</h2>
<p>Der hier vorgestellte Ansatz kann natürlich nicht nur auf einzelne, eindeutige Grafiken mit entsprechenden Links angewendet werden, sondern als Bibliothek z. B. für <a href="https://wiki.selfhtml.org/wiki/JavaScript/DOM/Document/getElementsByTagName">alle Grafiken in einem Dokument</a> oder alle <a href="https://wiki.selfhtml.org/wiki/JavaScript/DOM/Document/getElementsByClassName">Grafiken einer bestimmten Klasse</a>. Auch der entsprechende Download-Link kann dann dynamisch ins DOM (z. B. in einer <a href="https://wiki.selfhtml.org/wiki/HTML/Textstrukturierung/figure#figcaption">Bildbeschriftung</a>) eingefügt werden.</p>
<p>Denkbar wäre eventuell auch der Einsatz als <a href="https://wiki.selfhtml.org/wiki/Bookmarklet">Bookmarklet</a>.</p>
<h2>Metadaten</h2>
<p>Da die Grafiken beim Speichern aus dem Kontext der umgebenen Webseite herausgelöst werden, können Sie im SVG-Code entsprechende Metadaten notieren, die dann mitgespeichert werden und so den Kontext weiterhin herstellen. Die freie Software <em>Inkscape</em> erzeugt dazu sehr ausführlichen Code innerhalb des <code>metadata</code>-Elements, an dem man sich orientieren kann – dabei nicht die entsprechenden XML-Namensraum-Angaben vergessen!</p>