JürgenB: SVG skalieren

problematische Seite

Hallo,

ich habe eine Grafik in SVG mit einer Angabe zum viewport. Daurch ist die Grafik skalierbar. Leider wird nicht nur die Position der Grafikelemente mit der Größe des SVG-Elements skaliert, sondern auch deren Größe. Siehe hierzu die „problematische Seite“. Da ich die Grafik per JS erzeuge, hier noch mal der erzeugte Code:

#plotarea { background-color:#ffffff; width:90%; height:80vh; border: 1px solid black }
<figure id="plotarea">
  <svg preserveAspectRatio="none" viewBox="0 0 500 500" height="100%" width="100%">
    <line stroke-width="1" stroke="black" y2="460" x2="480" y1="480" x1="20"></line>
    <polyline points="20,475 15,10 490,50 470,400 400,450 " fill="none" stroke-width="3" stroke="green"></polyline>
    <polygon points="70,430 70,70 430,70 430,430 " fill-opacity="0.2" fill="red" stroke="none"></polygon>
    <text y="430" x="70" dy="1.1em" text-anchor="end" style="font-size: 0.8em; color: blue; fill: blue;">Text_ro</text>
    <text y="430" x="70" dy="-0.1em" text-anchor="start" style="font-size: 1em; color: blue; fill: blue;">Text_lu</text>
    <text transform="translate(0,0) rotate(270)" y="430" x="-250" dy="0.3em" text-anchor="middle" style="font-size: 1.5em; color: blue; fill: blue;">Text_mm</text>
  </svg>
</figure>

Gibt es eine Möglichkeit, diese Grafik so zu gestalten, dass die Positionsangaben mit der Größe des SVG-Elements mit skalieren, die Text-Größe und die Linienstärke aber nicht?

Gruß
Jürgen

  1. problematische Seite

    Hallo Jürgen,

    Gibt es eine Möglichkeit, diese Grafik so zu gestalten, dass die Positionsangaben mit der Größe des SVG-Elements mit skalieren, die Text-Größe und die Linienstärke aber nicht?

    Für Linienstärken funktioniert in neueren Browsern bereits die für SVG2 vorgesehene Eigenschaft bzw. Attribut vector-effect mit Wert non-scaling-stroke.

    Im CSS:

    svg * { vector-effect: non-scaling-stroke; }
    

    Für Textgrößen kenne ich nichts Vergleichbares. Hier müsste man mit JS beim SVG-Element bzw. den Textelementen via onzoom oder onresize die Eigenschaft currentScale abfragen und den Textelementen bei selbiger Eigenschaft oder via transform="scale(x)" den reziproken Wert zuweisen.

    Grüße, Thomas

    1. problematische Seite

      Hallo Thomas,

      Für Textgrößen kenne ich nichts Vergleichbares. Hier müsste man mit JS beim SVG-Element bzw. den Textelementen via onzoom oder onresize die Eigenschaft currentScale abfragen und den Textelementen bei selbiger Eigenschaft oder via transform="scale(x)" den reziproken Wert zuweisen.

      vielen Dank für die Infos. Ich glaube, ich bleibe dann bei der jetzigen Variante, bei er ich nach resize die ganze Grafik neu erstelle.

      Gruß
      Jürgen

    2. problematische Seite

      @@ThomasM

      svg * { vector-effect: non-scaling-stroke; }

      Oder als Attribut vector-effect="non-scaling-stroke".

      Für Textgrößen kenne ich nichts Vergleichbares.

      Wie mein geschätzter Kollege mir zuflüsterte, ist auch dafür was in der Mache.

      Hier müsste man mit JS beim SVG-Element bzw. den Textelementen via onzoom oder onresize die Eigenschaft currentScale abfragen und den Textelementen bei selbiger Eigenschaft oder via transform="scale(x)" den reziproken Wert zuweisen.

      In Making responsive SVG graphs wird unter Preventing the distortions wohl dasselbe behandelt.

      LLAP 🖖

      --
      “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
      Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
      1. problematische Seite

        Hallo Gunnar,

        In Making responsive SVG graphs wird unter Preventing the distortions wohl dasselbe behandelt.

        vielen Dank für den Link. Ich werde mal versuchen, den Code zu verstehen.

        Leider hat die Seite zwei nicht unerhebliche Probleme:

        • Der Code läuft nicht im IE. Ärgerlich, aber das kennen wir ja schon.
        • Die Seite hat zwar das Wort „responsive“ im Titel, ist es aber keineswegs. Ich wollte die Seite gestern vom Smartphone aus lesen, sah aber nur schwarz. Ich habe das auf mein Uraltsmartphone zurückgeführt. Heute morgen am FF 47 sah es aber auch nicht besser aus. Bei schmalem Viewport wird ebenfalls ein Teil der Seite schwarz überdeckt. Und das ist nicht OK und lässt mich an der Qualität des vorgestellten Codes zweifeln.

        Gruß
        Jürgen

        1. problematische Seite

          Hallo,

          beim Versuch, das Script zu verstehen, bin ich auch auf die Methode getTransformToElement gestoßen, die aber laut https://www.chromestatus.com/feature/5736166087196672 nicht mehr weiter unterstützt werden soll. Ich glaube, ich bleibe bei der Methode „Nach Größenänderung alles neu zeichnen“.

          Gruß
          Jürgen

      2. problematische Seite

        Hej Gunnar,

        @@ThomasM

        svg * { vector-effect: non-scaling-stroke; }

        Oder als Attribut vector-effect="non-scaling-stroke".

        Live-Einsatz in einer wunderbaren Codepen-Demo (die freilich eigentlich was anderes zeigt, aber non-scaling-stroke neben vielem anderen verwendet - wollte nur den Link loswerden)

        ;-)

        Marc

        1. problematische Seite

          @@marctrix

          Live-Einsatz in einer wunderbaren Codepen-Demo (die freilich eigentlich was anderes zeigt …)

          In anderen Worten: Go home, SVG, you’re drunk!

          LLAP 🖖

          --
          “The best way to help people learn: answer their coding question an hour later, they’ll have likely figured it out by then.” —Todd Motto
          Selfcode: sh:) fo:} ch:? rl:) br:> n4:& va:| de:> zu:} fl:{ ss:| ls:# js:|
  2. problematische Seite

    Hallo,

    ich habe jetzt eine Lösung für das Skalierproblem gefunden: Link

    Ich bin dazu wie folgt vorgegangen:

    • Angabe einer viewbox
    • Setzen von vector-effect auf non-scaling-stroke
    • Bei Texten merke ich mir Position und Rotation, frage dann über getScreenCTM() die Transformationsmatrix des svg-Elements ab und korrigiere mit den Skalierwerten aus der Matrix die Skalierung der Texte.

    Gruß
    Jürgen

    PS Ich habe etwas aufgeräumt. Die Dateien befinden sich jetzt im Ordner „FktPlot“.