Start · Sprachen · JavaScript · Referenz · SVGTransform

SVGTransform

Schnittstelle

Steht für genau eine Transformation wie <code>translate(…)</code>, <code>rotate(…)</code> oder <code>matrix(…)</code> in einer <code>SVGTransformList</code> und macht sie per Skript les- und änderbar.

seit JavaScript Baseline: alle Browser (SVG 1.1) Kategorie: webapi

Signatur

interface SVGTransform

Beschreibung

SVGTransform steht für einen einzelnen Eintrag im transform-Attribut eines SVG-Elements, ebenso in gradientTransform und patternTransform. Aus transform="translate(10 20) rotate(45)" entstehen zwei SVGTransform-Objekte. Sie liegen in der SVGTransformList unter element.transform.baseVal. Die Objekte sind live: Änderst du eines, aktualisiert der Browser sofort das Attribut und die Darstellung.

Es gibt keinen öffentlichen Konstruktor. Neue Instanzen erzeugst du mit SVGSVGElement.createSVGTransform(). Das ergibt eine Einheitsmatrix vom Typ SVG_TRANSFORM_MATRIX. Alternativ nimmst du SVGTransformList.createSVGTransformFromMatrix(matrix). Die Art und die Werte legst du dann mit einer der Methoden fest. Dabei werden type, angle und matrix automatisch passend gesetzt:

  • setMatrix(matrix): setzt eine beliebige Matrix (Typ MATRIX)
  • setTranslate(tx, ty): Verschiebung (Typ TRANSLATE)
  • setScale(sx, sy): Skalierung (Typ SCALE)
  • setRotate(angle, cx, cy): Drehung um den Punkt (cx, cy) (Typ ROTATE)
  • setSkewX(angle) / setSkewY(angle): Scherung (Typ SKEWX bzw. SKEWY)

Die Eigenschaften sind schreibgeschützt: type gibt die Art als Konstante an (SVG_TRANSFORM_UNKNOWN = 0, MATRIX = 1, TRANSLATE = 2, SCALE = 3, ROTATE = 4, SKEWX = 5, SKEWY = 6). matrix liefert die zugehörige 2D-Matrix (DOMMatrix bzw. das ältere SVGMatrix) mit den Werten a bis f. angle enthält den Winkel in Grad bei Drehung und Scherung, bei allen anderen Arten ist er 0.

Die Schnittstelle lohnt sich, wenn du Transformationen häufig änderst, etwa beim Ziehen, Zoomen oder Animieren. Du veränderst dann die Zahlen im vorhandenen Objekt direkt und musst den Attribut-String nicht jedes Mal neu zusammenbauen und parsen.

Parameter

Name Typ Default Beschreibung
$setMatrix(matrix) Pflicht DOMMatrix2DInit | SVGMatrix Übernimmt die Werte a bis f der übergebenen Matrix. Danach ist type gleich SVG_TRANSFORM_MATRIX. Die Werte werden kopiert, eine Verknüpfung zur Ausgangsmatrix bleibt nicht bestehen.
$setTranslate(tx, ty) Pflicht number, number Verschiebung in Benutzereinheiten auf der x- und y-Achse.
$setScale(sx, sy) Pflicht number, number Skalierungsfaktoren für x und y. Beide Werte müssen angegeben werden. Für gleichmäßiges Skalieren übergibst du zweimal denselben Wert.
$setRotate(angle, cx, cy) Pflicht number, number, number Drehwinkel in Grad um den Mittelpunkt (cx, cy). Für eine Drehung um den Ursprung übergibst du 0, 0.
$setSkewX(angle) / setSkewY(angle) Pflicht number Scherwinkel in Grad entlang der x- bzw. y-Achse.

Rückgabewert

Typ
SVGTransform
Beschreibung
Instanzen bekommst du über SVGSVGElement.createSVGTransform(), über SVGTransformList.getItem(i) oder über createSVGTransformFromMatrix(). Alle set*()-Methoden geben undefined zurück.

Beispiele

Neue Transformation erzeugen und anhängen

const svg = document.querySelector('svg');
const rect = svg.querySelector('#box');

// Instanz erzeugen: zunächst eine Einheitsmatrix
const t = svg.createSVGTransform();
t.setTranslate(50, 20);

// An die Transformationsliste des Elements anhängen
rect.transform.baseVal.appendItem(t);

console.log(t.type === SVGTransform.SVG_TRANSFORM_TRANSLATE);
console.log(rect.getAttribute('transform'));
true translate(50 20) // Firefox schreibt z. B. "translate(50, 20)"

Vorhandene Transformationen auslesen

// <rect id="box" transform="translate(10 20) rotate(45)" … />
const rect = document.querySelector('#box');
const list = rect.transform.baseVal;

for (let i = 0; i < list.numberOfItems; i++) {
  const { type, angle, matrix } = list.getItem(i);
  console.log(type, angle, matrix.e, matrix.f);
}
2 0 10 20 4 45 0 0

Element per Maus ziehen, ohne den Attribut-String neu zu bauen

const svg = document.querySelector('svg');
const el = svg.querySelector('#handle');

// Eine eigene Translate-Transformation an den Anfang der Liste setzen
const move = svg.createSVGTransform();
move.setTranslate(0, 0);
el.transform.baseVal.insertItemBefore(move, 0);

let start = null;

el.addEventListener('pointerdown', (e) => {
  el.setPointerCapture(e.pointerId);
  start = { x: e.clientX - move.matrix.e, y: e.clientY - move.matrix.f };
});

el.addEventListener('pointermove', (e) => {
  if (!start) return;
  // Das Objekt ist live: die Darstellung ändert sich sofort
  move.setTranslate(e.clientX - start.x, e.clientY - start.y);
});

el.addEventListener('pointerup', () => { start = null; });

Drehung um den Mittelpunkt und Zusammenfassen der Liste

const svg = document.querySelector('svg');
const rect = svg.querySelector('#box');
const { x, y, width, height } = rect.getBBox();

const rot = svg.createSVGTransform();
rot.setRotate(30, x + width / 2, y + height / 2);
rect.transform.baseVal.appendItem(rot);
console.log(rot.angle); // 30

// Alle Einträge zu einer einzigen Matrix zusammenfassen
const combined = rect.transform.baseVal.consolidate();
console.log(combined.type, combined.angle);
30 1 0