Sök…


Anmärkningar

Skriptning av SVG med de ursprungliga DOM-gränssnitten är för närvarande (2016) i ett tillstånd av liten förändring. Den nuvarande SVG-standarden (1.1) implementeras bra av de flesta stora webbläsare. Men eftersom SVG 2.0-standarden är under utveckling har vissa webbläsare börjat ta bort SVG 1.1-funktioner som kommer att vara föråldrade i 2.0. Du kan se en fullständig lista över föreslagna ändringar från SVG 1.1 till SVG 2.0 i bilaga L till SVG 2.0 .

Byta ut pathSegList och annan SVGPathSeg användning

I SVG 1.1 definieras <path> element för att ha en pathSegList egenskap som ger tillgång till en naturlig representation av alla sökkommandon . Google Chrome v48 tog bort den här egenskapen i slutet av 2015, som en förberedelse för en föreslagen ersättning i SVG 2.0 . Tills SVG 2.0-stöd har lagts till måste du använda en polyfyll för att antingen få tillbaka 1.1-funktionaliteten eller för att implementera det föreslagna 2.0 API .

Ersätter getTransformToElement()

Chrome v48 tog också bort SVGGraphicsElement.getTransformToElement() -metoden. En enkel polyfill existerar för att implementera den gamla metoden .

Skapa ett element

Det enklaste sättet att förstå att skapa och modifiera SVG-element är att använda elementen med DOM Level 2 Core- gränssnitten, som du skulle göra med HTML eller XML.

Det är viktigt att elementen som skapats från JavaScript skapas i samma namnområde som deklareras i SVG-elementet - i det här exemplet: " http://www.w3.org/2000/svg ". Nästan alla attribut för SVG-element finns dock inte i något namnområde. Du får inte placera dem i SVG-namnområdet.

Här demonstrerar vi SVG värd inuti HTML, eftersom detta är ett vanligt fall:

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

Det finns några attribut som måste skapas i ett visst namnområde. Det är de som är listade med kolon i deras namn i SVG-attributindex . Specifikt är de: xlink:actuate , xlink:arcrole , xlink:href , xlink:role , xlink:show , xlink:title , xlink:type , xml:base , xml:lang och xml:space . Ställ in dessa attribut med 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' );

Om du skapar element ofta, särskilt med många attribut, kan en hjälpfunktion som följande spara dig att skriva, undvika misstag och göra din kod lättare att läsa:

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

Läsa / skriva attribut

Du kan använda antingen DOM Level 2 Core- metoder getAttribute() , getAttributeNS() , setAttribute() och setAttributeNS() att läsa och skriva värden från SVG-element, eller så kan du använda anpassade egenskaper och metoder som anges i SVG 1.1 IDL (Interface) Definitionsspråk).

Enkla numeriska attribut

Om du till exempel har ett SVG-cirkelelement:

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

Du kan antingen använda DOM-metoder för att läsa och skriva attributen:

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

... eller så kan du använda de anpassade cy cx , cy och r definierade för SVGCircleElement . Observera att det inte är direkta nummer, men istället - som för många accessorer i SVG 1.1 - tillåter de åtkomst till animerade värden. Dessa egenskaper är av typen SVGAnimatedLength . Om du inte ser animations- och längdenheter kan du använda sådana attribut som:

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

transformationer

SVG-grupper kan användas för att flytta, rotera, skala och på annat sätt transformera flera grafiska element som en helhet. (Mer information om SVG-översättningar finns i kapitel 7 ). Här är en grupp som gör en smiley som du kan justera storlek, rotation och placering av genom att justera 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>

Att använda skript för att justera skalan på detta via DOM-metoder kräver att man manipulerar hela transform som en sträng:

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

Med SVG DOM kan man gå igenom de specifika transformationerna i listan, hitta den önskade och ändra värdena:

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

Dra SVG-element

Att använda musen för att dra ett SVG-element (eller grupp av element) kan åstadkommas genom:

  1. Att lägga till mousedown hanterare för att starta dra: lägga till en översättning på elementet som ska användas under dragning (om det behövs), spåra händelser med mousemove och lägga till en mouseup att avsluta dra.
  2. mousemove position från skärmkoordinater till de lokala koordinaterna för objektet du drar och uppdaterar översättningen i enlighet därmed.
  3. Under mouseup avlägsnar du mousemove och mouseup .
// 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow