52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { Observer, Observable } from 'rxjs';
|
|
|
|
|
|
@Injectable()
|
|
export class DeviceOrientationService {
|
|
|
|
compassHeading(alpha, beta, gamma):number {
|
|
|
|
// Convert degrees to radians
|
|
var alphaRad = alpha * (Math.PI / 180);
|
|
var betaRad = beta * (Math.PI / 180);
|
|
var gammaRad = gamma * (Math.PI / 180);
|
|
|
|
// Calculate equation components
|
|
var cA = Math.cos(alphaRad);
|
|
var sA = Math.sin(alphaRad);
|
|
var cB = Math.cos(betaRad);
|
|
var sB = Math.sin(betaRad);
|
|
var cG = Math.cos(gammaRad);
|
|
var sG = Math.sin(gammaRad);
|
|
|
|
// Calculate A, B, C rotation components
|
|
var rA = - cA * sG - sA * sB * cG;
|
|
var rB = - sA * sG + cA * sB * cG;
|
|
var rC = - cB * cG;
|
|
|
|
// Calculate compass heading
|
|
var compassHeading = Math.atan(rA / rB);
|
|
|
|
// Convert from half unit circle to whole unit circle
|
|
if(rB < 0) {
|
|
compassHeading += Math.PI;
|
|
}else if(rA < 0) {
|
|
compassHeading += 2 * Math.PI;
|
|
}
|
|
return compassHeading * (180/Math.PI);
|
|
}
|
|
|
|
getCurrentCompassHeading(): Observable<number> {
|
|
return Observable.create((observer: Observer<number>) => {
|
|
window.addEventListener("deviceorientation", (event:DeviceOrientationEvent)=>{
|
|
let heading = this.compassHeading(event.alpha,event.beta,event.gamma);
|
|
if(!Number.isNaN(heading)) {
|
|
observer.next(heading);
|
|
}
|
|
} );
|
|
});
|
|
}
|
|
|
|
}
|