Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将DeviceOrientationEvent.webkitCompassHeading与iOS上的相关beta和gamma值一起使用?_Javascript_Ios_Three.js - Fatal编程技术网

Javascript 如何将DeviceOrientationEvent.webkitCompassHeading与iOS上的相关beta和gamma值一起使用?

Javascript 如何将DeviceOrientationEvent.webkitCompassHeading与iOS上的相关beta和gamma值一起使用?,javascript,ios,three.js,Javascript,Ios,Three.js,我已经修改了DeviceOrientationControl,使其指向北方,而不是设备启动时的方向。当它在Android上工作时,我很难让iOS版本正常工作。这是我的修改版本 /** * @author richt / http://richt.me * @author WestLangley / http://github.com/WestLangley * * W3C Device Orientation control (http://w3c.github.io/deviceori

我已经修改了DeviceOrientationControl,使其指向北方,而不是设备启动时的方向。当它在Android上工作时,我很难让iOS版本正常工作。这是我的修改版本

/**
 * @author richt / http://richt.me
 * @author WestLangley / http://github.com/WestLangley
 *
 * W3C Device Orientation control (http://w3c.github.io/deviceorientation/spec-source-orientation.html)
 */

THREE.DeviceOrientationControls = function ( object ) {

    var scope = this;

    this.object = object;
    this.object.rotation.reorder( 'YXZ' );

    this.enabled = true;

    this.deviceOrientation = {};
    this.screenOrientation = 0;

    this.alphaOffset = 0; // radians
    this.absolute = false;
    this.alphaOffsetDevice = undefined;
    this.alphaOffsetScreen = undefined;

    var onDeviceOrientationChangeEvent = function ( event ) {
        if(scope.absolute) return;

        scope.deviceOrientation = event;

    };

    var onDeviceOrientationAbsoluteChangeEvent = function ( event ) {

        scope.deviceOrientation = event;
        scope.absolute = true;

    };

    var onScreenOrientationChangeEvent = function () {

        scope.screenOrientation = window.orientation || 0;

    };

    // The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''

    var setObjectQuaternion = function () {

        var zee = new THREE.Vector3( 0, 0, 1 );

        var euler = new THREE.Euler();

        var q0 = new THREE.Quaternion();

        var q1 = new THREE.Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis

        return function ( quaternion, alpha, beta, gamma, orient ) {

            euler.set( beta, alpha, - gamma, 'YXZ' ); // 'ZXY' for the device, but 'YXZ' for us

            quaternion.setFromEuler( euler ); // orient the device

            quaternion.multiply( q1 ); // camera looks out the back of the device, not the top

            quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) ); // adjust for screen orientation

        };

    }();

    this.connect = function () {

        onScreenOrientationChangeEvent(); // run once on load

        window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent, false );
        window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false );
        window.addEventListener( 'deviceorientationabsolute', onDeviceOrientationAbsoluteChangeEvent, false );

        scope.enabled = true;

    };

    this.disconnect = function () {

        window.removeEventListener( 'orientationchange', onScreenOrientationChangeEvent, false );
        window.removeEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false );
        window.removeEventListener( 'deviceorientationabsolute', onDeviceOrientationAbsoluteChangeEvent, false );

        scope.enabled = false;

    };

    this.update = function () {
        if ( scope.enabled === false ) return;

        var device;
        device = scope.deviceOrientation;

        if ( device ) {

            var alpha = this.getDirection() ? THREE.Math.degToRad( this.getDirection() ) + scope.alphaOffset : 0; // Z

            var beta = device.beta ? THREE.Math.degToRad( device.beta ) : 0; // X'

            var gamma = device.gamma ? THREE.Math.degToRad( device.gamma ) : 0; // Y''

            var orient = scope.screenOrientation ? THREE.Math.degToRad( scope.screenOrientation ) : 0; // O

            setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient );

        }

    };

    this.dispose = function () {

        scope.disconnect();

    };

    this.iOSOrientationPermission = function ()
    {
    if (typeof DeviceOrientationEvent.requestPermission === 'function') {
            DeviceOrientationEvent.requestPermission().then(permissionState => {
                if (permissionState === 'granted') {

                }

                console.log(permissionState);
            }).catch(console.error);
        }
    }

    this.getDirection = function ()
    {
        return (typeof scope.deviceOrientation.webkitCompassHeading != "undefined") ? scope.deviceOrientation.webkitCompassHeading : scope.deviceOrientation.alpha;
    }

    this.getDirectionMap = function ()
    {
        return (typeof scope.deviceOrientation.webkitCompassHeading != "undefined") ? (360 - scope.deviceOrientation.webkitCompassHeading) : scope.deviceOrientation.alpha;
    }

    this.connect();

};

我已将DeviceOrientationControl中提到的DeviceOrientationEvent.alpha替换为函数getDirection(),该函数在Android上返回DeviceOrientationEvent.alpha,在iOS上返回DeviceOrientationEvent.webkitCompassHeading,但这不适用于iOS,相反,当手机在Y轴上旋转时,或者当手机倾斜超过地平线时,它会导致场景摄影机四处晃动。我在网上几乎找不到关于如何使用webkitCompassHeading值的信息,我所发现的一点信息建议用它代替alpha值,正如上面所述,在我的情况下,alpha值不起作用。alpha/beta/gamma值似乎是从四元数内部转换而来的,而webkitCompassHeading只是一个单独的0-360值,因此不能直接与其他值一起使用

我曾尝试在启动时使用校准功能获取webkitCompassHeading,并使用它来抵消alpha,但这只提供了大约50%的正确结果。由于在Android上,alpha值在内部不断更新为标题值,因此我认为在iOS上使用类似的方法是最好的方法,但在这一点上,我感到困惑。在安卓系统上,我使用谷歌浏览器,在iOS上使用Safari

这里有几个关于我正在使用的API的链接