Signatur
Beschreibung
Die schreibgeschützte Eigenschaft altitudeAngle eines Touch-Objekts gibt an, wie steil ein Eingabestift (zum Beispiel der Apple Pencil) zur X-Y-Ebene des Bildschirms steht. Der Wert ist eine Zahl im Bogenmaß (Radiant) zwischen 0 und π/2. Bei 0 liegt der Stift parallel zur Oberfläche, bei π/2 (etwa 1.5708) steht er senkrecht darauf.
Zusammen mit Touch.azimuthAngle (Richtung der Neigung in der Bildschirmebene) beschreibt altitudeAngle die räumliche Lage des Stifts. Das braucht man vor allem in Zeichen- und Handschrift-Anwendungen: Bei flach gehaltenem Stift kann der Strich zum Beispiel breiter werden, wie bei einem schräg gehaltenen Bleistift („Schattieren“). Ob die Eingabe tatsächlich von einem Stift stammt, zeigt Touch.touchType ("stylus" oder "direct").
Für Berührungen mit dem Finger (touchType === "direct") gibt es keine sinnvolle Neigung. Hier liefert die Eigenschaft einen Standardwert, typischerweise π/2. Den Wert liest man in den Handlern von touchstart und touchmove aus event.touches, event.changedTouches oder event.targetTouches aus.
Rückgabewert
0 (parallel zur Oberfläche) bis Math.PI / 2 (senkrecht). In Browsern ohne Unterstützung ist die Eigenschaft undefined.Beispiele
Neigungswinkel in Grad ausgeben
const canvas = document.querySelector('#zeichenflaeche');
canvas.addEventListener('touchmove', (event) => {
for (const touch of event.changedTouches) {
if (typeof touch.altitudeAngle !== 'number') {
console.log('altitudeAngle wird nicht unterstützt');
return;
}
const grad = touch.altitudeAngle * 180 / Math.PI;
console.log(`${touch.touchType}: ${grad.toFixed(1)}°`);
}
}, { passive: true });
Strichbreite abhängig von der Stiftneigung
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
let letzter = null;
const breiteAusNeigung = (touch) => {
// Flacher Stift ergibt breiteren Strich (1 bis 12 px)
if (touch.touchType !== 'stylus' || touch.altitudeAngle === undefined) return 2;
const flachheit = 1 - touch.altitudeAngle / (Math.PI / 2); // 0 = senkrecht, 1 = flach
return 1 + flachheit * 11;
};
canvas.addEventListener('touchstart', (e) => {
const t = e.changedTouches[0];
letzter = { x: t.clientX, y: t.clientY };
});
canvas.addEventListener('touchmove', (e) => {
e.preventDefault(); // Scrollen beim Zeichnen verhindern
const t = e.changedTouches[0];
const rect = canvas.getBoundingClientRect();
ctx.lineWidth = breiteAusNeigung(t);
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(letzter.x - rect.left, letzter.y - rect.top);
ctx.lineTo(t.clientX - rect.left, t.clientY - rect.top);
ctx.stroke();
letzter = { x: t.clientX, y: t.clientY };
}, { passive: false });
Fallback auf Pointer Events
const flaeche = document.querySelector('#flaeche');
if ('PointerEvent' in window && 'altitudeAngle' in PointerEvent.prototype) {
// Plattformübergreifend über Pointer Events
flaeche.addEventListener('pointermove', (e) => {
if (e.pointerType === 'pen') console.log('Pointer:', e.altitudeAngle);
});
} else {
// Nur Safari/iOS: Touch-Schnittstelle
flaeche.addEventListener('touchmove', (e) => {
const t = e.touches[0];
if (t.touchType === 'stylus') console.log('Touch:', t.altitudeAngle);
}, { passive: true });
}
// Wichtig · Fallstricke
- Kompatibilität: Die Eigenschaft ist nicht standardisiert bzw. experimentell und praktisch nur in Safari auf iOS/iPadOS mit Apple Pencil verfügbar. Chrome und Firefox bieten sie auf
Touchnicht an, dort ist der Wertundefined. Prüfen Sie deshalb immer, ob die Eigenschaft vorhanden ist. - Einheit: Der Wert ist im Bogenmaß, nicht in Grad. Umrechnung in Grad:
winkel * 180 / Math.PI. - Richtung der Skala: Ein großer Wert bedeutet einen steilen Stift. Das ist anders als bei
PointerEvent.tiltX/tiltY, wo0für senkrecht steht. - Finger-Eingaben: Bei
touchType === "direct"ist der Wert ein Standardwert ohne Aussagekraft. Werten Sie ihn nur bei Stift-Eingaben aus. - Empfehlung: Für neue Projekte besser
PointerEvent.altitudeAnglebzw.tiltX/tiltYverwenden. Pointer Events werden breiter unterstützt und decken Maus, Stift und Touch gemeinsam ab. - Wer in
touchmovepreventDefault()aufruft, muss den Listener mit{ passive: false }registrieren.