Signatur
Beschreibung
GestureEvent ist eine nicht standardisierte, WebKit-spezifische Schnittstelle. Sie liefert Informationen über Zwei-Finger-Gesten wie Zusammenziehen/Aufziehen (Pinch-Zoom) und Drehen. Solche Events feuern in Safari auf dem Mac (Trackpad-Gesten) sowie in Safari bzw. allen WebKit-basierten Browsern unter iOS und iPadOS.
Es gibt drei zugehörige Event-Typen: gesturestart (zwei oder mehr Finger berühren die Fläche), gesturechange (die Finger bewegen sich während der Geste) und gestureend (die Geste endet). Du registrierst sie mit element.addEventListener("gesturechange", handler). Die zugehörigen on-Eigenschaften (ongesturechange usw.) sind nicht zuverlässig vorhanden, deshalb solltest du immer addEventListener verwenden.
Die wichtigsten Eigenschaften sind scale: der Skalierungsfaktor relativ zum Beginn der Geste, Ausgangswert 1.0. Außerdem rotation: der Drehwinkel in Grad relativ zum Beginn, Ausgangswert 0, positiv im Uhrzeigersinn. Typische Anwendungsfälle sind Bildbetrachter, Karten und Zeichenflächen. Häufig wird die Schnittstelle auch genutzt, um die eingebaute Seitenvergrößerung von Safari per preventDefault() zu unterdrücken.
Weil andere Browser dieses Event nicht kennen, brauchst du für plattformübergreifenden Code immer eine Alternative. Das sind Pointer Events bzw. Touch Events, bei denen du den Abstand zwischen den Fingern selbst berechnest. Für Trackpad-Pinch in Chromium und Firefox kommt das wheel-Event mit ctrlKey === true infrage.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $scale | number | 1.0 | Nur lesbar. Skalierungsfaktor seit gesturestart: < 1 heißt zusammengezogen, > 1 heißt aufgezogen. |
| $rotation | number | 0 | Nur lesbar. Drehwinkel in Grad seit Beginn der Geste, positiv im Uhrzeigersinn. |
| $clientX / clientY | number | Nur lesbar. Mittelpunkt der Geste relativ zum Viewport (in WebKit vorhanden, aber nicht dokumentiert zugesichert). | |
| $screenX / screenY | number | Nur lesbar. Mittelpunkt der Geste relativ zum Bildschirm. | |
| $altKey / ctrlKey / metaKey / shiftKey | boolean | false | Nur lesbar. Zeigt an, ob während der Geste die jeweilige Zusatztaste gedrückt war. |
| $initGestureEvent() | function | Veraltet. Initialisiert ein mit document.createEvent("GestureEvent") erzeugtes Event. Nicht mehr verwenden. |
Rückgabewert
gesturestart, gesturechange und gestureend übergeben wird.Beispiele
Funktionsprüfung und Auslesen von scale/rotation
// Prüfen, ob der Browser GestureEvent kennt (nur WebKit)
const hatGesten = typeof window.GestureEvent !== 'undefined';
console.log('GestureEvent verfügbar:', hatGesten);
const flaeche = document.querySelector('#flaeche');
const beiAenderung = (event) => {
event.preventDefault();
console.log(`Skalierung: ${event.scale.toFixed(2)}, Drehung: ${event.rotation.toFixed(1)}°`);
};
flaeche.addEventListener('gesturechange', beiAenderung);
// Später wieder entfernen
// flaeche.removeEventListener('gesturechange', beiAenderung);
Bild per Pinch zoomen und drehen
const bild = document.querySelector('#foto');
let basisSkala = 1;
let basisDrehung = 0;
let aktSkala = 1;
let aktDrehung = 0;
const anwenden = () => {
bild.style.transform = `scale(${aktSkala}) rotate(${aktDrehung}deg)`;
};
bild.addEventListener('gesturestart', (e) => e.preventDefault());
bild.addEventListener('gesturechange', (e) => {
e.preventDefault();
// scale/rotation sind relativ zum Gestenbeginn → mit Basis verrechnen
aktSkala = Math.min(Math.max(basisSkala * e.scale, 0.5), 5);
aktDrehung = basisDrehung + e.rotation;
anwenden();
});
bild.addEventListener('gestureend', (e) => {
e.preventDefault();
basisSkala = aktSkala;
basisDrehung = aktDrehung;
});
Seiten-Zoom in Safari unterdrücken, mit Alternative für andere Browser
const karte = document.querySelector('#karte');
let zoom = 1;
const setzeZoom = (faktor) => {
zoom = Math.min(Math.max(zoom * faktor, 0.25), 8);
karte.style.transform = `scale(${zoom})`;
};
if ('GestureEvent' in window) {
// Safari: native Geste abfangen
let letzteSkala = 1;
karte.addEventListener('gesturestart', (e) => { e.preventDefault(); letzteSkala = 1; });
karte.addEventListener('gesturechange', (e) => {
e.preventDefault();
setzeZoom(e.scale / letzteSkala);
letzteSkala = e.scale;
});
} else {
// Chromium/Firefox: Trackpad-Pinch kommt als wheel-Event mit ctrlKey
karte.addEventListener('wheel', (e) => {
if (!e.ctrlKey) return;
e.preventDefault();
setzeZoom(Math.exp(-e.deltaY / 100));
}, { passive: false });
}