{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "fboës - Der Blog | Artikel mit dem Tag \"SVG\"",
  "home_page_url": "https://journal.3960.org/",
  "feed_url": "https://journal.3960.org/tagged/svg/feed.json",
  "description": "Programmierung, Luft- & Raumfahrt, Kurioses: Der Blog von und mit Frank Boës.",
  "icon": "https://cdn.3960.org/favicon-192x192.png",
  "favicon": "https://cdn.3960.org/images/tile-128x128.png",
  "author": {
    "name": "Frank Boës",
    "url": "mailto:info@3960.org"
  },
  "authors": [
    {
      "name": "Frank Boës",
      "url": "mailto:info@3960.org"
    }
  ],
  "language": "de-DE",
  "_rss": {
    "about": "http://cyber.harvard.edu/rss/rss.html",
    "copyright": "© 2008-2023 Creative Commons BY"
  },
  "items": [
    {
      "id": "user/posts/2023-03-05-24h-uhr-als-web-component/index.md",
      "url": "https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/",
      "title": "Die 24h-Uhr – als Web Component",
      "content_html": "<p><img src=\"https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock-240x240.png\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> Web Components zu bauen ist gar nicht so kompliziert, selbst ohne Framework. Nach meinen vorherigen <a href=\"https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/../2020-04-05-svg-web-components/\">Überlegungen zur Verwendung von SVGs in Web Components</a> war es also höchste Zeit, eine 24-Stunden-Uhr zu bauen.</p>\n<!-- more -->\n<h2 id=\"more\">Die Idee</h2>\n<p>24h-Uhren sind analoge Uhren, die einen feinen Unterschied zu herkömmlichen Uhren aufweisen. An Stelle von 12 Stunden pro Umdrehung des Stundenzeigers zeigen sie 24 Stunden an. Damit braucht also der Stundenzeiger einen kompletten Tag für einen Vollkreis.</p>\n<p>Damit ist es möglich, die vierundzwanzig Stunden auf dem Ziffernblatt grafisch in Tag, Dämmerung und Nacht einzuteilen. Da diese sich in Bezug auf das Datum und die geografische Position verändern, brauchte die Uhr also auch diese Informationen. In meinem Fall habe ich eine Skala auf dem Stundenring angebracht, die sich für die Nacht dunkelblau, für die Dämmung mittelblau und für den Tag hellblau verfärbt.</p>\n<p><span class=\"figure\"><img src=\"https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock-2.png\" alt=\"Im hohen Norden scheint die Sonne heute nur kurz\" /><span class=\"figcaption\" aria-hidden=\"true\">Im hohen Norden scheint die Sonne heute nur kurz<br /></span></span></p>\n<h2 id=\"die-umsetzung\">Die Umsetzung</h2>\n<p>Der Bau als <a href=\"https://journal.3960.org/tagged/web-components/\">Web Component</a> erlaubt es nun, die Uhr mit relativ wenig HTML in eine beliebige Seite einzubauen. Unter <a href=\"https://github.com/fboes/twentyfour-hours-clock\">der Github-Seite zur 24h-Uhr</a> findet sich eine knappe Anleitung, der Einbau einer Web Component muss aber nicht komplizierter sein als:</p>\n<pre><code class=\"language-html\">&lt;<i>twentyfour-hours-clock</i>&gt;&lt;/<i>twentyfour-hours-clock</i>&gt;\n</code></pre>\n<p>Weitere <strong>Attribute</strong> erlauben es, die Component vorher mit Werten zu bestücken – die sich auch im Nachhinein mit JavaScript ändern lassen:</p>\n<pre><code class=\"language-html\">&lt;<i>twentyfour-hours-clock</i> <var>width</var>=&quot;<kbd>128</kbd>&quot; <var>height</var>=&quot;<kbd>128</kbd>&quot; <var>datetime</var>=&quot;<kbd>2011-10-10T14:48:00</kbd>&quot; <var>longitude</var>=&quot;<kbd>auto</kbd>&quot; <var>latitude</var>=&quot;<kbd>auto</kbd>&quot;&gt;&lt;/<i>twentyfour-hours-clock</i>&gt;\n</code></pre>\n<p>Auch das Einfärben, Vergrößern und Verkleinern von Einzelteilen der Web Component sind mit <strong>CSS Custom Properties</strong> möglich:</p>\n<pre><code class=\"language-html\">&lt;<i>style</i>&gt;\ntwentyfour-hours-clock {\n  --color-watchhand: pink;\n  --color-night: #111111;\n}\n&lt;/<i>style</i>&gt;\n&lt;<i>twentyfour-hours-clock</i>&gt;&lt;/<i>twentyfour-hours-clock</i>&gt;\n</code></pre>\n<p>Die Web Component selber wurde mit TypeScript gebaut. Tatsächlich wäre auch der Bau direkt in <i>Vanilla JavaScript</i> möglich gewesen. Meine letzten Abenteuer in <a href=\"https://www.typescriptlang.org/\">TypeScript</a> sind aber so angenehme Erfahrungen gewesen, dass ich die Unterstützung bei der Typisierung in JavaScript nicht mehr missen möchte, und die Web Component in TypeScript gebaut habe. Inzwischen halte ich bei JavaScript die Verwendung von TypeScript für so hilfreich, dass ich auf ESLint zur Überprüfung meiner Programmierung bei Privatprojekten gerne verzichte.</p>\n<h2 id=\"her-mit-der-uhr\">Her mit der Uhr!</h2>\n<p>Ein funktionierendes Beispiel für die fertige Uhr findet sich auf der <a href=\"https://fboes.github.io/twentyfour-hours-clock/dist/\">Demonstrationsseite für die 24h-Uhr</a>.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Die%2024h-Uhr%20%E2%80%93%20als%20Web%20Component&amp;url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2023-03-05-24h-uhr-als-web-component%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />",
      "summary": "Web Components zu bauen ist gar nicht so kompliziert, selbst ohne Framework. Nach meinen vorherigen Überlegungen zur Verwendung von SVGs in Web Components war…",
      "date_published": "2023-03-05T18:56:12+01:00",
      "date_modified": "2023-03-05T18:56:12+01:00",
      "author": {
        "name": "Frank Boës",
        "url": "mailto:info@3960.org",
        "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
      },
      "authors": [
        {
          "name": "Frank Boës",
          "url": "mailto:info@3960.org",
          "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
        }
      ],
      "banner_image": "https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock.png",
      "language": "de-DE",
      "image": "https://journal.3960.org/posts/2023-03-05-24h-uhr-als-web-component/24h-clock.png",
      "tags": [
        "Webdevelop",
        "Web-Components",
        "SVG",
        "Javascript",
        "CSS",
        "Geografie",
        "Outdoor",
        "Programmierung",
        "Technologie"
      ]
    },
    {
      "id": "user/posts/2022-05-10-svg-kugelsicher-machen/index.md",
      "url": "https://journal.3960.org/posts/2022-05-10-svg-kugelsicher-machen/",
      "title": "SVG kugelsicher machen",
      "content_html": "<p>SVGs können nicht nur mit Grafikprogrammen wie Adobe Illustrator oder <a href=\"https://inkscape.org/\">Inkscape</a> erstellt werden, sondern auch mit einem einfachen Texteditor – oder programmatisch mit jeder Skriptsprache, die man so zur Hand hat. Damit die SVG-Grafik aber in jedem Umfeld funktioniert, sind ein paar Besonderheiten zu beachten:</p>\n<!-- more -->\n<h2 id=\"more\">Struktur</h2>\n<pre><code class=\"language-xml\"><b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;</b>\n&lt;<i>svg</i> <var>version</var>=&quot;<kbd>1.1</kbd>&quot; <var>viewBox</var>=&quot;<kbd>0 0 100 100</kbd>&quot; <var>width</var>=&quot;<kbd>210mm</kbd>&quot; <var>height</var>=&quot;<kbd>210mm</kbd>&quot; <var>xmlns</var>=&quot;<kbd>http://www.w3.org/2000/svg</kbd>&quot;&gt;\n  &lt;<i>title</i>&gt;<u>&lt;!-- Document Title goes here --&gt;</u>&lt;/<i>title</i>&gt;\n  &lt;<i>style</i>&gt;\n    <u>&lt;!-- CSS goes here --&gt;</u>\n  &lt;/<i>style</i>&gt;\n  &lt;<i>defs</i>&gt;\n    <u>&lt;!-- Optional: Pastable objects --&gt;</u>\n  &lt;/<i>defs</i>&gt;\n  <u>&lt;!-- Here comes the actual SVG --&gt;</u>\n&lt;/<i>svg</i>&gt;\n</code></pre>\n<p>Die Grundstruktur eines SVG-Dokuments kann man sich ähnlich wie die eines HTML-Dokuments vorstellen:</p>\n<p>Zuerst kommen Meta-Angaben. Dazu gehört der Dokumenten-Titel, CSS und gegebenenfalls noch <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs\"><code>&lt;defs&gt;</code></a>, falls ihr Grafikkomponenten mehrfach verwenden wollt.</p>\n<p>Erst danach sollte die eigentliche Ausgabe von Grafikelementen beginnen.</p>\n<h2 id=\"title\">Title</h2>\n<p>In SVG hat das <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title\"><code>&lt;title&gt;</code>-Tag</a> mehrere Bedeutungen:</p>\n<ol>\n<li>Wenn es auf der obersten Ebene steht wird es wie das <code>&lt;title&gt;</code>-Tag HTML verwendet, um den Namen eines Dokuments festzulegen.</li>\n<li>Wenn es innerhalb des Dokuments vorkommt übernimmt es die Funktion des aus HTML bekannten <code>title</code>-Attributs. Beim Überfahren mit der Maus wird zum Beispiel eine kleiner Tooltip angezeigt.</li>\n</ol>\n<h2 id=\"css\">CSS</h2>\n<p>…funktioniert wie in HTML. Dementsprechend sollte man versuchen, nicht jedem Element einzeln mittels <code>stroke</code>- und <code>fill</code>-Attributen Styles zuzuordnen, sondern mit CSS das Layout globaler zu definieren.</p>\n<p>Tatsächlich gibt es aber ein paar Besonderheiten bei der <a href=\"https://css-tricks.com/svg-properties-and-css/\">Verwendung von CSS in SVGs</a>:</p>\n<h3 id=\"rgba-farben-funktionieren-nicht-zuverlässig\">RGBA-Farben funktionieren nicht zuverlässig</h3>\n<p>RGBA-Farben haben die Fähigkeit, darunterliegende Teile einer Grafik durchscheinen zu lassen. Der Alpha-Kanal bestimmt dabei die Durchlässigkeit bzw. Opazität. Leider werden RGBA-Farben nicht in jedem Fall korrekt ausgegeben. Die meisten Browser können es, dafür kaum ein Grafikprogramm oder Bildbetrachter.</p>\n<p>Stattdessen gibt es verschiedene Formen von Opazität bzw. Transparenz.</p>\n<ul>\n<li><code>opacity</code> macht ein gesamtes Element,</li>\n<li><code>fill-opacity</code> nur die Füllung,</li>\n<li><code>stroke-opacity</code> nur die Umrandung opak bzw. transparent.</li>\n</ul>\n<p>In CSS sieht das wie folgt aus:</p>\n<pre><code class=\"language-css\"><i>.black-a-fifty</i> {\n  <u>/* fill: rgba(0,0,0,0.5); --- will not always work */</u>\n  <b>fill</b>: <em>#000000</em>;\n  <b>fill-opacity</b>: 0.5;\n}\n</code></pre>\n<h3 id=\"css-custom-properties-funktionieren-nicht-zuverlässig\">CSS Custom Properties funktionieren nicht zuverlässig</h3>\n<p>Fans von <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties\">CSS Custom Properties</a> haben bei SVG ebenfalls kein Glück: Die meisten Grafikprogramme können diese Variablen nicht verarbeiten. Stattdessen gibt es aber einen kleinen Ausweg mit dem CSS-Wert <code>currentColor</code>:</p>\n<p>Der Wert für <code>currentColor</code> wird mit der in SVG sonst irrelevanten CSS-Eigenschaft <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/color\"><code>color</code></a> gesetzt (die im Gegensatz zu der gleichnamigen Eigenschaft in HTML nicht aktiv ELemente einfärbt – dafür ist in SVG ja <code>fill</code> und <code>stroke</code> da). Der Aufruf von <code>currentColor</code> wird dann mit dem zuletzt via <code>color</code> gesetztem Wert gefüllt – ganz wie bei einer CSS Custom Property.</p>\n<pre><code class=\"language-css\"><i>.black</i> {\n  <b>color</b>: black; <u>/* sets currentColor to `black` */</u>\n}\n\n<i>.red</i> {\n  <b>color</b>: red; <u>/* sets currentColor `red` */</u>\n}\n\n<u>/* These elements will be colored black or red, depending on class */</u>\n\n<i>rect</i> {\n  <b>stroke</b>: currentColor;\n  <b>fill</b>: currentColor;\n}\n\n<i>text</i> {\n  <b>fill</b>: currentColor;\n}\n</code></pre>\n<h2 id=\"mehrzeiliger-text\">Mehrzeiliger Text</h2>\n<p>In SVG kann in Theorie nur einzeiliger Text gesetzt werden, beziehungsweise muss jede neue Zeile neu positioniert werden. Mit einem kleinen Trick kann man aber mehrzeiligen Text erstellen, indem jede Zeile in ein <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Element/tspan\"><code>&lt;tspan&gt;</code>-Element</a> gehüllt und diese relativ unter der vorhergehenden Zeile positioniert wird:</p>\n<pre><code class=\"language-xml\">&lt;<i>text</i>&gt;\n  &lt;<i>tspan</i> <var>x</var>=&quot;<kbd>0</kbd>&quot;&gt;Line 1&lt;/<i>tspan</i>&gt;\n  &lt;<i>tspan</i> <var>x</var>=&quot;<kbd>0</kbd>&quot; <var>dy</var>=&quot;<kbd>1.1em</kbd>&quot;&gt;Line 2&lt;/<i>tspan</i>&gt;\n  &lt;<i>tspan</i> <var>x</var>=&quot;<kbd>0</kbd>&quot; <var>dy</var>=&quot;<kbd>1.1em</kbd>&quot;&gt;Line 3&lt;/<i>tspan</i>&gt;\n  &lt;<i>tspan</i> <var>x</var>=&quot;<kbd>0</kbd>&quot; <var>dy</var>=&quot;<kbd>1.1em</kbd>&quot;&gt;Line 4&lt;/<i>tspan</i>&gt;\n&lt;/<i>text</i>&gt;\n</code></pre>\n<p>Wichtig ist hier die Definition des Zeilenabstands – diese muss in jedem <code>dy</code>-Attribut wiederholt werden.</p>\n<h2 id=\"links\">Links</h2>\n<p>Wenn ihr Links in eurem SVG verwenden wollt, gibt es zwei Wege, wobei je nach Ausgabemedium nur einer von beiden funktioniert… oder auch gar keiner.</p>\n<p>Die veraltete, aber noch weit verbreitete Methode sind <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href\"><code>xlink:href</code>-Attribute</a>, die die Ziel-URL an einem Element festlegen. Damit diese funktionieren, muss zuerst an dem <code>&lt;svg&gt;</code>-Knoten ein neuer <a href=\"https://developer.mozilla.org/en-US/docs/Related/IMSC/Namespaces\">Namespace</a> deklariert werden:</p>\n<pre><code class=\"language-xml\">&lt;<i>svg</i> … <var>xmlns:xlink</var>=&quot;<kbd>http://www.w3.org/1999/xlink</kbd>&quot;&gt;\n</code></pre>\n<p>Sobald dieser Namespace bekannt ist, kann das Attribut verwendet werden.</p>\n<p>In SVG2 wird stattdessen das aus HTML bekannte <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Element/a\"><code>&lt;a&gt;</code>-Tag mit <code>href</code>-Attribut</a> verwendet.</p>\n<p>Für eine maximale Kompatibilität kann man beide Techniken miteinander kombinieren:</p>\n<pre><code class=\"language-xml\">&lt;<i>a</i> <var>xlink:href</var>=&quot;<kbd>https://www.example.com</kbd>&quot; <var>href</var>=&quot;<kbd>https://www.example.com</kbd>&quot;&gt;…&lt;/<i>a</i>&gt;\n</code></pre>\n<p>Übrigens: Die Links für <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use\"><code>&lt;defs&gt;</code> und <code>&lt;use&gt;</code></a> werden mit dem selben <code>xlink:href</code>- beziehungsweise <code>href</code>-Attribut gebaut.</p>\n<h2 id=\"linien-abrunden\">Linien abrunden</h2>\n<p>Im Standard sind SVG-Linien eine scharfkantige Sache. Zum Glück gibt es CSS-Eigenschaften, die sowohl die Enden mit <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap\"><code>stroke-linecap</code></a> als auch die Ecken mit <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin\"><code>stroke-linejoin</code></a> abrunden können.</p>\n<pre><code class=\"language-css\"><i>.rounded-line</i> {\n  <b>stroke-linecap</b>: round;\n  <b>stroke-linejoin</b>: round;\n}\n</code></pre>\n<h2 id=\"inkscape\">Inkscape</h2>\n<p>Wenn euer SVG-Dokument auch in <a href=\"https://inkscape.org/\">Inkscape</a> bearbeitbar sein soll, könnt ihr mit einem zusätzlichen XML-Namensraum kleine Helferlein im Dokument hinterlassen:</p>\n<pre><code class=\"language-xml\">&lt;<i>svg</i> … <var>xmlns:inkscape</var>=&quot;<kbd>http://www.inkscape.org/namespaces/inkscape</kbd>&quot;&gt;\n</code></pre>\n<p>Jetzt steht euch die Möglichkeit zur Verfügung, die aus Inkscape bekannten Layer in eurem SVG zu verwenden. Dazu müsst ihr eine beliebige Gruppe nur mit zusätzlichen Attributen ausstatten:</p>\n<pre><code class=\"language-xml\">&lt;<i>g</i> <var>inkscape:groupmode</var>=&quot;<kbd>layer</kbd>&quot; <var>inkscape:label</var>=&quot;<kbd>Name your layer</kbd>&quot;&gt;…&lt;/<i>g</i>&gt;\n</code></pre>\n<h2 id=\"fazit\">Fazit</h2>\n<p>Wenn eure SVGs nicht nur in modernsten Browsern, sondern auch in älteren Browsern und  Grafikprogrammen funktionieren soll, müssen ein paar Spielregeln eingehalten werden. Im Endeffekt ist nach kurzer Umgewöhnung das Erzeugen wunderschöner SVG-Dokumente nicht viel komplizierter als das Erstellen von HTML-Dokumenten.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=SVG%20kugelsicher%20machen&amp;url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2022-05-10-svg-kugelsicher-machen%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />",
      "summary": "SVGs können nicht nur mit Grafikprogrammen wie Adobe Illustrator oder Inkscape erstellt werden, sondern auch mit einem einfachen Texteditor – oder…",
      "date_published": "2022-05-10T19:06:51+02:00",
      "date_modified": "2022-05-11T08:52:28+02:00",
      "author": {
        "name": "Frank Boës",
        "url": "mailto:info@3960.org",
        "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
      },
      "authors": [
        {
          "name": "Frank Boës",
          "url": "mailto:info@3960.org",
          "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
        }
      ],
      "banner_image": "https://cdn.3960.org/favicon-192x192.png",
      "language": "de-DE",
      "image": "https://cdn.3960.org/favicon-192x192.png",
      "tags": [
        "SVG",
        "CSS",
        "Programmierung",
        "Webdevelop"
      ]
    },
    {
      "id": "user/posts/2021-12-04-print-stylesheets-fuer-svg-grafiken/index.md",
      "url": "https://journal.3960.org/posts/2021-12-04-print-stylesheets-fuer-svg-grafiken/",
      "title": "Print-Stylesheets… für SVG-Grafiken",
      "content_html": "<p>Vektor-Grafiken haben für Logos, Diagramme und Symbole die fantastische Eigenschaft, bei beliebig hoher Auflösung relativ kleine Dateigrößen zu verursachen. Und hier folgen ein paar Kniffe, um SVG-Grafiken mit der Hilfe von CSS sowohl am Bildschirm als auch im Druck gut aussehen zu lassen.</p>\n<!-- more -->\n<p id=\"more\">Seitdem <a href=\"https://caniuse.com/svg\" rel=\"nomention\">die Unterstützung von SVG-Vektor-Grafiken in jedem modernen Browser kein Problem mehr darstellt</a>, ist der Siegeszug von SVG-Grafiken unaufhaltsam. Ob via <code>&lt;img&gt;</code>, als CSS-Hintergrundbild, oder direkt in ein HTML-Dokument eingebettet: kleine Symbole wie komplexe Grafiken können so responsiv auf den Bildschirm gezaubert werden. Eine <a href=\"https://css-tricks.com/using-svg/\">Einleitung in das Thema „SVG“ bei CSS-Tricks</a> erklärt die grundsätzlichen Handgriffe.</p>\n<p>Fast immer wird eine SVG-Grafik mit einem Vektor-Grafikprogramm (wie zum Beispiel dem kostenlosen <a href=\"https://inkscape.org/\">Inkscape</a>) erzeugt. Dabei wird oft vergessen, dass SVG-Dateien eigentlich nur aus XML bestehen, das mit <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG\" title=\"Dokumentation zum manuellen Erstellen von SVG-Grafiken\">Hilfe eines Text-Editors bearbeitet werden kann</a>.</p>\n<p>Interessanterweise kann <a href=\"https://developer.mozilla.org/en-US/docs/Web/SVG/Applying_SVG_effects_to_HTML_content\">innerhalb eines SVG-Dokuments auch CSS verwendet werden</a>. Und mit CSS können wir auch <strong>Media-Queries</strong> einsetzen.</p>\n<p>Höchste Zeit, den Text-Editor auszupacken und unserem SVG zusätzliches CSS überzuhelfen!</p>\n<h2 id=\"ein-einfaches-print-stylesheet\">Ein einfaches Print-Stylesheet</h2>\n<p>Ein einfaches Stylesheet, um beim Druck von HTML- und SVG-Dokumenten im Browser störendes Beiwerk wie die automatisch vom Browser erzeugte Kopf- und Fußzeile loszuwerden, sieht wie folgt aus:</p>\n<pre><code class=\"language-css\"><i>@page</i> {\n  <b>margin</b>: 0;\n  <b>padding</b>: 0;\n}\n<i>@page</i> :footer {\n  display: none\n}\n<i>@page</i> :header {\n  display: none\n}\n</code></pre>\n<p>Genau dieses CSS lässt sich mit einem <code>&lt;style&gt;</code>-Tag direkt in die SVG-Grafik einbauen. Dazu kann man an jeder beliebigen Stelle im Dokument ein solches Tag einfügen, und dann CSS einfügen:</p>\n<pre><code class=\"language-xml\"><b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;</b>\n&lt;<i>svg</i> <var>version</var>=&quot;<kbd>1.1</kbd>&quot; <var>xmlns</var>=&quot;<kbd>http://www.w3.org/2000/svg</kbd>&quot;&gt;\n  &lt;<i>title</i>&gt;…&lt;/<i>title</i>&gt;\n  &lt;<i>style</i>&gt;\n  @page {\n    margin: 0;\n    padding: 0;\n  }\n  @page :footer {\n    display: none\n  }\n  @page :header {\n    display: none\n  }\n  &lt;/<i>style</i>&gt;\n  <u>&lt;!-- your svg here --&gt;</u>\n&lt;/<i>svg</i>&gt;\n</code></pre>\n<p>Natürlich könnt ihr auch jede andere Media-Query in das Dokument einfügen. Zu beachten: Beim Re-Import in ein Grafik-Programm kann dies möglicherweise nicht mehr korrekt interpretiert werden, und eure Grafik wirkt etwas verspielt. Uns interessiert aber sowieso nur das Ergebnis im Browser.</p>\n<h2 id=\"druckvorschau\">Druckvorschau</h2>\n<p>Um die Idee weiterzutreiben, kann man für eine SVG-Grafik im DIN A4 eine praktische Druckvorschau mitliefern. Dazu bauen wir uns ein Dokument mit den entsprechenden Abmessungen von 210×297 Millimetern und erzeugen ein Rechteck, dass exakt dem Seitenrand folgt:</p>\n<pre><code class=\"language-xml\"><b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;</b>\n&lt;<i>svg</i> <var>width</var>=&quot;<kbd>210mm</kbd>&quot; <var>height</var>=&quot;<kbd>297mm</kbd>&quot; <var>viewBox</var>=&quot;<kbd>0 0 210 297</kbd>&quot; <var>version</var>=&quot;<kbd>1.1</kbd>&quot; <var>xmlns</var>=&quot;<kbd>http://www.w3.org/2000/svg</kbd>&quot;&gt;\n  &lt;<i>rect</i> <var>x</var>=&quot;<kbd>0</kbd>&quot; <var>y</var>=&quot;<kbd>0</kbd>&quot; <var>width</var>=&quot;<kbd>210</kbd>&quot; <var>height</var>=&quot;<kbd>297</kbd>&quot; /&gt;\n  <u>&lt;!-- your svg here --&gt;</u>\n&lt;/<i>svg</i>&gt;\n</code></pre>\n<p>Dieses Rechteck ist nun sowohl auf dem Bildschirm als auch im Druck zu sehen. Interessanterweise können wir so ziemlich jedem SVG-Element mittels <code>class</code> und <code>id</code> Attribute mitgeben, die wir (wie aus HTML gewohnt) CSS zuweisen können.</p>\n<p>In diesem Fall wollen wir die eigentliche Seite weiß und den nicht druckbaren Bereich grau darstellen. Nicht zuletzt zeigt eine gepunktete Linie die Blattgrenze an:</p>\n<pre><code class=\"language-xml\"><b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;</b>\n&lt;<i>svg</i> <var>width</var>=&quot;<kbd>210mm</kbd>&quot; <var>height</var>=&quot;<kbd>297mm</kbd>&quot; <var>viewBox</var>=&quot;<kbd>0 0 210 297</kbd>&quot; <var>version</var>=&quot;<kbd>1.1</kbd>&quot; <var>xmlns</var>=&quot;<kbd>http://www.w3.org/2000/svg</kbd>&quot;&gt;\n  &lt;<i>title</i>&gt;…&lt;/<i>title</i>&gt;\n  &lt;<i>style</i>&gt;\n  svg {\n    margin: 1em auto;\n    background-color: #ddd;\n  }\n  .page {\n    stroke: #999;\n    stroke-dasharray: 0.5, 0.5;\n    fill: #fff;\n    display: inline;\n  }\n  &lt;/<i>style</i>&gt;\n  &lt;<i>rect</i> <var>class</var>=&quot;<kbd>page</kbd>&quot; <var>x</var>=&quot;<kbd>0</kbd>&quot; <var>y</var>=&quot;<kbd>0</kbd>&quot; <var>width</var>=&quot;<kbd>210</kbd>&quot; <var>height</var>=&quot;<kbd>297</kbd>&quot; /&gt;\n  <u>&lt;!-- your svg here --&gt;</u>\n&lt;/<i>svg</i>&gt;\n</code></pre>\n<p>Damit wird unsere Kosmetik nun nicht im Druck zu Gesicht bekommen, unterscheiden wir noch zwischen Screen- und Print-Styles:</p>\n<pre><code class=\"language-xml\"><b>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;</b>\n&lt;<i>svg</i> <var>width</var>=&quot;<kbd>210mm</kbd>&quot; <var>height</var>=&quot;<kbd>297mm</kbd>&quot; <var>viewBox</var>=&quot;<kbd>0 0 210 297</kbd>&quot; <var>version</var>=&quot;<kbd>1.1</kbd>&quot; <var>xmlns</var>=&quot;<kbd>http://www.w3.org/2000/svg</kbd>&quot;&gt;\n  &lt;<i>title</i>&gt;…&lt;/<i>title</i>&gt;\n  &lt;<i>style</i>&gt;\n  @page {\n    margin: 0;\n    padding: 0;\n  }\n  @page :footer {\n    display: none\n  }\n  @page :header {\n    display: none\n  }\n  .page {\n    display: none;\n  }\n  @media screen {\n    svg {\n      margin: 1em auto;\n      background-color: #ddd;\n    }\n    .page {\n      stroke: #999;\n      stroke-dasharray: 0.5, 0.5;\n      fill: #fff;\n      display: inline;\n    }\n  }\n  &lt;/<i>style</i>&gt;\n  &lt;<i>rect</i> <var>class</var>=&quot;<kbd>page</kbd>&quot; <var>x</var>=&quot;<kbd>0</kbd>&quot; <var>y</var>=&quot;<kbd>0</kbd>&quot; <var>width</var>=&quot;<kbd>210</kbd>&quot; <var>height</var>=&quot;<kbd>297</kbd>&quot; /&gt;\n  <u>&lt;!-- your svg here --&gt;</u>\n&lt;/<i>svg</i>&gt;\n</code></pre>\n<p>Fertig ist die <a href=\"https://journal.3960.org/posts/2021-12-04-print-stylesheets-fuer-svg-grafiken/orbit.svg\">SVG-Grafik mit Media Queries</a> (in diesem Falle ein Spielbrett für Raumschiffe) – sowohl für die Ausgabe am Bildschirm als auch den Druck vorbereitet.</p>\n<h2 id=\"weitere-ideen\">Weitere Ideen</h2>\n<p>Die Kombination aus SVG und CSS kann man natürlich noch weiter treiben. Da so ziemlich jede Media-Query im Browser für SVGs funktioniert, können auch Anpassungen an den <a href=\"https://journal.3960.org/posts/2020-06-15-css-variables-dark-mode/\">Dark Mode</a> oder für verschiedene Monitor-Größen direkt im SVG eingebettet werden.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Print-Stylesheets%E2%80%A6%20f%C3%BCr%20SVG-Grafiken&amp;url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2021-12-04-print-stylesheets-fuer-svg-grafiken%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />",
      "summary": "Vektor-Grafiken haben für Logos, Diagramme und Symbole die fantastische Eigenschaft, bei beliebig hoher Auflösung relativ kleine Dateigrößen zu verursachen.…",
      "date_published": "2021-12-04T18:23:43+01:00",
      "date_modified": "2021-12-04T18:23:43+01:00",
      "author": {
        "name": "Frank Boës",
        "url": "mailto:info@3960.org",
        "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
      },
      "authors": [
        {
          "name": "Frank Boës",
          "url": "mailto:info@3960.org",
          "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
        }
      ],
      "banner_image": "https://cdn.3960.org/favicon-192x192.png",
      "language": "de-DE",
      "image": "https://cdn.3960.org/favicon-192x192.png",
      "tags": [
        "SVG",
        "CSS",
        "Idee",
        "Programmierung",
        "Webdevelop"
      ]
    },
    {
      "id": "user/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/index.md",
      "url": "https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/",
      "title": "Flugnavigation mittels Rechenscheibe zum Selberbau",
      "content_html": "<p><a href=\"https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet.jpg\" class=\"gallery__link\" title=\"Eine Rechenscheibe zur Berechnung von Distanzen und Geschwindigkeiten.\"><img src=\"https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet-240x240.jpg\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"Eine Rechenscheibe zur Berechnung von Distanzen und Geschwindigkeiten.\" /></a> Da ich mich in letzter Zeit verstärkt mit der <a href=\"https://journal.3960.org/posts/2021-01-31-einsteiger-tutorial-fuer-il-2-sturmovik/\">Jagd-Fliegerei des Zweiten Weltkriegs</a> beschäftigt habe, musste ich mich wohl oder übel verstärkt mit Flug-Navigation ohne GPS oder sonstige technische Unterstützung auseinandersetzen. Dabei hilft es enorm, den Zusammenhang zwischen Fluggeschwindigkeit und zurückgelegter Strecke zu kennen.</p>\n<p>Mittels eines Taschenrechners oder einer App sind solche Berechnungen trivial. Aber wie wäre es, diese Berechnungen <em>ohne</em> elektronische Hilfsmittel zu lösen? Zum Beispiel mit einer Rechenscheibe?</p>\n<!-- more -->\n<h2 id=\"more\">Berechnungen</h2>\n<p>Schon in meinen Ausführungen zum <a href=\"https://journal.3960.org/posts/2019-09-22-vfr-ohne-technischen-schnickschnack/\">Sichtflug ohne technischen Schnickschnack</a> war eine der entscheidenden Hilfen beim Navigieren ohne elektronische Hilfen (neben der Kenntnis des Geländes und der Ziel-Richtung) vor allen Dingen die Kenntnis der Zeit, die man für eine bestimmten Streckenabschnitt auf dem Flugplan benötigt. Dabei kann bei einer genauen Kenntnis der Streckenlänge und der eigenen Geschwindigkeit über dem Boden relativ exakt berechnet werden, zu welchem Zeitpunkt die Strecke zurückgelegt sein müsste.</p>\n<p>Die eigentlichen Rechnungen für die Navigation sind recht übersichtlich, solange man die Einheiten korrekt mitführt:</p>\n<ul>\n<li>Strecke ÷ Geschwindigkeit = Zeit, also zum Beispiel: 10 km ÷ 100 km/h = 0.1h, also 6 Minuten</li>\n<li>Strecke ÷ Zeit = Geschwindigkeit, also zum Beispiel: 100 km ÷ 0.5h = 200 km/h</li>\n<li>Geschwindigkeit × Zeit = Strecke, also zum Beispiel: 500 km/h × 0.25h = 125 km</li>\n</ul>\n<p>Dabei gibt es die folgenden Herausforderung beim Kopfrechnen:</p>\n<ol>\n<li>Die eigentliche Berechnung der resultierenden Brüche. </li>\n<li>Die korrekten Umformung von Einheiten (Kilometern, nautische Meilen, <i>statute miles</i>, Knoten, Stunden, Minuten)</li>\n</ol>\n<p>Die Einheiten umzurechnen ist wegen der nicht ganzzahligen Multiplikatoren teilweise etwas schwierig im Kopf zu vollziehen:</p>\n<div class=\"table-wrapper\"><table>\n<caption id=\"conversion-imperial-to-metric-units\">Conversion Imperial to Metric Units</caption>\n<colgroup>\n<col />\n<col />\n<col class=\"table-cell--right\" />\n</colgroup>\n<thead>\n<tr>\n<th>Imperial unit</th>\n<th>Symbol</th>\n<th style=\"text-align:right\">Metric unit</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>1 nautical mile</td>\n<td>1 NM</td>\n<td style=\"text-align:right\">1852m</td>\n</tr>\n<tr>\n<td>1 knot</td>\n<td>1 kn</td>\n<td style=\"text-align:right\">1.852 km/h</td>\n</tr>\n<tr>\n<td>1 statute mile</td>\n<td>1 mi</td>\n<td style=\"text-align:right\">1609.344m</td>\n</tr>\n<tr>\n<td>1 mile per hour</td>\n<td>1 mph</td>\n<td style=\"text-align:right\">1.609 km/h</td>\n</tr>\n</tbody></table></div>\n<p>…ganz zu schweigen von der Tatsache, dass eine Stunde aus sechzig Minuten besteht und damit eine Stundenangabe mit Nachkommastellen im Kopf schwierig in eine Angabe in Minuten umzurechnen ist.</p>\n<p>Die Komplikation, dass die gemessene Fluggeschwindigkeit (<i>air speed</i>) nicht zwangsläufig mit der Geschwindigkeit über dem Boden (<i>ground speed</i>) übereinstimmt, ignorieren wir vorerst – können aber bei Kenntnis der Windrichtung und -stärke dies ebenfalls näherungsweise per einfacher Arithmetik mit einbeziehen.</p>\n<p>Im Regelfall kann man sich mit einzelnen Faustformeln behelfen, die man vorher durchgerechnet haben sollte.</p>\n<div class=\"video-player video-player--youtube\"><iframe allowfullscreen=\"allowfullscreen\" title=\"IL-2 Great Battles: Navigating in VR\" src=\"https://www.youtube-nocookie.com/embed/Ydlv6AD3oHo?enablejsapi=1\" srcdoc=\"&lt;style&gt;*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}&lt;/style&gt;&lt;a href=&quot;https://www.youtube.com/embed/Ydlv6AD3oHo?autoplay=1&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/Ydlv6AD3oHo/hqdefault.jpg&quot; alt=&quot;&quot;&gt;&lt;span&gt;▶&lt;/span&gt;&lt;/a&gt;\"></iframe><!-- img src=\"https://img.youtube.com/vi/Ydlv6AD3oHo/hqdefault.jpg\" --></div>\n<p>Bei Variablen Strecken und Geschwindigkeiten wird es aber höchste Zeit, sich mit nicht-elektronischen Rechenhilfen auseinanderzusetzen: Rechenschiebern beziehungsweise Rechenscheiben.</p>\n<h2 id=\"rechenscheiben-für-divisionen-und-lineare-zusammenhänge\">Rechenscheiben für Divisionen und lineare Zusammenhänge</h2>\n<p><a href=\"https://de.wikipedia.org/wiki/Rechenscheibe\">Rechenscheiben</a> sind kompakte, runde Ausführung eines <a href=\"https://de.wikipedia.org/wiki/Rechenschieber\">Rechenschiebers</a>. Je nach Findigkeit ihres Konstrukteurs sind sie in der Lage, eine ganze Menge mathematische Operationen rein grafisch-mechanisch durchzuführen. Gerade lineare Zusammenhänge sind mit Hilfe <a href=\"https://de.wikipedia.org/wiki/Logarithmus\">logarithmischer Skalen</a> gut zu lösen. Dabei werden zwei logarithmische Skalen gegeneinander verschoben, das Ergebnis ist dann auf einer dritte Skala ablesbar.</p>\n<p>So bietet zum Beispiel der klassische <a href=\"https://en.wikipedia.org/wiki/E6B\">mechanische Navigationsrechner E6-B</a> eine ganze Reihe von Möglichkeiten, Umrechnungen zwischen verschiedenen Einheiten durchzuführen, die für die (Flug-)Navigation hilfreich sind. Ich persönlich wollte aber einen nicht ganz so komplexen Rechner. Stattdessen sollte er übersichtlicher sein, und gleichzeitig alle Grundbedürfnisse eines Jagdfliegers abbilden.</p>\n<p>Höchste Zeit also, das Grafikprogramm anzuwerfen und sich mit Logarithmen und Winkelberechnungen zu beschäftigen, um einen eigenen Navigations-Drehrechner zu entwerfen.</p>\n<h2 id=\"das-distanz-gerät-dg21\">Das Distanz-Gerät DG21</h2>\n<p>Ziel meiner Bemühungen war eine Navigations-Rechenscheibe, die man mit heimischen Hilfsmitteln herstellen konnte. Mein Navigationsrechner sollte folgendes beherrschen:</p>\n<ul>\n<li>Umrechnung von Knoten (kn), Meilen pro Stunde (mph) und Kilometern pro Stunde (km/h).</li>\n<li>Umrechnung von <a href=\"https://de.wikipedia.org/wiki/Seemeile\">nautischen Meilen</a> (NM), <i>Statute Miles</i> (mi) und Kilometern (km).</li>\n<li>Berechnung der zurückgelegten Strecke bei einer gegebenen Geschwindigkeit und Zeit.</li>\n<li>Berechnung der benötigten Zeit bei einer gegebenen Geschwindigkeit und Strecke.</li>\n<li>Berechnung der benötigten Geschwindigkeit bei einer gegebenen Zeit und Strecke.</li>\n</ul>\n<p>Die ungewöhnliche Ansammlung von verschiedenen Einheiten hat nicht zuletzt damit zu tun, dass je nach Kartenmaterial und Fluggerät sowohl imperiale als auch metrische Angaben wild miteinander kombiniert werden können. So hatten west-alliierte Jagdflugzeuge Angaben in Meilen pro Stunde, während Flugzeuge der Achsenmächte und der Sowjetunion stattdessen Kilometer pro Stunde verwendeten. Andersherum wird zum Beispiel in <i>IL-2 Great Battles</i> ein 10km-Kartenraster verwendet, während Streckenabschnitte in Meilen <em>oder</em> Kilometern angegeben werden können. Bei modernen Simulatoren wiederum werden Geschwindigkeiten in Knoten angegeben, während Strecken gerne in nautischen Meilen gemessen werden.</p>\n<p><a href=\"https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet-detail.jpg\" class=\"gallery__link\" title=\"Eine Detail-Aufnahme des Distanz-Gerätes.\"><img src=\"https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet-detail-400x225.jpg\" class=\"default\" width=\"400\" height=\"225\" style=\"--aspect-ratio: 16/9;\" alt=\"Eine Detail-Aufnahme des Distanz-Gerätes.\" /></a></p>\n<p>Nach einigen Papierprototypen habe ich mit dem <strong>Distanz-Gerät DG21</strong> eine für mich passable Lösung gefunden, kompakt und übersichtlich alle Anforderungen zu erfüllen. Das Distanz-Gerät besteht aus zwei gegeneinander verdrehbaren Scheiben. In einem Sichtfenster kann dabei die Geschwindigkeit eingestellt beziehungsweise ausgegeben werden, während zwei aufeinander treffende Ringskalen den Zusammenhang zwischen Strecke und Zeit abbilden.</p>\n<p>Die Funktionsweise ist dabei einfach:</p>\n<ol>\n<li>Auf dem äußersten Skalenring befindet sich die Angabe für Strecke (Dividend),</li>\n<li>auf der dagegen verdrehbaren Scheibe die Angabe der Zeit (Divisor),</li>\n<li>und auf als Resultat in einem Sichtfenster die Geschwindigkeit (Wert des Quotienten).</li>\n</ol>\n<p>Solange zwei der Werte bekannt sind, ergibt sich automatisch der dritte Wert. Darüber hinaus werden <em>alle</em> Zusammenhänge zwischen Strecke und Zeit grafisch angezeigt, ohne die Scheibe weiter manipulieren zu müssen.</p>\n<p>Die Umrechnungen für Strecke und Geschwindigkeit sind dabei als nebeneinanderliegende, fest miteinander verbundene Skalenringe ausgeführt.</p>\n<p>Dabei habe ich zwei Varianten gebaut, die hier zum Herunterladen, Ausdrucken und Zusammenbasteln bereitstehen:</p>\n<ol>\n<li>Das <strong><a href=\"https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet_dg21a2.svg\" download>Distanz-Gerät DG21A2</a></strong> (Download als SVG-Datei, circa 300 KB) ist eine sehr kompakte Version, in der Version DG21A2.2 hat es auch eine präzise Skala für geringe Geschwindigkeiten. Diese Scheibe.</li>\n<li>Das <strong><a href=\"https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet_dg21a3.svg\" download>Distanz-Gerät DG21A3</a></strong> (Download als SVG-Datei, circa 330 KB) bietet gegenüber dem DG21A2 zusätzlich die Umrechnung in Meter pro Sekunde (m/s), ist dafür aber etwas unübersichtlicher und hat auch keine Präzisionsskala für geringe Geschwindigkeiten.</li>\n</ol>\n<p>Beide Do-it-yourself-Navigationsrechner können mit einem Drucker auf Papier oder Pappe in der Größe DIN A4 ausgedruckt und mit einem scharfen Messer ausgeschnitten werden. Die beiden Scheiben werden mit einer Musterklammer verbunden, und können danach für die Berechnung gegeneinander verdreht werden.</p>\n<p>Die Rechner sind außerdem Open Source. Die SVG-Dateien können mit jedem beliebigen Vektor-Programm geöffnet und bearbeitet werden. Und da beide Dateien unter der „Creative Commons“-Lizenz stehen, ist das rechtlich auch ohne Probleme möglich.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Flugnavigation%20mittels%20Rechenscheibe%20zum%20Selberbau&amp;url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />",
      "summary": "Da ich mich in letzter Zeit verstärkt mit der Jagd-Fliegerei des Zweiten Weltkriegs beschäftigt habe, musste ich mich wohl oder übel verstärkt mit Flug…",
      "date_published": "2021-03-05T19:20:29+01:00",
      "date_modified": "2021-12-03T17:58:37+01:00",
      "author": {
        "name": "Frank Boës",
        "url": "mailto:info@3960.org",
        "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
      },
      "authors": [
        {
          "name": "Frank Boës",
          "url": "mailto:info@3960.org",
          "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
        }
      ],
      "banner_image": "https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet.jpg",
      "language": "de-DE",
      "image": "https://journal.3960.org/posts/2021-03-05-flugnavigation-mittels-rechenscheibe-zum-selberbau/distanz-geraet.jpg",
      "tags": [
        "Fliegerei",
        "Geografie",
        "Idee",
        "Simulation",
        "Aerofly FS2",
        "Technologie",
        "SVG"
      ]
    },
    {
      "id": "user/posts/2020-11-28-vector-art-fuer-hardspace-shipbreakers/index.md",
      "url": "https://journal.3960.org/posts/2020-11-28-vector-art-fuer-hardspace-shipbreakers/",
      "title": "Vector-Art für „Hardspace: Shipbreakers“",
      "content_html": "<p><img src=\"https://journal.3960.org/posts/2020-11-28-vector-art-fuer-hardspace-shipbreakers/lynx-salvage.svg\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> Das Spiel <a href=\"https://hardspace-shipbreaker.com/\">Hardspace: Shipbreakers</a> hat es mir sehr angetan. Neben dem gelungenen Spielprinzip zieht mich vor allen Dingen die Atmosphäre in den Bann. </p>\n<p>Zur Atmosphäre gehört das allgegenwärtige Branding des Arbeitgebers des Protagonisten, „Lynx Salvage“. Für die private Verwendung habe ich daher das <a href=\"https://journal.3960.org/posts/2020-11-28-vector-art-fuer-hardspace-shipbreakers/lynx-salvage.svg\">Logo der Firma „Lynx Salvage“ als SVG-Vektor-Art</a> vektorisiert.</p>\n<p>Diese Datei besteht aus überschneidungsfreien Außenlinien des Logos und des Schriftzugs – und eignet sich daher zum Bedrucken oder Besticken von Kleidung.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=Vector-Art%20f%C3%BCr%20%E2%80%9EHardspace%3A%20Shipbreakers%E2%80%9C&amp;url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2020-11-28-vector-art-fuer-hardspace-shipbreakers%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />",
      "summary": "Das Spiel Hardspace: Shipbreakers hat es mir sehr angetan. Neben dem gelungenen Spielprinzip zieht mich vor allen Dingen die Atmosphäre in den Bann.\nZur…",
      "date_published": "2020-11-28T19:25:23+01:00",
      "date_modified": "2020-12-01T11:17:47+01:00",
      "author": {
        "name": "Frank Boës",
        "url": "mailto:info@3960.org",
        "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
      },
      "authors": [
        {
          "name": "Frank Boës",
          "url": "mailto:info@3960.org",
          "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
        }
      ],
      "banner_image": "https://cdn.3960.org/favicon-192x192.png",
      "language": "de-DE",
      "image": "https://cdn.3960.org/favicon-192x192.png",
      "tags": [
        "Raumfahrt",
        "Spiel",
        "SVG"
      ]
    },
    {
      "id": "user/posts/2020-04-05-svg-web-components/index.md",
      "url": "https://journal.3960.org/posts/2020-04-05-svg-web-components/",
      "title": "SVG und Web Components",
      "content_html": "<p><img src=\"https://journal.3960.org/posts/2020-04-05-svg-web-components/hsi-240x240.png\" class=\"quad\" width=\"240\" height=\"240\" style=\"--aspect-ratio: 1/1;\" alt=\"\" /> <a href=\"https://www.webcomponents.org/\" rel=\"nomention\">Web Components</a> erlauben in modernen Browsern, eigene Tags mit beliebig komplexen Verhalten zu definieren. Und wie der Name „Komponente“ schon nahelegt, kann man diese kleinen Bibliotheken beliebig oft weiterverwenden, sobald diese einmalig geladen wurden.</p>\n<p>Mit einigen kleinen Kniffen kann die Entwicklung solcher Komponenten noch schneller von der Hand gehen.</p>\n<!-- more -->\n<h2 id=\"more\">Wie starte ich mit Web Components?</h2>\n<p>Für den Einstieg in das Thema Web Components empfiehlt sich die Lektüre der ausgezeichneten <a href=\"https://developers.google.com/web/fundamentals/web-components\" rel=\"nomention\">Einführung von Google</a> und <a href=\"https://css-tricks.com/an-introduction-to-web-components/\">CSS-Tricks</a>. Andere Anleitungen basieren teilweise auf älteren Ideen, die getrost ignoriert werden können.</p>\n<p><strong>Update 2020–09</strong>: Die Vielzahl der Wege, wie man eine Web Component bauen kann, <a href=\"https://webcomponents.dev/blog/all-the-ways-to-make-a-web-component/\" rel=\"nomention\">hat webcomponents.dev veranlasst, eine Auflistung aller möglichen Wege zum Erstellen einer Web Component zusammenzustellen</a>.</p>\n<p>Außerdem lohnt es sich immer, moderne Beispiele anzuschauen. Ich für meinen Teil habe entsprechend versucht, einen <a href=\"https://en.wikipedia.org/wiki/Horizontal_situation_indicator\" rel=\"nomention\">Horizontal Situation Indicator</a> als Vanilla-JavaScript Web Component mustergültig zu bauen. Der daraus resultierende <a href=\"https://github.com/fboes/webcomponent-hsi\">Quellcode der „Horizontal Situation Indicator“ Web Component</a> wird im Rahmen dieses Artikels immer wieder als Beispiel herangezogen.</p>\n<div class=\"embed embed--codepen\"><iframe allowfullscreen=\"allowfullscreen\" title=\"Die montierte &quot;Horizontal Situation Indicator&quot; Web Component\" src=\"https://journal.3960.org//codepen.io/fboes/embed/dyoBvzP/?height=265&amp;theme-id=0&amp;default-tab=result&amp;embed-version=2\" height=\"265\"></iframe></div>\n<h2 id=\"wie-denkt-man-eine-web-component\">Wie <em>denkt</em> man eine Web Component?</h2>\n<p>Die größte Hürde für den angehenden Komponenten-Bauer ist das Verständnis, wie all die schönen Teile zusammenpassen.</p>\n<p>Da eine Web Compoment gekapselt ist, kann nur über eine vorher definierte Schnittstelle von außen Zugriff auf ihr Verhalten genommen werden. Es ist also sehr sinnig, die Konzeption und den Bau einer Web Component wie den Bau einer Schnittstelle bzw. eines Interfaces zu verstehen.</p>\n<p>Als Beispiel nehmen wir einfach die <a href=\"https://3960.org/webcomponent-hsi/\">fertige Implementation der HSI-Web-Component</a>:</p>\n<pre><code class=\"language-html\">&lt;<i>horizontal-situation-indicator</i> <var>id</var>=&quot;<kbd>hsi</kbd>&quot; <var>heading</var>=&quot;<kbd>45.0</kbd>&quot; <var>heading-select</var>=&quot;<kbd>0.0</kbd>&quot;&gt;&lt;/<i>horizontal-situation-indicator</i>&gt;\n</code></pre>\n<h3 id=\"attribute-bzw-properties\">Attribute bzw. Properties</h3>\n<p>Beim Bau einer Web Component müssen neben dem <strong>Namen der Web Component</strong> auch die <strong>Attribute der Web Component und ihre möglichen Werte</strong> definiert werden.</p>\n<p>Diese Attribute verwandeln sich innerhalb der JavaScript-Repräsentation der Web Component in <strong>Properties</strong>, die mit den Attributen synchronisiert sind:</p>\n<pre><code class=\"language-javascript\"><b>const</b> el = <b>document</b>.<b>getElementById</b>(<kbd>'hsi'</kbd>);\nel.<b>getAttribute</b>(<kbd>'heading'</kbd>); <u>// &quot;45.0&quot;</u>\nel.heading; <u>// &quot;45.0&quot;</u>\n\nel.<b>setAttribute</b>(<kbd>'heading'</kbd>, <kbd>'60.0'</kbd>);\nel.<b>getAttribute</b>(<kbd>'heading'</kbd>); <u>// &quot;60.0&quot;</u>\nel.heading; <u>// &quot;60.0&quot;</u>\n\nel.heading = <kbd>'135.0'</kbd>;\nel.<b>getAttribute</b>(<kbd>'heading'</kbd>); <u>// &quot;135.0&quot;</u>\nel.heading; <u>// &quot;135.0&quot;</u>\n</code></pre>\n<p>Bei dem Zugriff auf eine Property mit einem <code>-</code> im Namen funktioniert der Zugriff leicht anders:</p>\n<pre><code class=\"language-javascript\">el.<b>getAttribute</b>(<kbd>'heading-select'</kbd>);\n<u>//el.heading-select existiert nicht</u>\nel[<kbd>'heading-select'</kbd>]; <u>// korrekte Schreibweise in `[]`</u>\n</code></pre>\n<p>Die Schreibweise mit <code>[]</code> erlaubt auch den dynamischen Zugriff auf Properties:</p>\n<pre><code class=\"language-javascript\"><b>let</b> attrName = <kbd>'heading-select'</kbd>;\n\nel.<b>getAttribute</b>(attrName);\nel[attrName];\n</code></pre>\n<h3 id=\"methoden\">Methoden</h3>\n<p>Darüber hinaus kann der Entwickler einer Web Component noch festlegen, dass die Komponente <strong>JavaScript-Methoden</strong> anbietet. Diese erlauben zum Beispiel von außen der Komponente zu befehlen, komplexe Prozesse innerhalb der Komponente zu erledigen.</p>\n<pre><code class=\"language-javascript\">el.synchronizeHeading();\n</code></pre>\n<p>Da JavaScript keine Sichtbarkeiten wie <code>public</code> und <code>private</code> für Methoden hat, hat sich als Konvention herausgebildet, private Methoden mit einem <code>_</code> zu beginnen.</p>\n<h3 id=\"events\">Events</h3>\n<p>Außerdem kann eine Web Component noch <strong>JavaScript-Events</strong> erzeugen, die außerhalb der Komponente registriert werden können. So emittiert z.B. das <code>&lt;video&gt;</code>-Tag Events, wenn ein Video beendet wurde, was ohne dieses Event außerhalb des Tags keiner wissen könnte.</p>\n<h2 id=\"was-kann-eine-web-component-alles-darstellen\">Was kann eine Web Component alles darstellen?</h2>\n<p>Web Components können fast alles darstellen, was auch regulär in einem Browser dargestellt werden kann. Besonderes Augenmerk muss aber darauf gelegt werden, dass alle benötigten Bestandteile in der einen JavaScript-Datei enthalten ist, die die Web Component definiert.</p>\n<p>Am Einfachsten einzubinden sind die folgenden Dinge:</p>\n<ul>\n<li>HTML</li>\n<li>CSS für die Web Component</li>\n<li>JavaScript-Interaktion für die Web Component</li>\n</ul>\n<p>Alle anderen Ressourcen (<strong>Bilder, Videos, Töne</strong>) können mit einem Trick eingeschmuggelt werden: Mittels <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\" rel=\"nomention\">Data URLs</a> können Binär-Dateien in Base64-Zeichenketten umgewandelt werden, die dann z.B. im <code>src</code>-Attribut eines <code>&lt;img&gt;</code> eingebunden werden können.</p>\n<p>Besonders spannend: <strong>SVG-Bilder</strong> sind nicht nur schön kompakt in Bezug auf ihren Speicherplatz, sondern <a href=\"https://css-tricks.com/using-svg/#article-header-id-5\" title=\"Inline SVG in HTML\">können auch direkt in das HTML</a> eingebunden werden – benötigen also den Base64-Trick nicht.</p>\n<h2 id=\"gibt-es-build-tools-für-web-components\">Gibt es Build Tools für Web Components?</h2>\n<p>In der Tat gibt es eine ganze Menge Tools, um das Zusammensetzen der einzelnen Teile einer Web Component zu unterstützen. In der Regel reicht aber <a href=\"https://github.com/fboes/webcomponent-hsi/blob/master/dev/build.js\">ein kleiner flotter Node.js-Mehrzeiler als Web Component Build Tool</a>, der aus einzelnen Dateien die eigentliche Web Component zusammensetzt. Die Kurzfassung:</p>\n<pre><code class=\"language-javascript\"><b>const</b> fs = <i>require</i>(<kbd>'fs'</kbd>);\n\n<b>let</b> source      = fs.readFileSync(<kbd>`horizontal-situation-indicator.js`</kbd>).toString();\n<b>let</b> templateCss = fs.readFileSync(<kbd>`src/horizontal-situation-indicator.css`</kbd>).toString();\n<b>let</b> templateSvg = fs.readFileSync(<kbd>`src/horizontal-situation-indicator.svg`</kbd>).toString();\n\nsource = source.<b>replace</b>(/(&lt;style&gt;).*(&lt;<samp>\\/</samp>style&gt;)/ms, templateCss);\nsource = source.<b>replace</b>(/(&lt;<samp>\\/</samp>style&gt;).*(<kbd>`)/ms, templateSvg);\nfs.writeFileSync(`</kbd>horizontal-situation-indicator.js`, source);\n</code></pre>\n<p>Das tatsächliche Skript ist zwar etwas komplexer, das Grundprinzip ist aber ein denkbar einfaches: Die Entwicklung von SVG und CSS (oder jedem anderen Dateitypen) findet in separaten Dateien statt, die mit dem obigen Skript einfach in das JavaScript der Web Component hineinkopiert werden. Unter anderem könnte hier auch die Konvertierung von Binär-Daten in ihre Base64-Entsprechung durchgeführt werden.</p>\n<h2 id=\"kann-man-das-erzeugen-von-get-und-set-für-jede-property-abkürzen\">Kann man das Erzeugen von <code>get</code> und <code>set</code> für jede Property abkürzen?</h2>\n<p>Da jeder Web Component eine Liste der zu synchronisierenden Attribute / Properties mit der Methode <code>observedAttributes</code> bekannt gemacht werden muss, kann genau diese Liste im <code>constructor</code> auch <a href=\"https://css-tricks.com/creating-a-custom-element-from-scratch/\">zum programmatischen Erzeugern von Gettern / Settern</a> verwendet werden.</p>\n<pre><code class=\"language-javascript\"><i>this</i>.constructor.observedAttributes.<i>forEach</i>((attrName) <samp>=&gt;</samp> {\n  Object.defineProperty(<i>this</i>, attrName, {\n    get() {\n      <i>return</i> <i>this</i>.<b>getAttribute</b>(attrName);\n    },\n    set(attrValue) {\n      <i>this</i>.<b>setAttribute</b>(attrName, attrValue);\n    }\n  });\n});\n</code></pre>\n<p>Diese Methode hat in einigen Web-Components-Frameworks möglicherweise Nachteile – für die Vanilla-Nutzung ist sie aber weitestgehend ungefährlich.</p>\n<h2 id=\"wie-löse-ich-styling-in-der-web-component\">Wie löse ich Styling <em>in</em> der Web Component?</h2>\n<p>Da Web Components sowieso nur in aktuellen Browsern zuverlässig funktionieren, kann man sich gleichzeitig auch auf fortgeschrittene CSS-Möglichkeiten verlassen. Um CSS innerhalb der Komponente von außen zu beeinflussen, verwende ich <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/--*\">CSS-Variablen bzw. CSS-Custom-Properties</a>. Innerhalb des CSS&#39; des Komponente definiere ich sie direkt an der DOM-Wurzel der Komponente:</p>\n<pre><code class=\"language-css\"><i>:host</i> {\n  <var>--background-color</var>: black;\n  <var>--foreground-color</var>: white;\n  <var>--heading-select-color</var>: cyan;\n  <var>--stroke-width</var>: 0.5;\n}\n<u>/*…und verwende diese CSS-Custom-Properties dann später in Variablen - bei mir z.B. als SVG-CSS-Eigenschaften:*/</u>\n\n<i>#background</i> {\n  <b>fill</b>: <b>var</b>(<var>--background-color</var>);\n}\n<i>*</i> {\n  <b>fill</b>: <b>var</b>(<var>--foreground-color</var>);\n}\n<i>*[stroke]</i> {\n  <b>stroke-width</b>: <b>var</b>(<var>--stroke-width</var>);\n}\n\n<i>#heading-select</i> {\n  <b>fill</b>: <b>var</b>(<var>--heading-select-color</var>);\n}\n</code></pre>\n<p>Wer nun auch immer diese Komponente verwendet, kann diese CSS-Custom-Properties von außen beeinflussen:</p>\n<pre><code class=\"language-css\"><i>horizontal-situation-indicator</i> {\n  <var>--heading-select-color</var>: red;\n  <var>--stroke-width</var>: 1;\n}\n</code></pre>\n<p>Bei der <a href=\"https://3960.org/webcomponent-hsi/\">Beispiel-Implementation von <code>&lt;horizontal-situation-indicator&gt;</code></a> kann auch bewundert werden, wie durch JavaScript diese CSS-Custom-Properties am lebenden Objekt verändert werden, und in der Komponente sich alles fröhlich verfärbt.</p>\n<p>Ganz nebenbei haben wir für die Komponente eine weitere Schnittstelle geschaffen – in diesem Fall eine Styling-Schnittstelle.</p>\n<p><strong>Update:</strong> Andererseits können aber auch einzelne DOM-Knoten ohne CSS-Properties zum expliziten Styling freigegeben werden. Eine <a href=\"https://css-tricks.com/styling-in-the-shadow-dom-with-css-shadow-parts/\">Anleitung zum Freigeben von DOM-Knoten aus dem Shadow-DOM zum CSS-Styling bei CSS-Tricks</a> zeigt die notwendigen Anpassungen im HTML:</p>\n<pre><code class=\"language-html\">&lt;<i>div</i> <var>part</var>=&quot;<kbd>style-me</kbd>&quot;&gt;…&lt;/<i>div</i>&gt;\n</code></pre>\n<p>…und dem CSS im Eltern-Dokument:</p>\n<pre><code class=\"language-css\"><i>horizontal-situation-indicator::part(style-me)</i> {\n  <b>font-weight</b>: bold;\n}\n</code></pre>\n<p>Auch hier hat wieder der Autor der Komponente die Herrschaft über die Elemente, die er nach außen freigibt – wie bei einer Schnittstelle.</p>\n<h2 id=\"wie-animiere-ich-svgs-in-web-components\">Wie animiere ich SVGs in Web Components?</h2>\n<p>Der eigentliche Clou der <a href=\"https://github.com/fboes/webcomponent-hsi\">HSI Web Component</a> ist die generelle Fähigkeit von JavaScript, DOM-Elemente und ihre Eigenschaften zu verändern. Dies können sowohl CSS-Eigenschaften als auch generelle Attribute von DOM-Elementen sein.</p>\n<p>Bei SVG bieten sich die folgenden Operationen an:</p>\n<ul>\n<li>Änderung von <code>stroke</code> und <code>stroke-width</code> zur Beeinflussung von Linien</li>\n<li>Änderung von <code>fill</code> zur Veränderung der Füllfarbe</li>\n<li>Änderung von <code>opacity</code> zur Veränderung der Durchsichtigkeit eines Elements</li>\n<li>Veränderung von Position, Größe und Rotation mittels <code>transform</code></li>\n<li>Austausch des Text-Inhalts von <code>&lt;text&gt;</code>-Knoten mittels <code>.textContent</code></li>\n</ul>\n<p>Bei SVG gibt es dabei die Möglichkeit, nicht nur via CSS diese Eigenschaften zu beeinflussen, sondern auch durch das Setzen von Attributen innerhalb des SVGs an einzelnen SVG-DOM-Knoten.</p>\n<p>Auch das ist in der <a href=\"https://3960.org/webcomponent-hsi/\">Beispiel-Implementation von <code>&lt;horizontal-situation-indicator&gt;</code></a> zu bestaunen – hier sind die Attribute der Komponente mit Animationsmethoden verknüpft, so dass Änderungen an den Attributen bzw. Properties der Web Component zeitgleich die Darstellung des eingeschlossenen SVGs ändert.</p>\n<h2 id=\"wie-sollte-eine-dokumentation-für-eine-web-compontent-aussehen\">Wie sollte eine Dokumentation für eine Web Compontent aussehen?</h2>\n<p>Da eine Web Component im Endeffekt eine Schnittstelle ist, muss es dazu eine <strong>Schnittstellen-Dokumentation</strong> geben. Ohne diese Dokumentation können andere Entwickler, die die Komponente verwenden möchten, nicht zuverlässig wissen, wie die Komponente zu bedienen ist.</p>\n<p>Als Minimum muss eine Dokumentation enthalten:</p>\n<pre><code class=\"language-markdown\"><em>## Properties</em>\n\n| Name           | Type    | Default | Description  |\n| -------------- | ------- | ------- | ------------ |\n| <samp>`heading`</samp>      | <samp>`float`</samp> | <samp>`null`</samp>  | Lorem ipsum… |\n\n<em>## Methods</em>\n\n| Name           | Parameters | Description         |\n| -------------- | ---------- | ------------------- |\n| <samp>`revHeading`</samp>   | none       | Lorem ipsum…        |\n\n<em>## Events</em>\n\n| Name           | Description                      |\n| -------------- | -------------------------------- |\n| <samp>`synchronized`</samp> | Lorem ipsum…                     |\n\n<em>## Styling</em>\n\n<samp>```css\ncomponent-name {\n  --background: color; /* Lorem ipsum… */\n}\n\ncomponent-name::part(part-name) {} /* Lorem ipsum… */\n```</samp>\n</code></pre>\n<h2 id=\"fazit\">Fazit</h2>\n<p>Der fertige <a href=\"https://github.com/fboes/webcomponent-hsi\">Horizontal Situation Indicator als Web Component ist in einem GitHub-Repository</a> gelandet, und einen Blick auf die <a href=\"https://3960.org/webcomponent-hsi/\">fertige Implementation der HSI-Web-Component</a> erlaubt einen interaktiven Blick auf die Zusammenhänge in der Komponente.</p><img src=\"https://stats.3960.org/p.php?idsite=2amp;action_name=SVG%20und%20Web%20Components&amp;url=https%3A%2F%2Fjournal.3960.org%2Fposts%2F2020-04-05-svg-web-components%2F%3Futm_source%3Dnewsfeed_view\" style=\"border:0;\" alt=\"\" />",
      "summary": "Web Components erlauben in modernen Browsern, eigene Tags mit beliebig komplexen Verhalten zu definieren. Und wie der Name „Komponente“ schon nahelegt, kann…",
      "date_published": "2020-04-05T18:41:26+02:00",
      "date_modified": "2023-03-05T10:14:07+01:00",
      "author": {
        "name": "Frank Boës",
        "url": "mailto:info@3960.org",
        "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
      },
      "authors": [
        {
          "name": "Frank Boës",
          "url": "mailto:info@3960.org",
          "avatar": "https://www.gravatar.com/avatar/71fcf51cf2ae9acdd54182d3e367ceca"
        }
      ],
      "banner_image": "https://journal.3960.org/posts/2020-04-05-svg-web-components/hsi.png",
      "language": "de-DE",
      "image": "https://journal.3960.org/posts/2020-04-05-svg-web-components/hsi.png",
      "tags": [
        "Webdevelop",
        "Web-Components",
        "SVG",
        "Javascript",
        "CSS",
        "Programmierung",
        "Technologie",
        "The Cool",
        "Fliegerei"
      ]
    }
  ]
}