SVG
Scripting
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;
}
}
-
SVGTransformList
zum Durchlaufen und Bearbeiten der Anzahl der Transformationen finden Sie unterSVGTransformList
. -
SVGTransform
zum Bearbeiten einzelner Transformationen finden Sie unterSVGTransform
.
SVG-Elemente ziehen
Das Ziehen eines SVG-Elements (oder einer Elementgruppe) mit der Maus kann wie folgt durchgeführt werden:
- Hinzufügen eines
mousedown
zummousedown
: Hinzufügen einer Übersetzung für das Element, die beim Ziehen verwendet werden soll (falls erforderlich), Verfolgung vonmousemove
und Hinzufügen einesmouseup
zummouseup
. - 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. - Während
mouseup
, Entfernen desmousemove
undmouseup
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());
}
}