Signatur
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 (TypMATRIX)setTranslate(tx, ty): Verschiebung (TypTRANSLATE)setScale(sx, sy): Skalierung (TypSCALE)setRotate(angle, cx, cy): Drehung um den Punkt (cx, cy) (TypROTATE)setSkewX(angle)/setSkewY(angle): Scherung (TypSKEWXbzw.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
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'));
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);
}
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);