Zoeken…


Opmerkingen

Het scripten van SVG met behulp van de native DOM-interfaces is momenteel (2016) in een staat van lichte verandering. De huidige SVG-standaard (1.1) wordt goed geïmplementeerd door de meeste grote webbrowsers. Omdat de SVG 2.0-standaard in ontwikkeling is, zijn sommige browsers begonnen met het verwijderen van SVG 1.1-functies die in 2.0 verouderd zijn. U kunt een volledige lijst met voorgestelde wijzigingen van SVG 1.1 in SVG 2.0 bekijken in Bijlage L van SVG 2.0 .

pathSegList en ander gebruik van SVGPathSeg vervangen

In SVG 1.1 <path> elementen worden gedefinieerd om een hebben pathSegList eigenschap die toegang tot een inheemse vertegenwoordiging van alle geeft commando's pad . Google Chrome v48 heeft deze eigenschap eind 2015 verwijderd ter voorbereiding op een voorgestelde vervanging in SVG 2.0 . Totdat SVG 2.0-ondersteuning is toegevoegd, moet u een polyfill gebruiken om de 1.1-functionaliteit terug te krijgen of om de voorgestelde 2.0 API te implementeren .

getTransformToElement() vervangen

Chrome v48 heeft ook de methode SVGGraphicsElement.getTransformToElement() verwijderd . Er bestaat een eenvoudige polyfill om de oude methode te implementeren .

Een element maken

De eenvoudigste manier om het maken en wijzigen van SVG-elementen te begrijpen, is door op de elementen te werken met behulp van de DOM Level 2 Core- interfaces, zoals u zou doen met HTML of XML.

Het is noodzakelijk dat de elementen die met JavaScript zijn gemaakt, in dezelfde naamruimte worden gemaakt die in het SVG-element is opgegeven - in dit voorbeeld: " http://www.w3.org/2000/svg ". Bijna alle kenmerken van SVG-elementen staan echter niet in een naamruimte. U mag ze niet in de SVG-naamruimte plaatsen.

Hier demonstreren we SVG gehost in HTML, omdat dit een veel voorkomend geval is:

<!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>

Er zijn enkele attributen die in een bepaalde naamruimte moeten worden gemaakt. Zij worden vermeld met dubbele punten in hun naam in de SVG Attribute Index . Concreet zijn ze: xlink:actuate , xlink:arcrole , xlink:href , xlink:role , xlink:show , xlink:title , xlink:type , xml:base , xml:lang en xml:space . Stel deze attributen in met 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' );

Als u vaak elementen maakt, met name met veel attributen, kan een helperfunctie zoals de volgende u het typen besparen, fouten voorkomen en uw code gemakkelijker leesbaar maken:

<!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>

Kenmerken lezen / schrijven

U kunt DOM Level 2 Core- methoden getAttribute() , getAttributeNS() , setAttribute() en setAttributeNS() gebruiken om waarden van SVG-elementen te lezen en te schrijven, of u kunt aangepaste eigenschappen en methoden gebruiken die zijn gespecificeerd in de SVG 1.1 IDL (Interface Definitietaal).

Eenvoudige numerieke kenmerken

Als u bijvoorbeeld een SVG-cirkelelement hebt:

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

u kunt DOM-methoden gebruiken om de kenmerken te lezen en te schrijven:

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

... of u kunt de aangepaste gebruiken cx , cy , en r eigenschappen gedefinieerd voor SVGCircleElement . Merk op dat dit geen directe nummers zijn, maar in plaats daarvan - zoals bij veel accessors in SVG 1.1 - toegang tot geanimeerde waarden mogelijk maken. Deze eigenschappen zijn van het type SVGAnimatedLength . Als animatie- en lengte-eenheden buiten beschouwing worden gelaten, kunt u attributen gebruiken zoals:

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

transformaties

SVG-groepen kunnen worden gebruikt om meerdere grafische elementen als geheel te verplaatsen, roteren, schalen en anderszins te transformeren. (Zie hoofdstuk 7 voor meer informatie over SVG-vertalingen). Hier is een groep die een smiley maakt waarvan je de grootte, rotatie en plaatsing kunt aanpassen door de 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>

Het gebruik van script om de schaal hiervan aan te passen via DOM-methoden vereist het manipuleren van het gehele transform als een string:

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);

Met de SVG DOM kunt u de specifieke transformaties in de lijst doorlopen, de gewenste transformaties vinden en de waarden wijzigen:

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;
  }
}
  • Zie SVGTransformList voor het doorlopen en manipuleren van het aantal transformaties.
  • Zie SVGTransform voor het manipuleren van afzonderlijke transformaties.

SVG-elementen slepen

U kunt de muis gebruiken om een SVG-element (of een groep elementen) te slepen door:

  1. Toevoegen mousedown handler begint de weerstand: toevoegen van een vertaling van het element gebruik tijdens slepen (indien nodig), het volgen mousemove gebeurtenissen, en het toevoegen van een mouseup handler om de weerstand te beëindigen.
  2. Tijdens mousemove , transformeert u de positie van de muis van schermcoördinaten naar de lokale coördinaten voor het object dat u sleept, en werkt u de vertaling dienovereenkomstig bij.
  3. Tijdens mouseup , het verwijderen van de mousemove en mouseup handlers.
// 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow