Signatur
Beschreibung
transform() verknüpft die aktuelle Transformationsmatrix des 2D-Kontexts mit einer weiteren affinen Matrix. Die sechs Argumente beschreiben die Matrix [a c e; b d f; 0 0 1]. Ein Punkt (x, y) wird damit auf (a·x + c·y + e, b·x + d·y + f) abgebildet. So lassen sich Skalierung, Rotation, Scherung und Verschiebung in einem einzigen Aufruf zusammenfassen.
Die Wirkung ist kumulativ. Jeder Aufruf wird mit der bereits bestehenden Transformation multipliziert, genau wie bei translate(), rotate() und scale(). Diese drei Methoden sind im Grunde Sonderfälle von transform(). Soll die Matrix nicht ergänzt, sondern ersetzt werden, verwendet man setTransform().
Typische Einsatzfälle sind Scherungen (Kursiv-Effekte, isometrische Darstellung), für die es keine eigene Methode gibt. Dazu kommt das Übernehmen fertiger Matrizen, etwa aus einer Physik-Engine oder aus SVG/CSS. Die Transformation betrifft nur Zeichenbefehle, die danach ausgeführt werden. Bereits gezeichnete Pixel bleiben unverändert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $a Pflicht | number | Horizontale Skalierung (m11). 1 = keine Änderung. |
|
| $b Pflicht | number | Vertikale Scherung (m12): Neigung der y-Werte in Abhängigkeit von x. | |
| $c Pflicht | number | Horizontale Scherung (m21): Neigung der x-Werte in Abhängigkeit von y. | |
| $d Pflicht | number | Vertikale Skalierung (m22). 1 = keine Änderung. |
|
| $e Pflicht | number | Horizontale Verschiebung (dx) in Pixeln. | |
| $f Pflicht | number | Vertikale Verschiebung (dy) in Pixeln. |
Beispiele
Rechteck horizontal scheren (Kursiv-Effekt)
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.save();
// c = -0.3 schert horizontal, e/f verschieben den Ursprung
ctx.transform(1, 0, -0.3, 1, 60, 20);
ctx.fillStyle = 'steelblue';
ctx.fillRect(0, 0, 120, 80);
ctx.restore(); // Transformation wieder zurücksetzen
console.log(ctx.getTransform().toString());
Kumulative Wirkung im Vergleich zu setTransform()
const ctx = document.createElement('canvas').getContext('2d');
ctx.transform(2, 0, 0, 2, 0, 0); // Skalierung ×2
ctx.transform(2, 0, 0, 2, 0, 0); // erneut ×2 → insgesamt ×4
console.log(ctx.getTransform().a);
ctx.setTransform(2, 0, 0, 2, 0, 0); // ersetzt → wieder ×2
console.log(ctx.getTransform().a);
Rotation um einen Mittelpunkt mit einer einzigen Matrix
const ctx = document.querySelector('canvas').getContext('2d');
const rotateAround = (ctx, angle, cx, cy) => {
const cos = Math.cos(angle);
const sin = Math.sin(angle);
// entspricht translate(cx, cy) · rotate(angle) · translate(-cx, -cy)
ctx.transform(cos, sin, -sin, cos,
cx - cos * cx + sin * cy,
cy - sin * cx - cos * cy);
};
ctx.save();
rotateAround(ctx, Math.PI / 6, 150, 100);
ctx.fillStyle = 'tomato';
ctx.fillRect(100, 75, 100, 50);
ctx.restore();
Isometrische Kachel zeichnen
const ctx = document.querySelector('canvas').getContext('2d');
ctx.save();
// Isometrische Projektion: 45°-Drehung plus vertikale Stauchung
ctx.transform(0.707, 0.409, -0.707, 0.409, 200, 50);
for (let x = 0; x < 4; x++) {
for (let y = 0; y < 4; y++) {
ctx.fillStyle = (x + y) % 2 ? '#8bc34a' : '#689f38';
ctx.fillRect(x * 40, y * 40, 40, 40);
}
}
ctx.restore();
// Wichtig · Fallstricke
- Kumulativ: Wer
transform()in einer Animationsschleife aufruft, ohne vorhersave()/restore()oderresetTransform()zu nutzen, sammelt die Transformationen Frame für Frame an. Das führt schnell zu „davonfliegenden“ Grafiken. - Reihenfolge zählt: Matrixmultiplikation ist nicht kommutativ.
transform(A)gefolgt vontransform(B)ergibt ein anderes Ergebnis als die umgekehrte Reihenfolge. - Ist ein Argument
InfinityoderNaN, wird der Aufruf stillschweigend ignoriert. Es gibt keinen Fehler. - Eine singuläre Matrix (z. B.
a = d = 0beib = c = 0) lässt alle folgenden Zeichnungen verschwinden. lineWidth, Schatten-Offsets und Muster werden mittransformiert. Bei Scherung oder ungleicher Skalierung werden Linien dadurch verzerrt.- Die aktuelle Matrix lässt sich mit
getTransform()alsDOMMatrixauslesen. Das wird von allen modernen Browsern unterstützt, im alten Internet Explorer fehlt es.transform()selbst ist überall verfügbar, auch inOffscreenCanvasRenderingContext2D.