Rotor: Verschiedene SVG-Fragen

Hallo,

ich habe von SVG nur wenig Ahnung (sehr lernwillig), finde aber auch keine mit bspw. Selfhtml auch nur annähernd vergleichbar hilfreichen Sites. Und habe eine ganze Reihe Fragen zu verschiedenen Themen.. Um ein bisschen zu sortieren, poste ich die Fragen als Antworten auf diesen Beitrag.

Für Hinweise und Antworten werde ich natürlich sehr dankbar sein.

  1. Ich erzeuge SVGs mit sehr vielen Kreisen und Polylinien (hunderte, manchmal auch vierstellig tausende - nach oben relativ offen). Bei meinem eher gemächlichen Pentium III mit 800 MHz dadurch dauert es ziemlich lange (Minuten), bis das Ergebnis angezeigt wird.

    Wenn ich mehrere Polygone gleichzeitig animiere, dann ist die Bewegung sehr abgehackt und dadurch sinnlos.

    Fragen:

    Gehe ich in der Annahme wohl recht, dass das an meinem 800 MHz-Prozessor liegt und bei Gigaherz-Prozessoren a) schneller geht und b) flüssig abläuft? Oder hängt das eher vom RAM (hab 256 MB) oder der Grafikkarte ab? Oder ist die flüssige Animation von mehreren komplexen Objekten zuviel von SVG verlangt?

  2. Ich erzeuge ein Viereck mit allen vier Seiten und ein Dreieck mit allen drei Seiten. Durch die Positionierung, deckt sich eine Seite des Dreiecks (min. teilweise) mit einer des Vierecks.

    Die Längen, in der die Geraden deckungsgleich sind, werden "anders" angezeigt, als sich nicht überschneidende Geraden (breiter oder dunkler).

    Frage:

    Kann ich diesen Effekt unterbinden? Sehr schmale Linien werden in SVG bspw. auch grau (statt schwarz) angezeigt, statt tatsächlich dünner zu sein.

  3. Ich habe ein Script, das mir beim Mausklick als "alert" die Position des Mauszeigers in SVG-Koordinaten anzeigt. D.h. wenn ich auf den Mittelpunkt eines Kreises bei cx=500 und cy=500 klicke, werden diese beiden Werte angezeigt. Das SVG ist dabei in eine HTML-Seite S eingebunden, die wiederum in einem iframe auf der Seite A angezeigt wird.

    Frage:

    Wie bringe ich diese Werte (aus dem SVG der Seite S) in ein "input"-Feld auf der Seite A mit dem iframe? Ich vermute gar nicht, die Forendiskussionen, die ich zum Thema fand, blieben alle ergebnislos, bzw. liefen auf die Vermutung hinaus, dass es schlicht und einfach nicht möglich ist. Oder doch..?

  4. Und noch eine Frage zur Animation:

    Wie kriege ich es hin, dass mir auf einem weißen "Blatt" Kreise und Polylinien gezeichnet werden? Die Striche sollen also animiert gezogen werden. Ich hab ein Beispiel für einen auf diese Weise animierten Pfad gefunden, und es hat anscheinend etwas mit "stroke-dashoffset" zu tun, aber leider werde ich weiter nicht schlau daraus, siehe hier:

    http://www.carto.net/papers/svg/samples/animated_bustrack.shtml

    Beschleunigung ist dabei nicht der Punkt, sondern die Anwendung des Effekts auf "circle" und "polyline".

    1. Man kann eine Linie gestrichelt anzeigen und diese Strichelung exakt definieren, bspw. so:

      stroke-dasharray: 5,5;

      Der Dasharray gibt an, wie groß Strich und Leere sind, hier jeweils 5. Zusätzlich kann man noch bestimmen, wo diese Strichelung anfängt, bspw. so:

      stroke-dashoffset: 2;

      Hier wird also die Strichelung vom Anfang der Figur um 2 Einheiten versetzt angefangen.

      Diese Strichelung kann animiert werden mit

      <animate attributeName="stroke-dashoffset" from="3" to="0" dur="5s"/>

      Um es so aussehen zu lassen, dass der Kreis gezeichnet wird, definiert man eine Strichelung, die zunächst eine Leere und dann einen Strich von genau dem Umfang des Kreises hat. Beim Kreis kann man das mit

      Umfang = 2 * Radius * Pi

      berechnen, ist der Radius wie im Beispiel = 200 lautet das (gerundete) Ergebnis 1257. Per dashoffset wird es nun so dargestellt, dass auf dem sichtbaren Kreis die unsichtbare Leere liegt und die Animation die "Strichelung" rein zieht:

      <g style="fill-opacity:0; fill:#ffffff; stroke:#000000; stroke-width:2; stroke-dasharray: 1257,1257; stroke-dashoffset: 1257;">

      <circle cx="500" cy="500" r="200"/>
      <animate attributeName="stroke-dashoffset" from="1257" to="0" dur="1s" begin="0s" fill="freeze"/>

      </g>

      Problematisch ist dabei, dass man wissen muss, wie lang diese Linie ist. Zur Bestimmung der Länge gibt es eine SVG-Funktion:

      getTotalLength()

      Die kann man aber nur auf Pfade, nicht auf Polylinien (oder Kreise) anwenden, d.h. man muss jegliches Objekt per "path" erstellen und kann dann einfügen:

      onload="alert(svgDocument.getElementById('pfad').getTotalLength())"

      Ein Viereck wird als Pfad bspw. so definiert:

      <path d="M200,110 290,200 200,290 110,200 200,110"/>

      Hier fügt man nun die ID und die Funktion zu:

      <path d="M200,110 290,200 200,290 110,200 200,110" id="pfad" onload="alert(svgDocument.getElementById('pfad').getTotalLength())"/>

      und erhält das Ergebnis, das man entsprechend dem Kreisbeispiel einsetzt.