Suche…


Bemerkungen

Die Skripterstellung für SVG mit den nativen DOM-Schnittstellen befindet sich derzeit (2016) in einem geringfügigen Wandel. Der aktuelle SVG-Standard (1.1) wird von den meisten großen Webbrowsern gut implementiert. Da der SVG 2.0-Standard jedoch in der Entwicklung ist, haben einige Browser damit begonnen, SVG 1.1-Funktionen zu entfernen, die in 2.0 veraltet sind. Eine vollständige Liste der vorgeschlagenen Änderungen von SVG 1.1 zu SVG 2.0 finden Sie in Anhang L von SVG 2.0 .

Ersetzen von pathSegList und anderer SVGPathSeg Verwendung

In SVG 1.1 <path> werden die Elemente definiert , um eine haben pathSegList Eigenschaft , die den Zugang zu einer nativen Darstellung aller gibt Befehle Weg . Google Chrome v48 hat diese Eigenschaft Ende 2015 entfernt, um einen Ersatz für SVG 2.0 vorzubereiten. Bis die Unterstützung für SVG 2.0 hinzugefügt wird, müssen Sie eine Polyfill verwenden, um entweder die 1.1-Funktionalität zurückzubekommen oder die vorgeschlagene 2.0-API zu implementieren .

getTransformToElement() ersetzen

Chrome V48 auch entfernt die SVGGraphicsElement.getTransformToElement() Methode. Es gibt eine einfache Polyfill, um die alte Methode zu implementieren .

Element erstellen

Das Erstellen und Ändern von SVG-Elementen ist am einfachsten, wenn Sie die Elemente mithilfe der DOM-Level-2-Core- Schnittstellen wie mit HTML oder XML bearbeiten.

Es ist zwingend erforderlich, dass die aus JavaScript erstellten Elemente in demselben Namespace erstellt werden, der im SVG-Element angegeben ist - in diesem Beispiel: " http://www.w3.org/2000/svg ". Fast alle Attribute von SVG-Elementen befinden sich jedoch nicht in einem Namespace. Sie dürfen sie nicht im SVG-Namespace platzieren.

Hier zeigen wir, wie SVG in HTML gehostet wird, da dies ein häufiger Fall ist:

<!doctype HTML>
<html><title>Creating an Element</title>
<body>
  <svg xmlns="http://www.w3.org/2000/svg"
       width="100%" height="100%"
       viewBox="0 0 400 300"></svg>

  <script>
     var svgNS = "http://www.w3.org/2000/svg";

     // Create a circle element (not part of the DOM yet)
     var circle = document.createElementNS(svgNS,'circle'); // Creates a <circle/>
     circle.setAttribute('fill','red'); // Note: NOT setAttributeNS()
     circle.setAttribute('cx',150);     // setAttribute turns 150 into a string
     circle.setAttribute('cy','80');    // using a string works, too
     circle.setAttribute('r',35);       // give the circle a radius so we can see it

     // Now, add the circle to the SVG document so we can see it
     var svg = document.querySelector('svg'); // the root <svg> element
     svg.appendChild(circle);
  </script>
</body></html>

In einem bestimmten Namespace müssen einige Attribute erstellt werden. Diese sind im SVG-Attribut-Index mit Doppelpunkten aufgeführt. xlink:arcrole sind insbesondere: xlink:actuate xlink:arcrole , xlink:arcrole , xlink:href , xlink:role , xlink:show , xlink:title , xlink:type , xml:base , xml:lang und xml:space . setAttributeNS() Sie diese Attribute mit setAttributeNS() :

var svgNS   = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";
var img = document.createElementNS( svgNS, 'image' );
img.setAttributeNS( xlinkNS, 'href', 'my.png' );

Wenn Sie häufig Elemente erstellen, insbesondere mit vielen Attributen, können Sie mit einer Hilfsfunktion wie der folgenden Tipparbeit sparen, Fehler vermeiden und den Code lesbarer machen:

<!doctype HTML>
<html><title>Creating an Element</title>
<body>
  <svg xmlns="http://www.w3.org/2000/svg"></svg>
  <script>
     var svg = document.querySelector('svg');
     var circle = createOn( svg, 'circle', {fill:'red', cx:150, cy:80, r:35} );

    // Create an SVG element on another node with a set of attributes.
    // Attributes with colons in the name (e.g. 'xlink:href') will automatically
    // find the appropriate namespace URI from the SVG element.
    // Optionally specify text to create as a child node, for example
    //   createOn(someGroup,'text',{x:100,'text-anchor':'middle'},"Hello World!");
    function createOn(parentEl,name,attrs,text){
      var doc=parentEl.ownerDocument, svg=parentEl;
      while (svg && svg.tagName!='svg') svg=svg.parentNode;
      var el = doc.createElementNS(svg.namespaceURI,name);
      for (var a in attrs){
        if (!attrs.hasOwnProperty(a)) continue;
        var p = a.split(':');
        if (p[1]) el.setAttributeNS(svg.getAttribute('xmlns:'+p[0]),p[1],attrs[a]);
        else      el.setAttribute(a,attrs[a]);
      }
      if (text) el.appendChild(doc.createTextNode(text));
      return parentEl.appendChild(el);
    }
  </script>
</body></html>

Attribute lesen / schreiben

Sie können die DOM Level 2 Core- Methoden getAttribute() , getAttributeNS() , setAttribute() und setAttributeNS() , um Werte aus SVG-Elementen zu lesen und zu schreiben, oder Sie können benutzerdefinierte Eigenschaften und Methoden verwenden, die in der SVG 1.1-IDL (Schnittstelle) angegeben sind Definitionssprache).

Einfache numerische Attribute

Wenn Sie beispielsweise ein SVG-Kreiselement haben:

<circle id="circ" cx="10" cy="20" r="15" />

Sie können entweder DOM-Methoden verwenden, um die Attribute zu lesen und zu schreiben:

var circ = document.querySelector('#circ');
var x = circ.getAttribute('cx') * 1; // Use *1 to convert from string to number value
circ.setAttribute('cy', 25);

... oder Sie können die benutzerdefinierten Eigenschaften cx , cy und r für SVGCircleElement . Beachten Sie, dass dies keine direkten Zahlen sind, sondern wie bei vielen Zugriffsmethoden in SVG 1.1 den Zugriff auf animierte Werte ermöglichen. Diese Eigenschaften sind vom Typ SVGAnimatedLength . Ohne Berücksichtigung von Animations- und Längeneinheiten können Sie folgende Attribute verwenden:

var x = circ.cx.baseVal.value; // this is a number, not a string
circ.cy.baseVal.value = 25;

Transformationen

SVG-Gruppen können verwendet werden, um mehrere grafische Elemente als Ganzes zu verschieben, zu drehen, zu skalieren und anderweitig zu transformieren. (Einzelheiten zu SVG-Übersetzungen finden Sie in Kapitel 7 ). Hier ist eine Gruppe, die ein Smiley erstellt, dessen Größe, Drehung und Platzierung durch die Anpassung der transform angepasst werden transform :

<g id="smiley" transform="translate(120,120) scale(5) rotate(30)">
  <circle r="20" fill="yellow" stroke-width="2"/>
  <path fill="none" d="M-10,5 a 5 3 0 0 0 20,0" stroke-width="2"/>
  <circle cx="-6" cy="-5" r="2" fill="#000"/>
  <circle cx="6"  cy="-5" r="2" fill="#000"/>
</g>

Die Verwendung des Skripts zum Anpassen der Skalierung über DOM-Methoden erfordert die Bearbeitung des gesamten transform als Zeichenfolge:

var face = document.querySelector('#smiley');

// Find the full string value of the attribute
var xform = face.getAttribute('transform');

// Use a Regular Expression to replace the existing scale with 'scale(3)'
xform = xform.replace( /scale\s*\([^)]+\)/, 'scale(3)' );

// Set the attribute to the new string.
face.setAttribute('transform',xform);

Mit dem SVG-DOM kann man die spezifischen Transformationen in der Liste durchlaufen, die gewünschte finden und die Werte ändern:

var face = document.querySelector('#smiley');

// Get the SVGTransformList, ignoring animation
var xforms = face.transform.baseVal;          

// Find the scale transform (pretending we don't know its index)
for (var i=0; i<xforms.numberOfItems; ++i){
  // Get this part as an SVGTransform
  var xform = xforms.getItem(i);
  if (xform.type == SVGTransform.SVG_TRANSFORM_SCALE){
    // Set the scale; both X and Y scales are required
    xform.setScale(3,3);
    break;
  }
}

SVG-Elemente ziehen

Das Ziehen eines SVG-Elements (oder einer Elementgruppe) mit der Maus kann wie folgt durchgeführt werden:

  1. Hinzufügen eines mousedown zum mousedown : Hinzufügen einer Übersetzung für das Element, die beim Ziehen verwendet werden soll (falls erforderlich), Verfolgung von mousemove und Hinzufügen eines mouseup zum mouseup .
  2. Transformieren Sie während der mousemove die Position der Maus von Bildschirmkoordinaten in die lokalen Koordinaten für das Objekt, das Sie ziehen, und aktualisieren Sie die Übersetzung entsprechend.
  3. Während mouseup , Entfernen des mousemove und mouseup Handler.
// Makes an element in an SVG document draggable.
// Fires custom `dragstart`, `drag`, and `dragend` events on the
// element with the `detail` property of the event carrying XY
// coordinates for the location of the element.
function makeDraggable(el){
  if (!el) return console.error('makeDraggable() needs an element');
  var svg = el;
  while (svg && svg.tagName!='svg') svg=svg.parentNode;
  if (!svg) return console.error(el,'must be inside an SVG wrapper');
  var pt=svg.createSVGPoint(), doc=svg.ownerDocument;

  var root = doc.rootElement || doc.body || svg;
  var xlate, txStartX, txStartY, mouseStart;
  var xforms = el.transform.baseVal;

  el.addEventListener('mousedown',startMove,false);

  function startMove(evt){
    // We listen for mousemove/up on the root-most
    // element in case the mouse is not over el.
    root.addEventListener('mousemove',handleMove,false);
    root.addEventListener('mouseup',  finishMove,false);

    // Ensure that the first transform is a translate()
    xlate = xforms.numberOfItems>0 && xforms.getItem(0);
    if (!xlate || xlate.type != SVGTransform.SVG_TRANSFORM_TRANSLATE){
      xlate = xforms.createSVGTransformFromMatrix( svg.createSVGMatrix() );
      xforms.insertItemBefore( xlate, 0 );
    }
    txStartX=xlate.matrix.e;
    txStartY=xlate.matrix.f;
    mouseStart = inElementSpace(evt);
    fireEvent('dragstart');
  }

  function handleMove(evt){
    var point = inElementSpace(evt);
    xlate.setTranslate(
      txStartX + point.x - mouseStart.x,
      txStartY + point.y - mouseStart.y
    );
    fireEvent('drag');
  }

  function finishMove(evt){
    root.removeEventListener('mousemove',handleMove,false);
    root.removeEventListener('mouseup',  finishMove,false);
    fireEvent('dragend');
  }

  function fireEvent(eventName){
    var event = new Event(eventName);
    event.detail = { x:xlate.matrix.e, y:xlate.matrix.f };
    return el.dispatchEvent(event);
  }

  // Convert mouse position from screen space to coordinates of el
  function inElementSpace(evt){
    pt.x=evt.clientX; pt.y=evt.clientY;
    return pt.matrixTransform(el.parentNode.getScreenCTM().inverse());
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow