admin管理员组

文章数量:1122826

I'm trying to get the correct orientation in my web application. On iOS, event.webkitCompassHeading works very well, but on Android, it is either undefined or returns NaN.

After searching on Google, I found this type of code:

headingMio = Math.round(roundedAlpha + 85) % 360;
if (headingMio < 0) {
    headingMio += 360; 
}

But it doesn't work in landscape mode. How can I fix this?There is my code:

let lastHeading = null;
    let threshold = 5;
    let threshold2 = 15;

    document.addEventListener('click', async function requestOrientationPermission() {
        if (typeof DeviceOrientationEvent.requestPermission === 'function') {
            try {
                const permissionState = await DeviceOrientationEvent.requestPermission();
                if (permissionState === 'granted') {
                    console.log("Permesso concesso per l'orientamento del dispositivo.");
                    // Aggiungi l'event listener per l'orientamento
                    window.addEventListener('deviceorientation', handleDeviceOrientation);
                    document.removeEventListener('click', requestOrientationPermission);
                } else {
                    console.log("Permesso negato per l'orientamento del dispositivo.");
                }
            } catch (error) {
                console.error('Errore nel richiedere il permesso:', error);
            }
        } else {
            window.addEventListener('deviceorientation', handleDeviceOrientation);
        }
    });

    // Funzione che gestisce i dati di orientamento del dispositivo
    function handleDeviceOrientation(event) {
        roundedAlpha = Math.round(360 - event.alpha);
        roundedBeta = Math.round(event.beta);
        roundedGamma = Math.round(event.gamma);

        headingMio = Math.round(event.webkitCompassHeading);

        if (headingMio === undefined || isNaN(headingMio)) {
            if (roundedBeta > 80 && roundedBeta < 105) {
               //not worikng landscape
            } else {
                headingMio = Math.round(roundedAlpha + 85) % 360;
                if (headingMio < 0) {
                    headingMio += 360; 
                }
            }
        }

        const c = document.getElementById("orientation");

        if (lastHeading === null || Math.abs(headingMio - lastHeading) > threshold) {
            lastHeading = headingMio;

            c.innerText = `Alpha (Z): ${roundedAlpha}, Beta (X - Inclinazione avanti/indietro): ${roundedBeta}, Gamma (Y - Inclinazione laterale): ${roundedGamma}, Nord Magnetico (Compass Heading): ${headingMio}`;

            if (!isNaN(headingMio)) {
                map.setHeading(parseInt(headingMio, 10));
            }
        }

        c.innerText = `Alpha (Z): ${roundedAlpha}, Beta (X - Inclinazione avanti/indietro): ${roundedBeta}, Gamma (Y - Inclinazione laterale): ${roundedGamma}, Nord Magnetico (Compass Heading): ${headingMio}`;

    }

I'm trying to get the correct orientation in my web application. On iOS, event.webkitCompassHeading works very well, but on Android, it is either undefined or returns NaN.

After searching on Google, I found this type of code:

headingMio = Math.round(roundedAlpha + 85) % 360;
if (headingMio < 0) {
    headingMio += 360; 
}

But it doesn't work in landscape mode. How can I fix this?There is my code:

let lastHeading = null;
    let threshold = 5;
    let threshold2 = 15;

    document.addEventListener('click', async function requestOrientationPermission() {
        if (typeof DeviceOrientationEvent.requestPermission === 'function') {
            try {
                const permissionState = await DeviceOrientationEvent.requestPermission();
                if (permissionState === 'granted') {
                    console.log("Permesso concesso per l'orientamento del dispositivo.");
                    // Aggiungi l'event listener per l'orientamento
                    window.addEventListener('deviceorientation', handleDeviceOrientation);
                    document.removeEventListener('click', requestOrientationPermission);
                } else {
                    console.log("Permesso negato per l'orientamento del dispositivo.");
                }
            } catch (error) {
                console.error('Errore nel richiedere il permesso:', error);
            }
        } else {
            window.addEventListener('deviceorientation', handleDeviceOrientation);
        }
    });

    // Funzione che gestisce i dati di orientamento del dispositivo
    function handleDeviceOrientation(event) {
        roundedAlpha = Math.round(360 - event.alpha);
        roundedBeta = Math.round(event.beta);
        roundedGamma = Math.round(event.gamma);

        headingMio = Math.round(event.webkitCompassHeading);

        if (headingMio === undefined || isNaN(headingMio)) {
            if (roundedBeta > 80 && roundedBeta < 105) {
               //not worikng landscape
            } else {
                headingMio = Math.round(roundedAlpha + 85) % 360;
                if (headingMio < 0) {
                    headingMio += 360; 
                }
            }
        }

        const c = document.getElementById("orientation");

        if (lastHeading === null || Math.abs(headingMio - lastHeading) > threshold) {
            lastHeading = headingMio;

            c.innerText = `Alpha (Z): ${roundedAlpha}, Beta (X - Inclinazione avanti/indietro): ${roundedBeta}, Gamma (Y - Inclinazione laterale): ${roundedGamma}, Nord Magnetico (Compass Heading): ${headingMio}`;

            if (!isNaN(headingMio)) {
                map.setHeading(parseInt(headingMio, 10));
            }
        }

        c.innerText = `Alpha (Z): ${roundedAlpha}, Beta (X - Inclinazione avanti/indietro): ${roundedBeta}, Gamma (Y - Inclinazione laterale): ${roundedGamma}, Nord Magnetico (Compass Heading): ${headingMio}`;

    }
Share Improve this question asked Nov 22, 2024 at 11:00 Pierpaolo LopezPierpaolo Lopez 91 bronze badge 0
Add a comment  | 

1 Answer 1

Reset to default 0

This is a modified version of your code which includes landscape mode handling:

let lastHeading = null;
let threshold = 5;

document.addEventListener('click', async function requestOrientationPermission() {
    if (typeof DeviceOrientationEvent.requestPermission === 'function') {
        try {
            const permissionState = await DeviceOrientationEvent.requestPermission();
            if (permissionState === 'granted') {
                console.log("Permission granted for device orientation.");
                window.addEventListener('deviceorientation', handleDeviceOrientation);
                document.removeEventListener('click', requestOrientationPermission);
            } else {
                console.log("Permission denied for device orientation.");
            }
        } catch (error) {
            console.error('Error requesting permission:', error);
        }
    } else {
        window.addEventListener('deviceorientation', handleDeviceOrientation);
    }
});

// Function to handle device orientation data
function handleDeviceOrientation(event) {
    const roundedAlpha = Math.round(event.alpha);
    const roundedBeta = Math.round(event.beta);
    const roundedGamma = Math.round(event.gamma);

    let headingMio;

    // Check if webkitCompassHeading is available
    if (event.webkitCompassHeading !== undefined) {
        headingMio = Math.round(event.webkitCompassHeading);
    } else {
        // Handle the case when webkitCompassHeading is not available
        headingMio = (roundedAlpha + (window.orientation || 0) + 360) % 360;
    }

    const c = document.getElementById("orientation");

    // Update the displayed orientation values
    if (lastHeading === null || Math.abs(headingMio - lastHeading) > threshold) {
        lastHeading = headingMio;

        c.innerText = `Alpha (Z): ${roundedAlpha}, Beta (X): ${roundedBeta}, Gamma (Y): ${roundedGamma}, Magnetic North (Compass Heading): ${headingMio}`;

        if (!isNaN(headingMio)) {
            map.setHeading(parseInt(headingMio, 10));
        }
    }
}

The following code has been changed as mentioned here.

  • When webkitCompassHeading is not available, the code calculates headingMio using roundedAlpha adjusted for the current window orientation (window.orientation), which provides a more accurate sense of direction based on the device's current orientation.
  • The calculation (roundedAlpha + (window.orientation || 0) + 360)% 360 makes the heading more accurate in landscape view by adjusting it based on the device's orientation.

本文标签: javascriptIncorrect orientation on Android in landscape modeStack Overflow