Signatur
Beschreibung
bezierCurveTo() erweitert den aktuellen Pfad um eine kubische Bézier-Kurve. Die Kurve beginnt am aktuellen Punkt des Pfades (zuletzt gesetzt z. B. über moveTo(), lineTo() oder eine vorherige Kurve), endet im Punkt (x, y) und wird von den zwei Kontrollpunkten (cp1x, cp1y) und (cp2x, cp2y) „angezogen“. Die Kurve läuft in der Regel nicht durch die Kontrollpunkte – sie bestimmen nur die Tangenten an Start und Ende.
Die Methode eignet sich für weiche, organische Formen: Herzen, Wellen, Sprechblasen, Verbindungslinien in Diagrammen (Node-Editoren) oder geglättete Linienzüge in Charts. Im Gegensatz zu quadraticCurveTo() mit nur einem Kontrollpunkt erlaubt die kubische Variante S-Kurven und eine unabhängige Steuerung von Anfangs- und Endrichtung.
Wie alle Pfadmethoden zeichnet bezierCurveTo() selbst nichts sichtbar. Erst ein Aufruf von stroke() oder fill() rendert den Pfad. Nach dem Aufruf ist (x, y) der neue aktuelle Punkt, sodass sich mehrere Kurven nahtlos verketten lassen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $cp1x Pflicht | number | x-Koordinate des ersten Kontrollpunkts (bestimmt die Richtung am Startpunkt). | |
| $cp1y Pflicht | number | y-Koordinate des ersten Kontrollpunkts. | |
| $cp2x Pflicht | number | x-Koordinate des zweiten Kontrollpunkts (bestimmt die Richtung am Endpunkt). | |
| $cp2y Pflicht | number | y-Koordinate des zweiten Kontrollpunkts. | |
| $x Pflicht | number | x-Koordinate des Endpunkts; wird zum neuen aktuellen Punkt. | |
| $y Pflicht | number | y-Koordinate des Endpunkts. |
Rückgabewert
undefined). Der Pfad wird direkt verändert.Beispiele
Einfache S-Kurve zeichnen
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(20, 100); // Startpunkt
ctx.bezierCurveTo(
80, 10, // Kontrollpunkt 1
160, 190, // Kontrollpunkt 2
230, 100 // Endpunkt
);
ctx.lineWidth = 3;
ctx.strokeStyle = '#0a7';
ctx.stroke();
Herzform aus zwei Kurven füllen
const ctx = document.querySelector('canvas').getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 60);
ctx.bezierCurveTo(100, 30, 50, 30, 50, 65);
ctx.bezierCurveTo(50, 100, 100, 120, 100, 150);
ctx.bezierCurveTo(100, 120, 150, 100, 150, 65);
ctx.bezierCurveTo(150, 30, 100, 30, 100, 60);
ctx.closePath();
ctx.fillStyle = 'crimson';
ctx.fill();
Verbindungslinie zwischen zwei Knoten (Node-Editor)
const ctx = document.querySelector('canvas').getContext('2d');
const connect = (from, to) => {
// Horizontale Tangenten für weiche Kabel-Optik
const dx = Math.abs(to.x - from.x) * 0.5;
ctx.beginPath();
ctx.moveTo(from.x, from.y);
ctx.bezierCurveTo(from.x + dx, from.y, to.x - dx, to.y, to.x, to.y);
ctx.stroke();
};
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
connect({ x: 40, y: 40 }, { x: 260, y: 160 });
connect({ x: 40, y: 160 }, { x: 260, y: 40 });
Kontrollpunkte zur Fehlersuche sichtbar machen
const ctx = document.querySelector('canvas').getContext('2d');
const start = { x: 30, y: 150 }, cp1 = { x: 90, y: 20 }, cp2 = { x: 200, y: 20 }, end = { x: 260, y: 150 };
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, end.x, end.y);
ctx.stroke();
// Hilfslinien und Punkte
ctx.setLineDash([4, 4]);
ctx.strokeStyle = 'gray';
ctx.beginPath();
ctx.moveTo(start.x, start.y); ctx.lineTo(cp1.x, cp1.y);
ctx.moveTo(end.x, end.y); ctx.lineTo(cp2.x, cp2.y);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = 'red';
[cp1, cp2].forEach(({ x, y }) => ctx.fillRect(x - 3, y - 3, 6, 6));
// Wichtig · Fallstricke
- Fehlender Startpunkt: Gibt es keinen aktuellen Punkt (z. B. direkt nach
beginPath()ohnemoveTo()), setzt der Browser implizit(cp1x, cp1y)als Startpunkt – das ergibt meist eine unerwartete Kurve. Daher immer vorhermoveTo()aufrufen. - Nicht-endliche Werte: Ist ein Argument
NaNoderInfinity, wird der Aufruf still ignoriert – es gibt keinen Fehler. Berechnete Koordinaten also vorher prüfen. - Kontrollpunkte liegen nicht auf der Kurve: Die Kurve verläuft innerhalb der konvexen Hülle aus Start-, Kontroll- und Endpunkt, berührt die Kontrollpunkte aber im Allgemeinen nicht.
- Glatte Übergänge: Für knickfreie Verkettung muss der zweite Kontrollpunkt einer Kurve, der gemeinsame Endpunkt und der erste Kontrollpunkt der nächsten Kurve auf einer Geraden liegen.
- Transformationen: Die Koordinaten werden durch die aktuelle Transformationsmatrix (
translate(),scale(),rotate()) umgerechnet. - Die Methode gibt es auch auf
Path2DundOffscreenCanvasRenderingContext2D; sie wird von allen modernen Browsern seit Jahren unterstützt.